1*8012ca3fSmsaitoh /* $NetBSD: t_thrd.c,v 1.2 2020/05/14 08:34:19 msaitoh Exp $ */
2a9ca1710Skamil
3a9ca1710Skamil /*-
4a9ca1710Skamil * Copyright (c) 2019 The NetBSD Foundation, Inc.
5a9ca1710Skamil * All rights reserved.
6a9ca1710Skamil *
7a9ca1710Skamil * This code is derived from software contributed to The NetBSD Foundation
8a9ca1710Skamil * by Kamil Rytarowski.
9a9ca1710Skamil *
10a9ca1710Skamil * Redistribution and use in source and binary forms, with or without
11a9ca1710Skamil * modification, are permitted provided that the following conditions
12a9ca1710Skamil * are met:
13a9ca1710Skamil * 1. Redistributions of source code must retain the above copyright
14a9ca1710Skamil * notice, this list of conditions and the following disclaimer.
15a9ca1710Skamil * 2. Redistributions in binary form must reproduce the above copyright
16a9ca1710Skamil * notice, this list of conditions and the following disclaimer in the
17a9ca1710Skamil * documentation and/or other materials provided with the distribution.
18a9ca1710Skamil *
19a9ca1710Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20a9ca1710Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21a9ca1710Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a9ca1710Skamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23a9ca1710Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24a9ca1710Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25a9ca1710Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26a9ca1710Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27a9ca1710Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28a9ca1710Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29a9ca1710Skamil * POSSIBILITY OF SUCH DAMAGE.
30a9ca1710Skamil */
31a9ca1710Skamil
32a9ca1710Skamil #include <sys/cdefs.h>
33a9ca1710Skamil __COPYRIGHT("@(#) Copyright (c) 2019\
34a9ca1710Skamil The NetBSD Foundation, inc. All rights reserved.");
35*8012ca3fSmsaitoh __RCSID("$NetBSD: t_thrd.c,v 1.2 2020/05/14 08:34:19 msaitoh Exp $");
36a9ca1710Skamil
37a9ca1710Skamil #include <signal.h>
38a9ca1710Skamil #include <stdbool.h>
39a9ca1710Skamil #include <threads.h>
40a9ca1710Skamil #include <time.h>
41a9ca1710Skamil
42a9ca1710Skamil #include <atf-c.h>
43a9ca1710Skamil
44a9ca1710Skamil ATF_TC(thrd_create);
ATF_TC_HEAD(thrd_create,tc)45a9ca1710Skamil ATF_TC_HEAD(thrd_create, tc)
46a9ca1710Skamil {
47a9ca1710Skamil atf_tc_set_md_var(tc, "descr", "Test C11 thrd_create(3)");
48a9ca1710Skamil }
49a9ca1710Skamil
50a9ca1710Skamil #define TC_ADDON 5
51a9ca1710Skamil
52a9ca1710Skamil static int
tcr_func(void * arg)53a9ca1710Skamil tcr_func(void *arg)
54a9ca1710Skamil {
55a9ca1710Skamil int a;
56a9ca1710Skamil
57a9ca1710Skamil a = (int)(intptr_t)arg;
58a9ca1710Skamil
59a9ca1710Skamil return a + TC_ADDON;
60a9ca1710Skamil }
61a9ca1710Skamil
ATF_TC_BODY(thrd_create,tc)62a9ca1710Skamil ATF_TC_BODY(thrd_create, tc)
63a9ca1710Skamil {
64a9ca1710Skamil thrd_t t;
65a9ca1710Skamil const int a = 5;
66a9ca1710Skamil int b;
67a9ca1710Skamil void *v;
68a9ca1710Skamil
69a9ca1710Skamil v = (void *)(intptr_t)a;
70a9ca1710Skamil
71a9ca1710Skamil ATF_REQUIRE_EQ(thrd_create(&t, tcr_func, v), thrd_success);
72a9ca1710Skamil ATF_REQUIRE_EQ(thrd_join(t, &b), thrd_success);
73a9ca1710Skamil ATF_REQUIRE_EQ(a + TC_ADDON, b);
74a9ca1710Skamil }
75a9ca1710Skamil
76a9ca1710Skamil ATF_TC(thrd_current);
ATF_TC_HEAD(thrd_current,tc)77a9ca1710Skamil ATF_TC_HEAD(thrd_current, tc)
78a9ca1710Skamil {
79a9ca1710Skamil atf_tc_set_md_var(tc, "descr", "Test C11 thrd_current(3)");
80a9ca1710Skamil }
81a9ca1710Skamil
82a9ca1710Skamil static int
tcur_func(void * arg __unused)83a9ca1710Skamil tcur_func(void *arg __unused)
84a9ca1710Skamil {
85a9ca1710Skamil
86a9ca1710Skamil return 0;
87a9ca1710Skamil }
88a9ca1710Skamil
ATF_TC_BODY(thrd_current,tc)89a9ca1710Skamil ATF_TC_BODY(thrd_current, tc)
90a9ca1710Skamil {
91a9ca1710Skamil thrd_t s, t;
92a9ca1710Skamil
93a9ca1710Skamil s = thrd_current();
94a9ca1710Skamil
95a9ca1710Skamil ATF_REQUIRE(thrd_equal(s, s) != 0);
96a9ca1710Skamil ATF_REQUIRE_EQ(thrd_create(&t, tcur_func, NULL), thrd_success);
97a9ca1710Skamil ATF_REQUIRE(thrd_equal(t, s) == 0);
98a9ca1710Skamil ATF_REQUIRE(thrd_equal(s, t) == 0);
99a9ca1710Skamil ATF_REQUIRE(thrd_equal(t, t) != 0);
100a9ca1710Skamil
101a9ca1710Skamil ATF_REQUIRE_EQ(thrd_join(t, NULL), thrd_success);
102a9ca1710Skamil }
103a9ca1710Skamil
104a9ca1710Skamil ATF_TC(thrd_detach);
ATF_TC_HEAD(thrd_detach,tc)105a9ca1710Skamil ATF_TC_HEAD(thrd_detach, tc)
106a9ca1710Skamil {
107a9ca1710Skamil atf_tc_set_md_var(tc, "descr", "Test C11 thrd_detach(3)");
108a9ca1710Skamil }
109a9ca1710Skamil
110a9ca1710Skamil static int
tdet_func(void * arg __unused)111a9ca1710Skamil tdet_func(void *arg __unused)
112a9ca1710Skamil {
113a9ca1710Skamil
114a9ca1710Skamil return 0;
115a9ca1710Skamil }
116a9ca1710Skamil
ATF_TC_BODY(thrd_detach,tc)117a9ca1710Skamil ATF_TC_BODY(thrd_detach, tc)
118a9ca1710Skamil {
119a9ca1710Skamil thrd_t t;
120a9ca1710Skamil
121a9ca1710Skamil ATF_REQUIRE_EQ(thrd_create(&t, tdet_func, NULL), thrd_success);
122a9ca1710Skamil ATF_REQUIRE_EQ(thrd_detach(t), thrd_success);
123a9ca1710Skamil }
124a9ca1710Skamil
125a9ca1710Skamil ATF_TC(thrd_exit);
ATF_TC_HEAD(thrd_exit,tc)126a9ca1710Skamil ATF_TC_HEAD(thrd_exit, tc)
127a9ca1710Skamil {
128a9ca1710Skamil atf_tc_set_md_var(tc, "descr", "Test C11 thrd_exit(3)");
129a9ca1710Skamil }
130a9ca1710Skamil
131a9ca1710Skamil static void
tex_func2(void)132a9ca1710Skamil tex_func2(void)
133a9ca1710Skamil {
134a9ca1710Skamil
135a9ca1710Skamil thrd_exit(1);
136a9ca1710Skamil }
137a9ca1710Skamil
138a9ca1710Skamil static int
tex_func(void * arg __unused)139a9ca1710Skamil tex_func(void *arg __unused)
140a9ca1710Skamil {
141a9ca1710Skamil
142a9ca1710Skamil tex_func2();
143a9ca1710Skamil
144a9ca1710Skamil return -1;
145a9ca1710Skamil }
146a9ca1710Skamil
ATF_TC_BODY(thrd_exit,tc)147a9ca1710Skamil ATF_TC_BODY(thrd_exit, tc)
148a9ca1710Skamil {
149a9ca1710Skamil thrd_t t;
150a9ca1710Skamil int b = 0;
151a9ca1710Skamil
152a9ca1710Skamil ATF_REQUIRE_EQ(thrd_create(&t, tex_func, NULL), thrd_success);
153a9ca1710Skamil ATF_REQUIRE_EQ(thrd_join(t, &b), thrd_success);
154a9ca1710Skamil ATF_REQUIRE_EQ(b, 1);
155a9ca1710Skamil }
156a9ca1710Skamil
157a9ca1710Skamil ATF_TC(thrd_sleep);
ATF_TC_HEAD(thrd_sleep,tc)158a9ca1710Skamil ATF_TC_HEAD(thrd_sleep, tc)
159a9ca1710Skamil {
160a9ca1710Skamil atf_tc_set_md_var(tc, "descr", "Test C11 thrd_sleep(3)");
161a9ca1710Skamil }
162a9ca1710Skamil
163a9ca1710Skamil static int alarmed;
164a9ca1710Skamil
165a9ca1710Skamil static void
alarm_handler(int signum)166a9ca1710Skamil alarm_handler(int signum)
167a9ca1710Skamil {
168a9ca1710Skamil
169a9ca1710Skamil ATF_REQUIRE_EQ(signum, SIGALRM);
170a9ca1710Skamil ++alarmed;
171a9ca1710Skamil }
172a9ca1710Skamil
ATF_TC_BODY(thrd_sleep,tc)173a9ca1710Skamil ATF_TC_BODY(thrd_sleep, tc)
174a9ca1710Skamil {
175a9ca1710Skamil struct timespec start, stop, diff;
176a9ca1710Skamil struct timespec ts, rem;
177a9ca1710Skamil struct timespec zero;
178a9ca1710Skamil struct sigaction sa;
179a9ca1710Skamil struct itimerval timer;
180a9ca1710Skamil
181a9ca1710Skamil zero.tv_sec = 0;
182a9ca1710Skamil zero.tv_nsec = 0;
183a9ca1710Skamil
184a9ca1710Skamil ts.tv_sec = 1;
185a9ca1710Skamil ts.tv_nsec = -1;
186a9ca1710Skamil ATF_REQUIRE_EQ(!thrd_sleep(&ts, NULL), 0);
187a9ca1710Skamil
188a9ca1710Skamil ts.tv_sec = 0;
189a9ca1710Skamil ts.tv_nsec = 1000000000/100; /* 1/100 sec */
190a9ca1710Skamil ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &start), 0);
191a9ca1710Skamil ATF_REQUIRE_EQ(thrd_sleep(&ts, &rem), 0);
192a9ca1710Skamil ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &stop), 0);
193a9ca1710Skamil timespecsub(&stop, &start, &diff);
194a9ca1710Skamil ATF_REQUIRE(timespeccmp(&diff, &ts, >=));
195a9ca1710Skamil ATF_REQUIRE(timespeccmp(&zero, &rem, ==));
196a9ca1710Skamil
197a9ca1710Skamil ts.tv_sec = 1;
198a9ca1710Skamil ts.tv_nsec = 0;
199a9ca1710Skamil memset(&sa, 0, sizeof(sa));
200a9ca1710Skamil sa.sa_handler = alarm_handler;
201a9ca1710Skamil sigaction(SIGALRM, &sa, NULL);
202a9ca1710Skamil memset(&timer, 0, sizeof(timer));
203a9ca1710Skamil timer.it_value.tv_sec = 0;
204a9ca1710Skamil timer.it_value.tv_usec = 100000; /* 100 msec */
205a9ca1710Skamil ATF_REQUIRE_EQ(setitimer(ITIMER_MONOTONIC, &timer, NULL), 0);
206a9ca1710Skamil ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &start), 0);
207a9ca1710Skamil ATF_REQUIRE_EQ(!thrd_sleep(&ts, &rem), 0);
208a9ca1710Skamil ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &stop), 0);
209a9ca1710Skamil timespecsub(&stop, &start, &diff);
210a9ca1710Skamil ATF_REQUIRE(timespeccmp(&diff, &ts, <));
211a9ca1710Skamil ATF_REQUIRE(timespeccmp(&zero, &rem, !=));
212a9ca1710Skamil ATF_REQUIRE_EQ(alarmed, 1);
213a9ca1710Skamil }
214a9ca1710Skamil
215a9ca1710Skamil ATF_TC(thrd_yield);
ATF_TC_HEAD(thrd_yield,tc)216a9ca1710Skamil ATF_TC_HEAD(thrd_yield, tc)
217a9ca1710Skamil {
218a9ca1710Skamil atf_tc_set_md_var(tc, "descr", "Test C11 thrd_yield(3)");
219a9ca1710Skamil }
220a9ca1710Skamil
ATF_TC_BODY(thrd_yield,tc)221a9ca1710Skamil ATF_TC_BODY(thrd_yield, tc)
222a9ca1710Skamil {
223a9ca1710Skamil
224a9ca1710Skamil thrd_yield();
225a9ca1710Skamil }
226a9ca1710Skamil
ATF_TP_ADD_TCS(tp)227a9ca1710Skamil ATF_TP_ADD_TCS(tp)
228a9ca1710Skamil {
229a9ca1710Skamil ATF_TP_ADD_TC(tp, thrd_create);
230a9ca1710Skamil ATF_TP_ADD_TC(tp, thrd_current);
231a9ca1710Skamil ATF_TP_ADD_TC(tp, thrd_detach);
232a9ca1710Skamil ATF_TP_ADD_TC(tp, thrd_exit);
233a9ca1710Skamil ATF_TP_ADD_TC(tp, thrd_sleep);
234*8012ca3fSmsaitoh ATF_TP_ADD_TC(tp, thrd_yield);
235a9ca1710Skamil
236a9ca1710Skamil return atf_no_error();
237a9ca1710Skamil }
238