11 pthread_rwlock_t rwlock
;
16 void *test_thread(void *ptr
) {
19 struct context
*context
= ptr
;
26 bool exclusive
= i
& 2;
29 str
= "pthread_rwlock_rdlock";
30 res
= pthread_rwlock_rdlock(&context
->rwlock
);
33 str
= "pthread_rwlock_tryrdlock";
34 res
= pthread_rwlock_tryrdlock(&context
->rwlock
);
37 str
= "pthread_rwlock_wrlock";
38 res
= pthread_rwlock_wrlock(&context
->rwlock
);
41 str
= "pthread_rwlock_trywrlock";
42 res
= pthread_rwlock_trywrlock(&context
->rwlock
);
46 if (try && res
== EBUSY
) {
49 fprintf(stderr
, "[%ld] %s: %s\n", context
->count
, str
, strerror(res
));
54 old
= __sync_fetch_and_or(&context
->value
, 1);
56 fprintf(stderr
, "[%ld] OR %lx\n", context
->count
, old
);
61 old
= __sync_fetch_and_and(&context
->value
, 0);
62 if ((old
& 1) != (exclusive
? 1 : 0)) {
63 fprintf(stderr
, "[%ld] AND %lx\n", context
->count
, old
);
67 res
= pthread_rwlock_unlock(&context
->rwlock
);
69 fprintf(stderr
, "[%ld] pthread_rwlock_unlock: %s\n", context
->count
, strerror(res
));
72 } while (__sync_fetch_and_sub(&context
->count
, 1) > 0);
77 int main(int argc
, char *argv
[])
79 struct context context
= {
80 .rwlock
= PTHREAD_RWLOCK_INITIALIZER
,
88 for (i
= 0; i
< threads
; ++i
) {
89 res
= pthread_create(&p
[i
], NULL
, test_thread
, &context
);
92 for (i
= 0; i
< threads
; ++i
) {
93 res
= pthread_join(p
[i
], NULL
);