6 typedef struct _ConditionLock
{
7 pthread_mutex_t _mutex
;
8 pthread_cond_t _condition
;
19 static int initConditionLockWithCondition(ConditionLock
*, int);
20 static int lockConditionLock(ConditionLock
*, int);
21 static int lockConditionLockWhenCondition(ConditionLock
*, int, int);
22 static int unlockConditionLockWithCondition(ConditionLock
*, int, int);
23 static int destroyConditionLock(ConditionLock
*);
24 static void * testThread(void *);
25 static void log(int, const char *, ConditionLock
*);
27 static ConditionLock
* lock
;
28 static volatile int count
= 0;
29 static volatile int logcount
= 0;
30 static log_t
* tracelog
;
31 #define TRACE_MAX_COUNT (4 * 1024 * 1024)
32 long iterations
= 999000L;
35 log(int self
, const char * op
, ConditionLock
* cl
)
37 tracelog
[logcount
].thread
= self
;
38 tracelog
[logcount
++].op
= op
;
39 if (logcount
== TRACE_MAX_COUNT
)
44 main(int argc
, char * argv
[])
48 lock
= (ConditionLock
*)calloc(sizeof(ConditionLock
), 1);
49 if (initConditionLockWithCondition(lock
, 0))
51 tracelog
= (log_t
*)calloc(sizeof(log_t
), TRACE_MAX_COUNT
);
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);
58 while (iterations
> -100) {
59 if (lockConditionLock(lock
, 0))
63 if (unlockConditionLockWithCondition(lock
, 1, 0))
67 destroyConditionLock(lock
);
75 testThread(void * arg
)
78 while (iterations
> 0) {
79 if (lockConditionLockWhenCondition(lock
, 1, self
))
82 if (unlockConditionLockWithCondition(lock
, 0, self
))
89 initConditionLockWithCondition(ConditionLock
* cl
, int condition
)
93 if ((rc
= pthread_mutex_init(&cl
->_mutex
, NULL
))) {
94 fprintf(stderr
, "pthread_mutex_init returned %d, %s\n", rc
, strerror(rc
));
98 if ((rc
= pthread_cond_init(&cl
->_condition
, NULL
))) {
99 fprintf(stderr
, "pthread_cond_init returned %d, %s\n", rc
, strerror(rc
));
103 cl
->_state
= condition
;
109 destroyConditionLock(ConditionLock
* cl
)
113 if ((rc
= pthread_mutex_destroy(&cl
->_mutex
))) {
114 fprintf(stderr
, "pthread_mutex_destroy returned %d, %s\n", rc
, strerror(rc
));
117 if ((rc
= pthread_cond_destroy(&cl
->_condition
))) {
118 fprintf(stderr
, "pthread_cond_destroy returned %d, %s\n", rc
, strerror(rc
));
125 lockConditionLock(ConditionLock
* cl
, int self
)
129 if ((rc
= pthread_mutex_lock(&cl
->_mutex
))) {
130 fprintf(stderr
, "pthread_mutex_lock() returned %d, %s\n", rc
, strerror(rc
));
134 log(self
, "Got lock", cl
);
139 lockConditionLockWhenCondition(ConditionLock
* cl
, int condition
, int self
)
143 if ((rc
= pthread_mutex_lock(&cl
->_mutex
))) {
144 fprintf(stderr
, "pthread_mutex_lock() returned %d, %s\n", rc
, strerror(rc
));
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
));
153 if (cl
->_state
!= condition
) {
154 log(self
, "condition lock wakeup with wrong condition", cl
);
158 log(self
, "Got condition", cl
);
163 unlockConditionLockWithCondition(ConditionLock
* cl
, int condition
, int self
)
167 if (cl
->_owner
!= self
) {
168 fprintf(stderr
, "%d: trying to unlock a lock owned by %d\n", self
, cl
->_owner
);
171 log(self
, condition
? "Unlocking with condition set" : "Unlocking with condition cleared", cl
);
172 cl
->_last_owner
= cl
->_owner
;
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
));
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
));