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