12 pthread_rwlock_t rwlock
;
17 void mask_signals(bool masked
, bool perthread
)
23 sigdelset(&mask
, SIGINT
);
26 sigaddset(&mask
, SIGWINCH
);
29 int action
= (masked
? SIG_BLOCK
: SIG_UNBLOCK
);
31 pthread_sigmask(action
, &mask
, NULL
);
33 sigprocmask(action
, &mask
, NULL
);
37 void test_signal(int signo
)
42 void *test_signal_thread(void *ptr
)
46 sigdelset(&mask
, SIGWINCH
);
47 pthread_sigmask(SIG_BLOCK
, &mask
, NULL
);
49 struct context
*context
= ptr
;
52 kill(getpid(), SIGWINCH
);
53 } while (context
->count
> 0);
58 void *test_thread(void *ptr
) {
61 struct context
*context
= ptr
;
66 mask_signals(false, true);
70 bool exclusive
= i
& 2;
73 str
= "pthread_rwlock_rdlock";
74 res
= pthread_rwlock_rdlock(&context
->rwlock
);
77 str
= "pthread_rwlock_tryrdlock";
78 res
= pthread_rwlock_tryrdlock(&context
->rwlock
);
81 str
= "pthread_rwlock_wrlock";
82 res
= pthread_rwlock_wrlock(&context
->rwlock
);
85 str
= "pthread_rwlock_trywrlock";
86 res
= pthread_rwlock_trywrlock(&context
->rwlock
);
90 if (try && res
== EBUSY
) {
93 fprintf(stderr
, "[%ld] %s: %s\n", context
->count
, str
, strerror(res
));
98 old
= __sync_fetch_and_or(&context
->value
, 1);
100 fprintf(stderr
, "[%ld] OR %lx\n", context
->count
, old
);
105 old
= __sync_fetch_and_and(&context
->value
, 0);
106 if ((old
& 1) != (exclusive
? 1 : 0)) {
107 fprintf(stderr
, "[%ld] AND %lx\n", context
->count
, old
);
111 res
= pthread_rwlock_unlock(&context
->rwlock
);
113 fprintf(stderr
, "[%ld] pthread_rwlock_unlock: %s\n", context
->count
, strerror(res
));
116 } while (__sync_fetch_and_sub(&context
->count
, 1) > 0);
121 int main(int argc
, char *argv
[])
123 struct context context
= {
124 .rwlock
= PTHREAD_RWLOCK_INITIALIZER
,
131 pthread_t p
[threads
+1];
133 mask_signals(true, false);
134 signal(SIGWINCH
, test_signal
);
136 for (i
= 0; i
< threads
; ++i
) {
137 res
= pthread_create(&p
[i
], NULL
, test_thread
, &context
);
141 pthread_create(&p
[threads
], NULL
, test_signal_thread
, &context
);
144 for (i
= 0; i
< threads
; ++i
) {
145 res
= pthread_join(p
[i
], NULL
);
148 res
= pthread_join(p
[threads
], NULL
);