9 #include <libkern/OSAtomic.h>
11 #include "darwintest_defaults.h"
12 #include <darwintest_utils.h>
16 pthread_mutex_t mutex
;
17 pthread_cond_t ready_cond
;
25 static void *wait_thread(void *ptr
) {
26 struct context
*context
= ptr
;
28 // tell producer thread that we are ready
30 T_ASSERT_POSIX_ZERO(pthread_mutex_lock(&context
->mutex
), "pthread_mutex_lock");
31 context
->ready
= true;
33 T_ASSERT_POSIX_ZERO(pthread_cond_signal(&context
->ready_cond
), "pthread_cond_signal");
38 if (context
->count
> 0) {
41 T_ASSERT_POSIX_ZERO(pthread_cond_wait(&context
->cond
, &context
->mutex
), "[%ld] pthread_rwlock_unlock", context
->count
);
51 T_ASSERT_POSIX_ZERO(pthread_mutex_unlock(&context
->mutex
), "[%ld] pthread_mutex_unlock", context
->count
);
56 T_DECL(cond
, "pthread_cond",
57 T_META_ALL_VALID_ARCHS(YES
), T_META_TIMEOUT(120), T_META_CHECK_LEAKS(NO
))
59 struct context context
= {
60 .cond
= PTHREAD_COND_INITIALIZER
,
61 .mutex
= PTHREAD_MUTEX_INITIALIZER
,
62 .ready_cond
= PTHREAD_COND_INITIALIZER
,
64 .count
= 50000 * dt_ncpu(),
71 for (i
= 0; i
< threads
; ++i
) {
73 T_ASSERT_POSIX_ZERO(pthread_mutex_lock(&context
.mutex
), "pthread_mutex_lock");
75 context
.ready
= false;
78 T_ASSERT_POSIX_ZERO(pthread_create(&p
[i
], NULL
, wait_thread
, &context
), "pthread_create");
81 // mutex will be dropped and allow consumer thread to acquire
83 T_ASSERT_POSIX_ZERO(pthread_cond_wait(&context
.ready_cond
, &context
.mutex
), "pthread_cond_wait");
84 } while (context
.ready
== false);
87 T_ASSERT_POSIX_ZERO(pthread_mutex_unlock(&context
.mutex
), "pthread_mutex_lock");
89 T_LOG("Thread %d ready.", i
);
92 T_LOG("All threads ready.");
94 long half
= context
.count
/ 2;
99 T_ASSERT_POSIX_ZERO(pthread_mutex_lock(&context
.mutex
), "[%ld] pthread_mutex_lock", context
.count
);
100 if (context
.waiters
) {
102 if (context
.count
> half
) {
103 str
= "pthread_cond_broadcast";
104 res
= pthread_cond_broadcast(&context
.cond
);
106 str
= "pthread_cond_signal";
107 res
= pthread_cond_signal(&context
.cond
);
110 T_ASSERT_POSIX_ZERO(res
, "[%ld] %s", context
.count
, str
);
112 if (context
.count
<= 0) {
114 T_PASS("Completed stres test successfully.");
118 T_ASSERT_POSIX_ZERO(pthread_mutex_unlock(&context
.mutex
),
119 "[%ld] pthread_mutex_unlock", context
.count
);
122 for (i
= 0; i
< threads
; ++i
) {
123 T_ASSERT_POSIX_ZERO(pthread_join(p
[i
], NULL
), NULL
);