1#	$NetBSD: t_pthread_once.sh,v 1.7 2025/04/16 01:52:42 riastradh Exp $
2#
3# Copyright (c) 2018 The NetBSD Foundation, Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27
28atf_test_case pthread_once
29pthread_once_head() {
30	atf_set "descr" "compile and run std::pthread_once"
31	atf_set "require.progs" "c++"
32}
33
34atf_test_case pthread_once_profile
35pthread_once_profile_head() {
36	atf_set "descr" "compile and run std::pthread_once with profiling option"
37	atf_set "require.progs" "c++"
38}
39
40atf_test_case pthread_once_pic
41pthread_once_pic_head() {
42	atf_set "descr" "compile and run PIC std::pthread_once"
43	atf_set "require.progs" "c++"
44}
45
46atf_test_case pthread_once_pic_32
47pthread_once_pic_32_head() {
48	atf_set "descr" "compile and run 32-bit PIC std::pthread_once"
49	atf_set "require.progs" "c++"
50}
51
52atf_test_case pthread_once_pic_profile
53pthread_once_pic_head() {
54	atf_set "descr" "compile and run PIC std::pthread_once with profiling &flag"
55	atf_set "require.progs" "c++"
56}
57
58atf_test_case pthread_once_pic_profile_32
59pthread_once_pic_profile_32_head() {
60	atf_set "descr" "compile and run 32-bit PIC std::pthread_once with profiling &flag"
61	atf_set "require.progs" "c++"
62}
63
64atf_test_case pthread_once_profile_32
65pthread_once_profile_32_head() {
66	atf_set "descr" "compile and run 32-bit std::pthread_once with profiling &flag"
67	atf_set "require.progs" "c++"
68}
69
70atf_test_case pthread_once_pie
71pthread_once_pie_head() {
72	atf_set "descr" "compile and run position independent (PIE) std::pthread_once"
73	atf_set "require.progs" "c++"
74}
75
76atf_test_case pthread_once_32
77pthread_once_32_head() {
78	atf_set "descr" "compile and run std::pthread_once for/in netbsd32 emulation"
79	atf_set "require.progs" "c++ file diff cat"
80}
81
82atf_test_case pthread_once_static
83pthread_once_static_head() {
84	atf_set "descr" "compile and run std::pthread_once with static &flag"
85	atf_set "require.progs" "c++"
86}
87
88pthread_once_body() {
89	cat > test.cpp << EOF
90#include <cstdio>
91#include <thread>
92int main(void) {
93        pthread_once_t flag = PTHREAD_ONCE_INIT;
94        pthread_once(&flag, [](){ printf("hello, world!\n"); });
95        return 0;
96}
97EOF
98	atf_check -s exit:0 -o ignore -e ignore c++ -o pthread_once test.cpp -pthread
99	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
100}
101
102pthread_once_profile_body() {
103	case `uname -m` in
104	riscv)	atf_expect_fail "PR port-riscv/59301:" \
105		    " riscv: missing MKPROFILE=yes support"
106		;;
107	esac
108
109	cat > test.cpp << EOF
110#include <cstdio>
111#include <thread>
112int main(void) {
113        pthread_once_t flag = PTHREAD_ONCE_INIT;
114        pthread_once(&flag, [](){ printf("hello, world!\n"); });
115        return 0;
116}
117EOF
118	atf_check -s exit:0 -o ignore -e ignore c++ -static -pg -o pthread_once test.cpp -pthread
119	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
120}
121
122pthread_once_profile_32_body() {
123	# check whether this arch is 64bit
124	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
125		atf_skip "this is not a 64 bit architecture"
126	fi
127	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
128		atf_skip "c++ -m32 not supported on this architecture"
129	else
130		if fgrep -q _LP64 ./def32; then
131			atf_fail "c++ -m32 does not generate netbsd32 binaries"
132		fi
133	fi
134
135	case `uname -m` in
136	riscv)	atf_expect_fail "PR port-riscv/59301:" \
137		    " riscv: missing MKPROFILE=yes support"
138		;;
139	esac
140
141	cat > test.cpp << EOF
142#include <cstdio>
143#include <thread>
144int main(void) {
145        pthread_once_t flag = PTHREAD_ONCE_INIT;
146        pthread_once(&flag, [](){ printf("hello, world!\n"); });
147        return 0;
148}
149EOF
150	atf_check -s exit:0 -o ignore -e ignore c++ -static -m32 -pg -o pthread_once test.cpp -pthread
151	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
152}
153
154pthread_once_pic_body() {
155	cat > test.cpp << EOF
156#include <stdlib.h>
157int callpic(void);
158int main(void) {callpic();exit(0);}
159EOF
160	cat > pic.cpp << EOF
161#include <cstdio>
162#include <thread>
163int callpic(void) {
164        pthread_once_t flag = PTHREAD_ONCE_INIT;
165        pthread_once(&flag, [](){ printf("hello, world!\n"); });
166        return 0;
167}
168EOF
169
170	atf_check -s exit:0 -o ignore -e ignore \
171	    c++ -fPIC -shared -o libtest.so pic.cpp
172	atf_check -s exit:0 -o ignore -e ignore \
173	    c++ -o pthread_once test.cpp -L. -ltest -pthread
174
175	export LD_LIBRARY_PATH=.
176	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
177}
178
179pthread_once_pic_32_body() {
180	# check whether this arch is 64bit
181	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
182		atf_skip "this is not a 64 bit architecture"
183	fi
184	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
185		atf_skip "c++ -m32 not supported on this architecture"
186	else
187		if fgrep -q _LP64 ./def32; then
188			atf_fail "c++ -m32 does not generate netbsd32 binaries"
189		fi
190	fi
191
192	cat > test.cpp << EOF
193#include <stdlib.h>
194int callpic(void);
195int main(void) {callpic();exit(0);}
196EOF
197	cat > pic.cpp << EOF
198#include <cstdio>
199#include <thread>
200int callpic(void) {
201        pthread_once_t flag = PTHREAD_ONCE_INIT;
202        pthread_once(&flag, [](){ printf("hello, world!\n"); });
203        return 0;
204}
205EOF
206
207	atf_check -s exit:0 -o ignore -e ignore \
208	    c++ -m32 -fPIC -shared -o libtest.so pic.cpp
209	atf_check -s exit:0 -o ignore -e ignore \
210	    c++ -m32 -o pthread_once test.cpp -L. -ltest -pthread
211
212	export LD_LIBRARY_PATH=.
213	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
214}
215
216pthread_once_pic_profile_body() {
217	case `uname -m` in
218	riscv)	atf_expect_fail "PR port-riscv/59301:" \
219		    " riscv: missing MKPROFILE=yes support"
220		;;
221	esac
222
223	cat > test.cpp << EOF
224#include <stdlib.h>
225int callpic(void);
226int main(void) {callpic();exit(0);}
227EOF
228	cat > pic.cpp << EOF
229#include <cstdio>
230#include <thread>
231int callpic(void) {
232        pthread_once_t flag = PTHREAD_ONCE_INIT;
233        pthread_once(&flag, [](){ printf("hello, world!\n"); });
234        return 0;
235}
236EOF
237
238	atf_check -s exit:0 -o ignore -e ignore \
239	    c++ -pg -fPIC -shared -o libtest.so pic.cpp
240	atf_check -s exit:0 -o ignore -e ignore \
241	    c++ -pg -o pthread_once test.cpp -L. -ltest -pthread
242
243	export LD_LIBRARY_PATH=.
244	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
245}
246
247pthread_once_pic_profile_32_body() {
248	# check whether this arch is 64bit
249	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
250		atf_skip "this is not a 64 bit architecture"
251	fi
252	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
253		atf_skip "c++ -m32 not supported on this architecture"
254	else
255		if fgrep -q _LP64 ./def32; then
256			atf_fail "c++ -m32 does not generate netbsd32 binaries"
257		fi
258	fi
259
260	case `uname -m` in
261	riscv)	atf_expect_fail "PR port-riscv/59301:" \
262		    " riscv: missing MKPROFILE=yes support"
263		;;
264	esac
265
266	cat > test.cpp << EOF
267#include <stdlib.h>
268int callpic(void);
269int main(void) {callpic();exit(0);}
270EOF
271	cat > pic.cpp << EOF
272#include <cstdio>
273#include <thread>
274int callpic(void) {
275        pthread_once_t flag = PTHREAD_ONCE_INIT;
276        pthread_once(&flag, [](){ printf("hello, world!\n"); });
277        return 0;
278}
279EOF
280
281	atf_check -s exit:0 -o ignore -e ignore \
282	    c++ -m32 -pg -fPIC -shared -o libtest.so pic.cpp
283	atf_check -s exit:0 -o ignore -e ignore \
284	    c++ -m32 -pg -o pthread_once test.cpp -L. -ltest -pthread
285
286	export LD_LIBRARY_PATH=.
287	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
288}
289
290pthread_once_pie_body() {
291	# check whether this arch supports -pie
292	if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
293		atf_skip "c++ -pie not supported on this architecture"
294	fi
295	cat > test.cpp << EOF
296#include <cstdio>
297#include <thread>
298int main(void) {
299        pthread_once_t flag = PTHREAD_ONCE_INIT;
300        pthread_once(&flag, [](){ printf("hello, world!\n"); });
301        return 0;
302}
303EOF
304	atf_check -s exit:0 -o ignore -e ignore c++ -fpie -pie -o pthread_once test.cpp -pthread
305	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
306}
307
308pthread_once_32_body() {
309	# check whether this arch is 64bit
310	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
311		atf_skip "this is not a 64 bit architecture"
312	fi
313	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
314		atf_skip "c++ -m32 not supported on this architecture"
315	else
316		if fgrep -q _LP64 ./def32; then
317			atf_fail "c++ -m32 does not generate netbsd32 binaries"
318		fi
319	fi
320
321	cat > test.cpp << EOF
322#include <cstdio>
323#include <thread>
324int main(void) {
325        pthread_once_t flag = PTHREAD_ONCE_INIT;
326        pthread_once(&flag, [](){ printf("hello, world!\n"); });
327        return 0;
328}
329EOF
330	atf_check -s exit:0 -o ignore -e ignore c++ -o pthread_once_32 -m32 test.cpp -pthread
331	atf_check -s exit:0 -o ignore -e ignore c++ -o pthread_once_64 test.cpp -pthread
332	file -b ./pthread_once_32 > ./ftype32
333	file -b ./pthread_once_64 > ./ftype64
334	if diff ./ftype32 ./ftype64 >/dev/null; then
335		atf_fail "generated binaries do not differ"
336	fi
337	echo "32bit binaries on this platform are:"
338	cat ./ftype32
339	echo "While native (64bit) binaries are:"
340	cat ./ftype64
341	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once_32
342
343	# do another test with static 32bit binaries
344	cat > test.cpp << EOF
345#include <cstdio>
346#include <thread>
347int main(void) {
348        pthread_once_t flag = PTHREAD_ONCE_INIT;
349        pthread_once(&flag, [](){ printf("hello, world!\n"); });
350        return 0;
351}
352EOF
353	atf_check -s exit:0 -o ignore -e ignore c++ -o pthread_once -m32 -pthread \
354	    -static test.cpp
355	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
356}
357
358pthread_once_static_body() {
359	cat > test.cpp << EOF
360#include <cstdio>
361#include <thread>
362int main(void) {
363        pthread_once_t flag = PTHREAD_ONCE_INIT;
364        pthread_once(&flag, [](){ printf("hello, world!\n"); });
365        return 0;
366}
367EOF
368	atf_check -s exit:0 -o ignore -e ignore c++ -static -o pthread_once test.cpp -pthread
369	atf_check -s exit:0 -o inline:"hello, world!\n" ./pthread_once
370}
371
372atf_init_test_cases()
373{
374
375	atf_add_test_case pthread_once
376	atf_add_test_case pthread_once_profile
377	atf_add_test_case pthread_once_pic
378	atf_add_test_case pthread_once_pie
379	atf_add_test_case pthread_once_32
380	atf_add_test_case pthread_once_static
381	atf_add_test_case pthread_once_pic_32
382	atf_add_test_case pthread_once_pic_profile
383	atf_add_test_case pthread_once_pic_profile_32
384	atf_add_test_case pthread_once_profile_32
385}
386