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 /*
13fc2512cfSRobert Mustacchi * Copyright 2016 Joyent, Inc.
14fc2512cfSRobert Mustacchi */
15fc2512cfSRobert Mustacchi
16fc2512cfSRobert Mustacchi /*
17fc2512cfSRobert Mustacchi * Test call_once(3C)
18fc2512cfSRobert Mustacchi */
19fc2512cfSRobert Mustacchi
20fc2512cfSRobert Mustacchi #include <threads.h>
21fc2512cfSRobert Mustacchi #include <sys/debug.h>
22fc2512cfSRobert Mustacchi
23fc2512cfSRobert Mustacchi #define CO_NTHREADS 32
24fc2512cfSRobert Mustacchi
25fc2512cfSRobert Mustacchi static int co_val = 41;
26fc2512cfSRobert Mustacchi static mtx_t co_once_mtx;
27fc2512cfSRobert Mustacchi static mtx_t co_mtx;
28fc2512cfSRobert Mustacchi static boolean_t co_go = B_FALSE;
29fc2512cfSRobert Mustacchi static once_flag co_once = ONCE_FLAG_INIT;
30fc2512cfSRobert Mustacchi static cnd_t co_cnd;
31fc2512cfSRobert Mustacchi
32fc2512cfSRobert Mustacchi static void
co_once_func(void)33fc2512cfSRobert Mustacchi co_once_func(void)
34fc2512cfSRobert Mustacchi {
35fc2512cfSRobert Mustacchi VERIFY3S(mtx_lock(&co_once_mtx), ==, thrd_success);
36fc2512cfSRobert Mustacchi co_val++;
37fc2512cfSRobert Mustacchi VERIFY3S(mtx_unlock(&co_once_mtx), ==, thrd_success);
38fc2512cfSRobert Mustacchi }
39fc2512cfSRobert Mustacchi
40fc2512cfSRobert Mustacchi /*ARGSUSED*/
41fc2512cfSRobert Mustacchi static int
co_thr(void * arg)42fc2512cfSRobert Mustacchi co_thr(void *arg)
43fc2512cfSRobert Mustacchi {
44fc2512cfSRobert Mustacchi VERIFY3S(mtx_lock(&co_mtx), ==, thrd_success);
45*b36afad7SRobert Mustacchi while (co_go == B_FALSE) {
46*b36afad7SRobert Mustacchi (void) cnd_wait(&co_cnd, &co_mtx);
47*b36afad7SRobert Mustacchi }
48fc2512cfSRobert Mustacchi VERIFY3S(mtx_unlock(&co_mtx), ==, thrd_success);
49fc2512cfSRobert Mustacchi call_once(&co_once, co_once_func);
50fc2512cfSRobert Mustacchi return (0);
51fc2512cfSRobert Mustacchi }
52fc2512cfSRobert Mustacchi
53fc2512cfSRobert Mustacchi int
main(void)54fc2512cfSRobert Mustacchi main(void)
55fc2512cfSRobert Mustacchi {
56fc2512cfSRobert Mustacchi int i;
57fc2512cfSRobert Mustacchi thrd_t threads[CO_NTHREADS];
58fc2512cfSRobert Mustacchi
59fc2512cfSRobert Mustacchi VERIFY3S(mtx_init(&co_once_mtx, mtx_plain), ==, thrd_success);
60fc2512cfSRobert Mustacchi VERIFY3S(mtx_init(&co_mtx, mtx_plain), ==, thrd_success);
61fc2512cfSRobert Mustacchi VERIFY3S(cnd_init(&co_cnd), ==, thrd_success);
62fc2512cfSRobert Mustacchi
63fc2512cfSRobert Mustacchi for (i = 0; i < CO_NTHREADS; i++) {
64fc2512cfSRobert Mustacchi VERIFY3S(thrd_create(&threads[i], co_thr, NULL), ==,
65fc2512cfSRobert Mustacchi thrd_success);
66fc2512cfSRobert Mustacchi }
67fc2512cfSRobert Mustacchi
68fc2512cfSRobert Mustacchi VERIFY3S(mtx_lock(&co_mtx), ==, thrd_success);
69fc2512cfSRobert Mustacchi co_go = B_TRUE;
70fc2512cfSRobert Mustacchi VERIFY3S(mtx_unlock(&co_mtx), ==, thrd_success);
71fc2512cfSRobert Mustacchi VERIFY3S(cnd_broadcast(&co_cnd), ==, thrd_success);
72fc2512cfSRobert Mustacchi
73fc2512cfSRobert Mustacchi for (i = 0; i < CO_NTHREADS; i++) {
74fc2512cfSRobert Mustacchi VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
75fc2512cfSRobert Mustacchi }
76fc2512cfSRobert Mustacchi VERIFY3S(co_val, ==, 42);
77fc2512cfSRobert Mustacchi
78fc2512cfSRobert Mustacchi return (0);
79fc2512cfSRobert Mustacchi }
80