]> git.saurik.com Git - apple/libpthread.git/blame - tests/cond.c
libpthread-218.30.1.tar.gz
[apple/libpthread.git] / tests / cond.c
CommitLineData
964d3577
A
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
2546420a
A
11#include <darwintest.h>
12#include <darwintest_utils.h>
13
964d3577
A
14struct context {
15 pthread_cond_t cond;
16 pthread_mutex_t mutex;
17 long waiters;
18 long count;
19};
20
2546420a 21static void *wait_thread(void *ptr) {
964d3577
A
22 int res;
23 struct context *context = ptr;
24
964d3577
A
25 bool loop = true;
26 while (loop) {
27 res = pthread_mutex_lock(&context->mutex);
28 if (res) {
2546420a 29 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_lock", context->count);
964d3577
A
30 }
31
32 if (context->count > 0) {
33 ++context->waiters;
34 res = pthread_cond_wait(&context->cond, &context->mutex);
35 if (res) {
2546420a 36 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_rwlock_unlock", context->count);
964d3577
A
37 }
38 --context->waiters;
39 --context->count;
40 } else {
41 loop = false;
42 }
43
44 res = pthread_mutex_unlock(&context->mutex);
45 if (res) {
2546420a 46 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_unlock", context->count);
964d3577
A
47 }
48 }
49
50 return NULL;
51}
52
2546420a
A
53T_DECL(cond, "pthread_cond",
54 T_META_ALL_VALID_ARCHS(YES))
964d3577
A
55{
56 struct context context = {
57 .cond = PTHREAD_COND_INITIALIZER,
58 .mutex = PTHREAD_MUTEX_INITIALIZER,
59 .waiters = 0,
2546420a 60 .count = 100000 * dt_ncpu(),
964d3577
A
61 };
62 int i;
63 int res;
64 int threads = 2;
65 pthread_t p[threads];
66 for (i = 0; i < threads; ++i) {
2546420a 67 T_ASSERT_POSIX_ZERO(pthread_create(&p[i], NULL, wait_thread, &context), NULL);
964d3577
A
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) {
2546420a 76 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_lock", context.count);
964d3577
A
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) {
2546420a 88 T_ASSERT_POSIX_ZERO(res, "[%ld] %s", context.count, str);
964d3577
A
89 }
90 }
91 if (context.count <= 0) {
92 loop = false;
2546420a 93 T_PASS("Completed stres test successfully.");
964d3577
A
94 }
95
96 res = pthread_mutex_unlock(&context.mutex);
97 if (res) {
2546420a 98 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_unlock", context.count);
964d3577
A
99 }
100 }
101
964d3577 102 for (i = 0; i < threads; ++i) {
2546420a 103 T_ASSERT_POSIX_ZERO(pthread_join(p[i], NULL), NULL);
964d3577 104 }
964d3577 105}