]> git.saurik.com Git - apple/libpthread.git/blame - tests/cond_stress.c
libpthread-218.1.3.tar.gz
[apple/libpthread.git] / tests / cond_stress.c
CommitLineData
2546420a
A
1#include <stdio.h>
2#include <stdlib.h>
3#include <pthread.h>
4#include <string.h>
5
6typedef struct _ConditionLock {
7 pthread_mutex_t _mutex;
8 pthread_cond_t _condition;
9 int _owner;
10 int _last_owner;
11 volatile int _state;
12} ConditionLock;
13
14typedef struct _log {
15 int thread;
16 const char * op;
17} log_t;
18
19static int initConditionLockWithCondition(ConditionLock *, int);
20static int lockConditionLock(ConditionLock *, int);
21static int lockConditionLockWhenCondition(ConditionLock *, int, int);
22static int unlockConditionLockWithCondition(ConditionLock *, int, int);
23static int destroyConditionLock(ConditionLock *);
24static void * testThread(void *);
25static void log(int, const char *, ConditionLock *);
26
27static ConditionLock * lock;
28static volatile int count = 0;
29static volatile int logcount = 0;
30static log_t * tracelog;
31#define TRACE_MAX_COUNT (4 * 1024 * 1024)
32long iterations = 999000L;
33
34static void
35log(int self, const char * op, ConditionLock * cl)
36{
37 tracelog[logcount].thread = self;
38 tracelog[logcount++].op = op;
39 if (logcount == TRACE_MAX_COUNT)
40 logcount = 0;
41}
42
43int
44main(int argc, char * argv[])
45{
46 pthread_t thread[4];
47
48 lock = (ConditionLock *)calloc(sizeof(ConditionLock), 1);
49 if (initConditionLockWithCondition(lock, 0))
50 abort();
51 tracelog = (log_t *)calloc(sizeof(log_t), TRACE_MAX_COUNT);
52
53 pthread_create(&thread[0], NULL, testThread, (void *)1);
54 pthread_create(&thread[1], NULL, testThread, (void *)2);
55 pthread_create(&thread[2], NULL, testThread, (void *)3);
56 pthread_create(&thread[3], NULL, testThread, (void *)4);
57
58 while (iterations > -100) {
59 if (lockConditionLock(lock, 0))
60 abort();
61 count = 1;
62 iterations--;
63 if (unlockConditionLockWithCondition(lock, 1, 0))
64 abort();
65 }
66
67 destroyConditionLock(lock);
68 free(lock);
69 free(tracelog);
70
71 return 0;
72}
73
74static void *
75testThread(void * arg)
76{
77 int self = (int)arg;
78 while (iterations > 0) {
79 if (lockConditionLockWhenCondition(lock, 1, self))
80 abort();
81 count = 0;
82 if (unlockConditionLockWithCondition(lock, 0, self))
83 abort();
84 }
85 return arg;
86}
87
88static int
89initConditionLockWithCondition(ConditionLock * cl, int condition)
90{
91 int rc;
92
93 if ((rc = pthread_mutex_init(&cl->_mutex, NULL))) {
94 fprintf(stderr, "pthread_mutex_init returned %d, %s\n", rc, strerror(rc));
95 return 1;
96 }
97
98 if ((rc = pthread_cond_init(&cl->_condition, NULL))) {
99 fprintf(stderr, "pthread_cond_init returned %d, %s\n", rc, strerror(rc));
100 return 1;
101 }
102
103 cl->_state = condition;
104
105 return 0;
106}
107
108static int
109destroyConditionLock(ConditionLock * cl)
110{
111 int rc;
112
113 if ((rc = pthread_mutex_destroy(&cl->_mutex))) {
114 fprintf(stderr, "pthread_mutex_destroy returned %d, %s\n", rc, strerror(rc));
115 return 1;
116 }
117 if ((rc = pthread_cond_destroy(&cl->_condition))) {
118 fprintf(stderr, "pthread_cond_destroy returned %d, %s\n", rc, strerror(rc));
119 return 1;
120 }
121 return 0;
122}
123
124static int
125lockConditionLock(ConditionLock * cl, int self)
126{
127 int rc;
128
129 if ((rc = pthread_mutex_lock(&cl->_mutex))) {
130 fprintf(stderr, "pthread_mutex_lock() returned %d, %s\n", rc, strerror(rc));
131 return 1;
132 }
133 cl->_owner = self;
134 log(self, "Got lock", cl);
135 return 0;
136}
137
138static int
139lockConditionLockWhenCondition(ConditionLock * cl, int condition, int self)
140{
141 int rc;
142
143 if ((rc = pthread_mutex_lock(&cl->_mutex))) {
144 fprintf(stderr, "pthread_mutex_lock() returned %d, %s\n", rc, strerror(rc));
145 return 1;
146 }
147 log(self, "Waiting for condition", cl);
148 while (cl->_state != condition) {
149 if ((rc = pthread_cond_wait(&cl->_condition, &cl->_mutex))) {
150 fprintf(stderr, "pthread_cond_wait() returned %d, %s\n", rc, strerror(rc));
151 return 1;
152 }
153 if (cl->_state != condition) {
154 log(self, "condition lock wakeup with wrong condition", cl);
155 }
156 }
157 cl->_owner = self;
158 log(self, "Got condition", cl);
159 return 0;
160}
161
162static int
163unlockConditionLockWithCondition(ConditionLock * cl, int condition, int self)
164{
165 int rc;
166
167 if (cl->_owner != self) {
168 fprintf(stderr, "%d: trying to unlock a lock owned by %d\n", self, cl->_owner);
169 abort();
170 }
171 log(self, condition ? "Unlocking with condition set" : "Unlocking with condition cleared", cl);
172 cl->_last_owner = cl->_owner;
173 cl->_owner = 0;
174 cl->_state = condition;
175 if ((rc = pthread_cond_signal(&cl->_condition))) {
176 fprintf(stderr, "pthread_cond_broadcast() returned %d, %s\n", rc, strerror(rc));
177 return 1;
178 }
179 log(self, "Sent broadcast", cl);
180 if ((rc = pthread_mutex_unlock(&cl->_mutex))) {
181 fprintf(stderr, "pthread_mutex_unlock() returned %d, %s\n", rc, strerror(rc));
182 return 1;
183 }
184 return 0;
185}
186