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