10 #include <libkern/OSAtomic.h>
11 #include <dispatch/dispatch.h>
13 #include <darwintest.h>
19 pthread_mutex_t mutex
;
24 static void *wait_thread(void *ptr
) {
26 struct context
*context
= ptr
;
32 gettimeofday(&tv
, NULL
);
33 tv
.tv_sec
+= (tv
.tv_usec
+ context
->udelay
) / (__typeof(tv
.tv_sec
)) USEC_PER_SEC
;
34 tv
.tv_usec
= (tv
.tv_usec
+ context
->udelay
) % (__typeof(tv
.tv_usec
)) USEC_PER_SEC
;
35 TIMEVAL_TO_TIMESPEC(&tv
, &ts
);
37 res
= pthread_mutex_lock(&context
->mutex
);
39 fprintf(stderr
, "[%ld] pthread_mutex_lock: %s\n", context
->count
, strerror(res
));
43 if (context
->count
> 0) {
44 res
= pthread_cond_timedwait(&context
->cond
, &context
->mutex
, &ts
);
45 if (res
!= ETIMEDOUT
) {
46 fprintf(stderr
, "[%ld] pthread_cond_timedwait: %s\n", context
->count
, strerror(res
));
54 res
= pthread_mutex_unlock(&context
->mutex
);
56 fprintf(stderr
, "[%ld] pthread_mutex_unlock: %s\n", context
->count
, strerror(res
));
64 T_DECL(cond_timedwait_timeout
, "pthread_cond_timedwait() timeout")
66 // This testcase launches 8 threads that all perform timed wait on the same
67 // conditional variable that is not being signaled in a loop. Ater the total
68 // of 8000 timeouts all threads finish and the testcase prints out the
69 // expected time (5[ms]*8000[timeouts]/8[threads]=5s) vs elapsed time.
70 struct context context
= {
71 .cond
= PTHREAD_COND_INITIALIZER
,
72 .mutex
= PTHREAD_MUTEX_INITIALIZER
,
77 long uexpected
= (context
.udelay
* context
.count
) / NUM_THREADS
;
78 T_LOG("waittime expected: %ld us", uexpected
);
79 struct timeval start
, end
;
80 gettimeofday(&start
, NULL
);
82 pthread_t p
[NUM_THREADS
];
83 for (int i
= 0; i
< NUM_THREADS
; ++i
) {
84 T_ASSERT_POSIX_ZERO(pthread_create(&p
[i
], NULL
, wait_thread
, &context
),
88 usleep((useconds_t
) uexpected
);
91 T_ASSERT_POSIX_ZERO(pthread_mutex_lock(&context
.mutex
),
92 "pthread_mutex_lock");
93 if (context
.count
<= 0) {
96 T_ASSERT_POSIX_ZERO(pthread_mutex_unlock(&context
.mutex
),
97 "pthread_mutex_unlock");
100 for (int i
= 0; i
< NUM_THREADS
; ++i
) {
101 T_ASSERT_POSIX_ZERO(pthread_join(p
[i
], NULL
), "pthread_join");
104 gettimeofday(&end
, NULL
);
106 ((uint64_t) end
.tv_sec
* USEC_PER_SEC
+ (uint64_t) end
.tv_usec
) -
107 ((uint64_t) start
.tv_sec
* USEC_PER_SEC
+ (uint64_t) start
.tv_usec
);
108 T_LOG("waittime actual: %llu us", uelapsed
);