xref: /titanic_44/usr/src/test/libc-tests/tests/c11_threads.c (revision d1c5dc47e23888b05d4095e8983ccf62acbc69fa)
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