]> git.saurik.com Git - apple/libpthread.git/blob - tests/cond.c
libpthread-218.51.1.tar.gz
[apple/libpthread.git] / tests / cond.c
1 #include <assert.h>
2 #include <pthread.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <stdbool.h>
8 #include <errno.h>
9 #include <libkern/OSAtomic.h>
10
11 #include <darwintest.h>
12 #include <darwintest_utils.h>
13
14 struct context {
15 pthread_cond_t cond;
16 pthread_mutex_t mutex;
17 long waiters;
18 long count;
19 };
20
21 static void *wait_thread(void *ptr) {
22 int res;
23 struct context *context = ptr;
24
25 bool loop = true;
26 while (loop) {
27 res = pthread_mutex_lock(&context->mutex);
28 if (res) {
29 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_lock", context->count);
30 }
31
32 if (context->count > 0) {
33 ++context->waiters;
34 res = pthread_cond_wait(&context->cond, &context->mutex);
35 if (res) {
36 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_rwlock_unlock", context->count);
37 }
38 --context->waiters;
39 --context->count;
40 } else {
41 loop = false;
42 }
43
44 res = pthread_mutex_unlock(&context->mutex);
45 if (res) {
46 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_unlock", context->count);
47 }
48 }
49
50 return NULL;
51 }
52
53 T_DECL(cond, "pthread_cond",
54 T_META_ALL_VALID_ARCHS(YES))
55 {
56 struct context context = {
57 .cond = PTHREAD_COND_INITIALIZER,
58 .mutex = PTHREAD_MUTEX_INITIALIZER,
59 .waiters = 0,
60 .count = 100000 * dt_ncpu(),
61 };
62 int i;
63 int res;
64 int threads = 2;
65 pthread_t p[threads];
66 for (i = 0; i < threads; ++i) {
67 T_ASSERT_POSIX_ZERO(pthread_create(&p[i], NULL, wait_thread, &context), NULL);
68 }
69
70 long half = context.count / 2;
71
72 bool loop = true;
73 while (loop) {
74 res = pthread_mutex_lock(&context.mutex);
75 if (res) {
76 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_lock", context.count);
77 }
78 if (context.waiters) {
79 char *str;
80 if (context.count > half) {
81 str = "pthread_cond_broadcast";
82 res = pthread_cond_broadcast(&context.cond);
83 } else {
84 str = "pthread_cond_signal";
85 res = pthread_cond_signal(&context.cond);
86 }
87 if (res != 0) {
88 T_ASSERT_POSIX_ZERO(res, "[%ld] %s", context.count, str);
89 }
90 }
91 if (context.count <= 0) {
92 loop = false;
93 T_PASS("Completed stres test successfully.");
94 }
95
96 res = pthread_mutex_unlock(&context.mutex);
97 if (res) {
98 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_unlock", context.count);
99 }
100 }
101
102 for (i = 0; i < threads; ++i) {
103 T_ASSERT_POSIX_ZERO(pthread_join(p[i], NULL), NULL);
104 }
105 }