]> git.saurik.com Git - apple/libpthread.git/blame_incremental - tests/cond.c
libpthread-138.10.4.tar.gz
[apple/libpthread.git] / tests / cond.c
... / ...
CommitLineData
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
11struct context {
12 pthread_cond_t cond;
13 pthread_mutex_t mutex;
14 long waiters;
15 long count;
16};
17
18void *wait_thread(void *ptr) {
19 int res;
20 struct context *context = ptr;
21
22 int i = 0;
23 char *str;
24
25 bool loop = true;
26 while (loop) {
27 res = pthread_mutex_lock(&context->mutex);
28 if (res) {
29 fprintf(stderr, "[%ld] pthread_mutex_lock: %s\n", context->count, strerror(res));
30 abort();
31 }
32
33 if (context->count > 0) {
34 ++context->waiters;
35 res = pthread_cond_wait(&context->cond, &context->mutex);
36 if (res) {
37 fprintf(stderr, "[%ld] pthread_rwlock_unlock: %s\n", context->count, strerror(res));
38 abort();
39 }
40 --context->waiters;
41 --context->count;
42 } else {
43 loop = false;
44 }
45
46 res = pthread_mutex_unlock(&context->mutex);
47 if (res) {
48 fprintf(stderr, "[%ld] pthread_mutex_unlock: %s\n", context->count, strerror(res));
49 abort();
50 }
51 }
52
53 return NULL;
54}
55
56int main(int argc, char *argv[])
57{
58 struct context context = {
59 .cond = PTHREAD_COND_INITIALIZER,
60 .mutex = PTHREAD_MUTEX_INITIALIZER,
61 .waiters = 0,
62 .count = 500000,
63 };
64 int i;
65 int res;
66 int threads = 2;
67 pthread_t p[threads];
68 for (i = 0; i < threads; ++i) {
69 res = pthread_create(&p[i], NULL, wait_thread, &context);
70 assert(res == 0);
71 }
72
73 long half = context.count / 2;
74
75 bool loop = true;
76 while (loop) {
77 res = pthread_mutex_lock(&context.mutex);
78 if (res) {
79 fprintf(stderr, "[%ld] pthread_mutex_lock: %s\n", context.count, strerror(res));
80 abort();
81 }
82 if (context.waiters) {
83 char *str;
84 if (context.count > half) {
85 str = "pthread_cond_broadcast";
86 res = pthread_cond_broadcast(&context.cond);
87 } else {
88 str = "pthread_cond_signal";
89 res = pthread_cond_signal(&context.cond);
90 }
91 if (res != 0) {
92 fprintf(stderr, "[%ld] %s: %s\n", context.count, str, strerror(res));
93 abort();
94 }
95 }
96 if (context.count <= 0) {
97 loop = false;
98 }
99
100 res = pthread_mutex_unlock(&context.mutex);
101 if (res) {
102 fprintf(stderr, "[%ld] pthread_mutex_unlock: %s\n", context.count, strerror(res));
103 abort();
104 }
105 }
106
107
108 for (i = 0; i < threads; ++i) {
109 res = pthread_join(p[i], NULL);
110 assert(res == 0);
111 }
112
113 return 0;
114}