xref: /netbsd-src/tests/lib/libpthread/t_thrd.c (revision 8012ca3f0e0935df89028ef98e60992407bddc93)
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