1*d1c5dc47SRobert Mustacchi /*
2*d1c5dc47SRobert Mustacchi * This file and its contents are supplied under the terms of the
3*d1c5dc47SRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
4*d1c5dc47SRobert Mustacchi * You may only use this file in accordance with the terms of version
5*d1c5dc47SRobert Mustacchi * 1.0 of the CDDL.
6*d1c5dc47SRobert Mustacchi *
7*d1c5dc47SRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
8*d1c5dc47SRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
9*d1c5dc47SRobert Mustacchi * http://www.illumos.org/license/CDDL.
10*d1c5dc47SRobert Mustacchi */
11*d1c5dc47SRobert Mustacchi
12*d1c5dc47SRobert Mustacchi /*
13*d1c5dc47SRobert Mustacchi * Copyright 2016 Joyent, Inc.
14*d1c5dc47SRobert Mustacchi */
15*d1c5dc47SRobert Mustacchi
16*d1c5dc47SRobert Mustacchi /*
17*d1c5dc47SRobert Mustacchi * Validate various C11 threads routines. Specifically we want to cover:
18*d1c5dc47SRobert Mustacchi *
19*d1c5dc47SRobert Mustacchi * o threads
20*d1c5dc47SRobert Mustacchi * o mutexes
21*d1c5dc47SRobert Mustacchi * o condition variables
22*d1c5dc47SRobert Mustacchi */
23*d1c5dc47SRobert Mustacchi
24*d1c5dc47SRobert Mustacchi #include <threads.h>
25*d1c5dc47SRobert Mustacchi #include <sys/debug.h>
26*d1c5dc47SRobert Mustacchi #include <stdlib.h>
27*d1c5dc47SRobert Mustacchi #include <unistd.h>
28*d1c5dc47SRobert Mustacchi
29*d1c5dc47SRobert Mustacchi #define STRESS_NTHREADS 128
30*d1c5dc47SRobert Mustacchi #define STRESS_COUNT 1000
31*d1c5dc47SRobert Mustacchi
32*d1c5dc47SRobert Mustacchi static mtx_t stress_mtx;
33*d1c5dc47SRobert Mustacchi static int stress_count;
34*d1c5dc47SRobert Mustacchi
35*d1c5dc47SRobert Mustacchi #define BROADCAST_NTHREADS 128
36*d1c5dc47SRobert Mustacchi
37*d1c5dc47SRobert Mustacchi static mtx_t broadcast_mtx;
38*d1c5dc47SRobert Mustacchi static cnd_t broadcast_cnd;
39*d1c5dc47SRobert Mustacchi static boolean_t broadcast_done;
40*d1c5dc47SRobert Mustacchi
41*d1c5dc47SRobert Mustacchi #define SIGNAL_NTHREADS 128
42*d1c5dc47SRobert Mustacchi
43*d1c5dc47SRobert Mustacchi static mtx_t signal_mtx;
44*d1c5dc47SRobert Mustacchi static cnd_t signal_cnd;
45*d1c5dc47SRobert Mustacchi static boolean_t signal_done;
46*d1c5dc47SRobert Mustacchi
47*d1c5dc47SRobert Mustacchi /*
48*d1c5dc47SRobert Mustacchi * This thread should only ever be used for detach.
49*d1c5dc47SRobert Mustacchi */
50*d1c5dc47SRobert Mustacchi static int
cthr_test_sleep_thr(void * arg)51*d1c5dc47SRobert Mustacchi cthr_test_sleep_thr(void *arg)
52*d1c5dc47SRobert Mustacchi {
53*d1c5dc47SRobert Mustacchi for (;;) {
54*d1c5dc47SRobert Mustacchi sleep(1000);
55*d1c5dc47SRobert Mustacchi }
56*d1c5dc47SRobert Mustacchi
57*d1c5dc47SRobert Mustacchi abort();
58*d1c5dc47SRobert Mustacchi }
59*d1c5dc47SRobert Mustacchi
60*d1c5dc47SRobert Mustacchi static void
cthr_test_mtx_init(void)61*d1c5dc47SRobert Mustacchi cthr_test_mtx_init(void)
62*d1c5dc47SRobert Mustacchi {
63*d1c5dc47SRobert Mustacchi mtx_t mtx;
64*d1c5dc47SRobert Mustacchi
65*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_plain), ==, thrd_success);
66*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
67*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_timed), ==, thrd_success);
68*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
69*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_plain | mtx_recursive), ==, thrd_success);
70*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
71*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_timed | mtx_recursive), ==, thrd_success);
72*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
73*d1c5dc47SRobert Mustacchi
74*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, UINT32_MAX), ==, thrd_error);
75*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, 42), ==, thrd_error);
76*d1c5dc47SRobert Mustacchi }
77*d1c5dc47SRobert Mustacchi
78*d1c5dc47SRobert Mustacchi static void
cthr_test_mtx_lockrec(void)79*d1c5dc47SRobert Mustacchi cthr_test_mtx_lockrec(void)
80*d1c5dc47SRobert Mustacchi {
81*d1c5dc47SRobert Mustacchi mtx_t mtx;
82*d1c5dc47SRobert Mustacchi
83*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_plain | mtx_recursive), ==, thrd_success);
84*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
85*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
86*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_trylock(&mtx), ==, thrd_success);
87*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
88*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
89*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
90*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
91*d1c5dc47SRobert Mustacchi }
92*d1c5dc47SRobert Mustacchi
93*d1c5dc47SRobert Mustacchi static void
cthr_test_mtx_trylock(void)94*d1c5dc47SRobert Mustacchi cthr_test_mtx_trylock(void)
95*d1c5dc47SRobert Mustacchi {
96*d1c5dc47SRobert Mustacchi mtx_t mtx;
97*d1c5dc47SRobert Mustacchi
98*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_plain), ==, thrd_success);
99*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_trylock(&mtx), ==, thrd_success);
100*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_trylock(&mtx), ==, thrd_busy);
101*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
102*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
103*d1c5dc47SRobert Mustacchi }
104*d1c5dc47SRobert Mustacchi
105*d1c5dc47SRobert Mustacchi static int
cthr_test_stress_thr(void * arg)106*d1c5dc47SRobert Mustacchi cthr_test_stress_thr(void *arg)
107*d1c5dc47SRobert Mustacchi {
108*d1c5dc47SRobert Mustacchi int i;
109*d1c5dc47SRobert Mustacchi int *ip = arg;
110*d1c5dc47SRobert Mustacchi
111*d1c5dc47SRobert Mustacchi for (i = 0; i < STRESS_COUNT; i++) {
112*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&stress_mtx), ==, thrd_success);
113*d1c5dc47SRobert Mustacchi *ip = *ip + 1;
114*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&stress_mtx), ==, thrd_success);
115*d1c5dc47SRobert Mustacchi }
116*d1c5dc47SRobert Mustacchi
117*d1c5dc47SRobert Mustacchi return (0);
118*d1c5dc47SRobert Mustacchi }
119*d1c5dc47SRobert Mustacchi
120*d1c5dc47SRobert Mustacchi static void
cthr_test_stress(void)121*d1c5dc47SRobert Mustacchi cthr_test_stress(void)
122*d1c5dc47SRobert Mustacchi {
123*d1c5dc47SRobert Mustacchi int i;
124*d1c5dc47SRobert Mustacchi thrd_t threads[STRESS_NTHREADS];
125*d1c5dc47SRobert Mustacchi
126*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&stress_mtx, mtx_plain), ==, thrd_success);
127*d1c5dc47SRobert Mustacchi for (i = 0; i < STRESS_NTHREADS; i++) {
128*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&threads[i], cthr_test_stress_thr,
129*d1c5dc47SRobert Mustacchi &stress_count), ==, thrd_success);
130*d1c5dc47SRobert Mustacchi }
131*d1c5dc47SRobert Mustacchi
132*d1c5dc47SRobert Mustacchi for (i = 0; i < STRESS_NTHREADS; i++) {
133*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
134*d1c5dc47SRobert Mustacchi }
135*d1c5dc47SRobert Mustacchi mtx_destroy(&stress_mtx);
136*d1c5dc47SRobert Mustacchi
137*d1c5dc47SRobert Mustacchi VERIFY3S(stress_count, ==, STRESS_NTHREADS * STRESS_COUNT);
138*d1c5dc47SRobert Mustacchi }
139*d1c5dc47SRobert Mustacchi
140*d1c5dc47SRobert Mustacchi static void
cthr_test_equal(void)141*d1c5dc47SRobert Mustacchi cthr_test_equal(void)
142*d1c5dc47SRobert Mustacchi {
143*d1c5dc47SRobert Mustacchi thrd_t self, other;
144*d1c5dc47SRobert Mustacchi
145*d1c5dc47SRobert Mustacchi self = thrd_current();
146*d1c5dc47SRobert Mustacchi
147*d1c5dc47SRobert Mustacchi VERIFY0(thrd_equal(self, self));
148*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&other, cthr_test_sleep_thr, NULL), ==,
149*d1c5dc47SRobert Mustacchi thrd_success);
150*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_equal(self, other), !=, 0);
151*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_equal(other, other), ==, 0);
152*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_detach(other), ==, thrd_success);
153*d1c5dc47SRobert Mustacchi }
154*d1c5dc47SRobert Mustacchi
155*d1c5dc47SRobert Mustacchi static void
cthr_test_detach_err(void)156*d1c5dc47SRobert Mustacchi cthr_test_detach_err(void)
157*d1c5dc47SRobert Mustacchi {
158*d1c5dc47SRobert Mustacchi thrd_t self, other;
159*d1c5dc47SRobert Mustacchi
160*d1c5dc47SRobert Mustacchi self = thrd_current();
161*d1c5dc47SRobert Mustacchi
162*d1c5dc47SRobert Mustacchi VERIFY0(thrd_equal(self, self));
163*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&other, cthr_test_sleep_thr, NULL), ==,
164*d1c5dc47SRobert Mustacchi thrd_success);
165*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_detach(other), ==, thrd_success);
166*d1c5dc47SRobert Mustacchi
167*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(self, NULL), ==, thrd_error);
168*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(other, NULL), ==, thrd_error);
169*d1c5dc47SRobert Mustacchi }
170*d1c5dc47SRobert Mustacchi
171*d1c5dc47SRobert Mustacchi static int
cthr_test_detach_thr0(void * arg)172*d1c5dc47SRobert Mustacchi cthr_test_detach_thr0(void *arg)
173*d1c5dc47SRobert Mustacchi {
174*d1c5dc47SRobert Mustacchi thrd_exit(23);
175*d1c5dc47SRobert Mustacchi abort();
176*d1c5dc47SRobert Mustacchi }
177*d1c5dc47SRobert Mustacchi
178*d1c5dc47SRobert Mustacchi static int
cthr_test_detach_thr1(void * arg)179*d1c5dc47SRobert Mustacchi cthr_test_detach_thr1(void *arg)
180*d1c5dc47SRobert Mustacchi {
181*d1c5dc47SRobert Mustacchi return (42);
182*d1c5dc47SRobert Mustacchi }
183*d1c5dc47SRobert Mustacchi
184*d1c5dc47SRobert Mustacchi static void
cthr_test_detach(void)185*d1c5dc47SRobert Mustacchi cthr_test_detach(void)
186*d1c5dc47SRobert Mustacchi {
187*d1c5dc47SRobert Mustacchi int status;
188*d1c5dc47SRobert Mustacchi thrd_t thrd;
189*d1c5dc47SRobert Mustacchi
190*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&thrd, cthr_test_detach_thr0, NULL), ==,
191*d1c5dc47SRobert Mustacchi thrd_success);
192*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(thrd, &status), ==, thrd_success);
193*d1c5dc47SRobert Mustacchi VERIFY3S(status, ==, 23);
194*d1c5dc47SRobert Mustacchi
195*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&thrd, cthr_test_detach_thr1, NULL), ==,
196*d1c5dc47SRobert Mustacchi thrd_success);
197*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(thrd, &status), ==, thrd_success);
198*d1c5dc47SRobert Mustacchi VERIFY3S(status, ==, 42);
199*d1c5dc47SRobert Mustacchi }
200*d1c5dc47SRobert Mustacchi
201*d1c5dc47SRobert Mustacchi static void
cthr_test_sleep(void)202*d1c5dc47SRobert Mustacchi cthr_test_sleep(void)
203*d1c5dc47SRobert Mustacchi {
204*d1c5dc47SRobert Mustacchi struct timespec ts;
205*d1c5dc47SRobert Mustacchi hrtime_t start, end;
206*d1c5dc47SRobert Mustacchi long stime = 10 * NANOSEC / MILLISEC;
207*d1c5dc47SRobert Mustacchi
208*d1c5dc47SRobert Mustacchi ts.tv_sec = 1;
209*d1c5dc47SRobert Mustacchi ts.tv_nsec = -1;
210*d1c5dc47SRobert Mustacchi
211*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_sleep(&ts, NULL), <, -1);
212*d1c5dc47SRobert Mustacchi
213*d1c5dc47SRobert Mustacchi ts.tv_sec = 0;
214*d1c5dc47SRobert Mustacchi ts.tv_nsec = stime;
215*d1c5dc47SRobert Mustacchi start = gethrtime();
216*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_sleep(&ts, NULL), ==, 0);
217*d1c5dc47SRobert Mustacchi end = gethrtime();
218*d1c5dc47SRobert Mustacchi
219*d1c5dc47SRobert Mustacchi VERIFY3S(end - start, >, stime);
220*d1c5dc47SRobert Mustacchi }
221*d1c5dc47SRobert Mustacchi
222*d1c5dc47SRobert Mustacchi static int
cthr_test_broadcast_thr(void * arg)223*d1c5dc47SRobert Mustacchi cthr_test_broadcast_thr(void *arg)
224*d1c5dc47SRobert Mustacchi {
225*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&broadcast_mtx), ==, thrd_success);
226*d1c5dc47SRobert Mustacchi while (broadcast_done == B_FALSE)
227*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_wait(&broadcast_cnd, &broadcast_mtx), ==,
228*d1c5dc47SRobert Mustacchi thrd_success);
229*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&broadcast_mtx), ==, thrd_success);
230*d1c5dc47SRobert Mustacchi
231*d1c5dc47SRobert Mustacchi return (0);
232*d1c5dc47SRobert Mustacchi }
233*d1c5dc47SRobert Mustacchi
234*d1c5dc47SRobert Mustacchi static void
cthr_test_broadcast(void)235*d1c5dc47SRobert Mustacchi cthr_test_broadcast(void)
236*d1c5dc47SRobert Mustacchi {
237*d1c5dc47SRobert Mustacchi int i;
238*d1c5dc47SRobert Mustacchi thrd_t threads[BROADCAST_NTHREADS];
239*d1c5dc47SRobert Mustacchi
240*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&broadcast_mtx, mtx_plain), ==, thrd_success);
241*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_init(&broadcast_cnd), ==, thrd_success);
242*d1c5dc47SRobert Mustacchi for (i = 0; i < BROADCAST_NTHREADS; i++) {
243*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&threads[i], cthr_test_broadcast_thr,
244*d1c5dc47SRobert Mustacchi NULL), ==, thrd_success);
245*d1c5dc47SRobert Mustacchi }
246*d1c5dc47SRobert Mustacchi
247*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&broadcast_mtx), ==, thrd_success);
248*d1c5dc47SRobert Mustacchi broadcast_done = B_TRUE;
249*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&broadcast_mtx), ==, thrd_success);
250*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_broadcast(&broadcast_cnd), ==, thrd_success);
251*d1c5dc47SRobert Mustacchi
252*d1c5dc47SRobert Mustacchi for (i = 0; i < STRESS_NTHREADS; i++) {
253*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
254*d1c5dc47SRobert Mustacchi }
255*d1c5dc47SRobert Mustacchi
256*d1c5dc47SRobert Mustacchi mtx_destroy(&broadcast_mtx);
257*d1c5dc47SRobert Mustacchi cnd_destroy(&broadcast_cnd);
258*d1c5dc47SRobert Mustacchi }
259*d1c5dc47SRobert Mustacchi
260*d1c5dc47SRobert Mustacchi
261*d1c5dc47SRobert Mustacchi static int
cthr_test_signal_thr(void * arg)262*d1c5dc47SRobert Mustacchi cthr_test_signal_thr(void *arg)
263*d1c5dc47SRobert Mustacchi {
264*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&signal_mtx), ==, thrd_success);
265*d1c5dc47SRobert Mustacchi while (signal_done == B_FALSE)
266*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_wait(&signal_cnd, &signal_mtx), ==,
267*d1c5dc47SRobert Mustacchi thrd_success);
268*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&signal_mtx), ==, thrd_success);
269*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_signal(&signal_cnd), ==, thrd_success);
270*d1c5dc47SRobert Mustacchi
271*d1c5dc47SRobert Mustacchi return (0);
272*d1c5dc47SRobert Mustacchi }
273*d1c5dc47SRobert Mustacchi
274*d1c5dc47SRobert Mustacchi static void
cthr_test_signal(void)275*d1c5dc47SRobert Mustacchi cthr_test_signal(void)
276*d1c5dc47SRobert Mustacchi {
277*d1c5dc47SRobert Mustacchi int i;
278*d1c5dc47SRobert Mustacchi thrd_t threads[SIGNAL_NTHREADS];
279*d1c5dc47SRobert Mustacchi
280*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&signal_mtx, mtx_plain), ==, thrd_success);
281*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_init(&signal_cnd), ==, thrd_success);
282*d1c5dc47SRobert Mustacchi for (i = 0; i < SIGNAL_NTHREADS; i++) {
283*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&threads[i], cthr_test_signal_thr, NULL),
284*d1c5dc47SRobert Mustacchi ==, thrd_success);
285*d1c5dc47SRobert Mustacchi }
286*d1c5dc47SRobert Mustacchi
287*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&signal_mtx), ==, thrd_success);
288*d1c5dc47SRobert Mustacchi signal_done = B_TRUE;
289*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&signal_mtx), ==, thrd_success);
290*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_signal(&signal_cnd), ==, thrd_success);
291*d1c5dc47SRobert Mustacchi
292*d1c5dc47SRobert Mustacchi for (i = 0; i < STRESS_NTHREADS; i++) {
293*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
294*d1c5dc47SRobert Mustacchi }
295*d1c5dc47SRobert Mustacchi
296*d1c5dc47SRobert Mustacchi mtx_destroy(&signal_mtx);
297*d1c5dc47SRobert Mustacchi cnd_destroy(&signal_cnd);
298*d1c5dc47SRobert Mustacchi }
299*d1c5dc47SRobert Mustacchi
300*d1c5dc47SRobert Mustacchi static void
cthr_test_cndtime(void)301*d1c5dc47SRobert Mustacchi cthr_test_cndtime(void)
302*d1c5dc47SRobert Mustacchi {
303*d1c5dc47SRobert Mustacchi mtx_t mtx;
304*d1c5dc47SRobert Mustacchi cnd_t cnd;
305*d1c5dc47SRobert Mustacchi struct timespec ts;
306*d1c5dc47SRobert Mustacchi
307*d1c5dc47SRobert Mustacchi ts.tv_sec = 0;
308*d1c5dc47SRobert Mustacchi ts.tv_nsec = 1 * NANOSEC / MILLISEC;
309*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_plain), ==, thrd_success);
310*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_init(&cnd), ==, thrd_success);
311*d1c5dc47SRobert Mustacchi
312*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
313*d1c5dc47SRobert Mustacchi VERIFY3S(cnd_timedwait(&cnd, &mtx, &ts), ==, thrd_timedout);
314*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
315*d1c5dc47SRobert Mustacchi
316*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
317*d1c5dc47SRobert Mustacchi cnd_destroy(&cnd);
318*d1c5dc47SRobert Mustacchi }
319*d1c5dc47SRobert Mustacchi
320*d1c5dc47SRobert Mustacchi static void
cthr_test_mtx_selftime(void)321*d1c5dc47SRobert Mustacchi cthr_test_mtx_selftime(void)
322*d1c5dc47SRobert Mustacchi {
323*d1c5dc47SRobert Mustacchi mtx_t mtx;
324*d1c5dc47SRobert Mustacchi struct timespec ts;
325*d1c5dc47SRobert Mustacchi
326*d1c5dc47SRobert Mustacchi ts.tv_sec = 0;
327*d1c5dc47SRobert Mustacchi ts.tv_nsec = 1 * NANOSEC / MILLISEC;
328*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_timed), ==, thrd_success);
329*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
330*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_timedlock(&mtx, &ts), ==, thrd_timedout);
331*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
332*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
333*d1c5dc47SRobert Mustacchi }
334*d1c5dc47SRobert Mustacchi
335*d1c5dc47SRobert Mustacchi static int
cthr_test_mtx_busy_thr(void * arg)336*d1c5dc47SRobert Mustacchi cthr_test_mtx_busy_thr(void *arg)
337*d1c5dc47SRobert Mustacchi {
338*d1c5dc47SRobert Mustacchi mtx_t *mtx = arg;
339*d1c5dc47SRobert Mustacchi struct timespec ts;
340*d1c5dc47SRobert Mustacchi
341*d1c5dc47SRobert Mustacchi ts.tv_sec = 0;
342*d1c5dc47SRobert Mustacchi ts.tv_nsec = 1 * NANOSEC / MILLISEC;
343*d1c5dc47SRobert Mustacchi
344*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_trylock(mtx), ==, thrd_busy);
345*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_timedlock(mtx, &ts), ==, thrd_timedout);
346*d1c5dc47SRobert Mustacchi
347*d1c5dc47SRobert Mustacchi return (0);
348*d1c5dc47SRobert Mustacchi }
349*d1c5dc47SRobert Mustacchi
350*d1c5dc47SRobert Mustacchi static void
cthr_test_mtx_busy(void)351*d1c5dc47SRobert Mustacchi cthr_test_mtx_busy(void)
352*d1c5dc47SRobert Mustacchi {
353*d1c5dc47SRobert Mustacchi mtx_t mtx;
354*d1c5dc47SRobert Mustacchi thrd_t thrd;
355*d1c5dc47SRobert Mustacchi
356*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_init(&mtx, mtx_timed), ==, thrd_success);
357*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
358*d1c5dc47SRobert Mustacchi
359*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_create(&thrd, cthr_test_mtx_busy_thr, &mtx), ==,
360*d1c5dc47SRobert Mustacchi thrd_success);
361*d1c5dc47SRobert Mustacchi VERIFY3S(thrd_join(thrd, NULL), ==, thrd_success);
362*d1c5dc47SRobert Mustacchi
363*d1c5dc47SRobert Mustacchi VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
364*d1c5dc47SRobert Mustacchi mtx_destroy(&mtx);
365*d1c5dc47SRobert Mustacchi }
366*d1c5dc47SRobert Mustacchi
367*d1c5dc47SRobert Mustacchi int
main(void)368*d1c5dc47SRobert Mustacchi main(void)
369*d1c5dc47SRobert Mustacchi {
370*d1c5dc47SRobert Mustacchi cthr_test_mtx_init();
371*d1c5dc47SRobert Mustacchi cthr_test_mtx_lockrec();
372*d1c5dc47SRobert Mustacchi cthr_test_mtx_trylock();
373*d1c5dc47SRobert Mustacchi cthr_test_stress();
374*d1c5dc47SRobert Mustacchi cthr_test_equal();
375*d1c5dc47SRobert Mustacchi cthr_test_detach_err();
376*d1c5dc47SRobert Mustacchi cthr_test_detach();
377*d1c5dc47SRobert Mustacchi cthr_test_sleep();
378*d1c5dc47SRobert Mustacchi cthr_test_broadcast();
379*d1c5dc47SRobert Mustacchi cthr_test_signal();
380*d1c5dc47SRobert Mustacchi cthr_test_cndtime();
381*d1c5dc47SRobert Mustacchi cthr_test_mtx_selftime();
382*d1c5dc47SRobert Mustacchi cthr_test_mtx_busy();
383*d1c5dc47SRobert Mustacchi
384*d1c5dc47SRobert Mustacchi return (0);
385*d1c5dc47SRobert Mustacchi }
386