t_call_once2.sh revision 1.2 1 # $NetBSD: t_call_once2.sh,v 1.2 2019/05/15 13:43:45 christos 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
28 atf_test_case call_once2
29 call_once2_head() {
30 atf_set "descr" "compile and run std::call_once"
31 atf_set "require.progs" "c++"
32 }
33
34 atf_test_case call_once2_profile
35 call_once2_profile_head() {
36 atf_set "descr" "compile and run std::call_once with profiling option"
37 atf_set "require.progs" "c++"
38 }
39
40 atf_test_case call_once2_pic
41 call_once2_pic_head() {
42 atf_set "descr" "compile and run PIC std::call_once"
43 atf_set "require.progs" "c++"
44 }
45
46 atf_test_case call_once2_pic_32
47 call_once2_pic_32_head() {
48 atf_set "descr" "compile and run 32-bit PIC std::call_once"
49 atf_set "require.progs" "c++"
50 }
51
52 atf_test_case call_once2_pic_profile
53 call_once2_pic_head() {
54 atf_set "descr" "compile and run PIC std::call_once with profiling flag"
55 atf_set "require.progs" "c++"
56 }
57
58 atf_test_case call_once2_pic_profile_32
59 call_once2_pic_profile_32_head() {
60 atf_set "descr" "compile and run 32-bit PIC std::call_once with profiling flag"
61 atf_set "require.progs" "c++"
62 }
63
64 atf_test_case call_once2_profile_32
65 call_once2_profile_32_head() {
66 atf_set "descr" "compile and run 32-bit std::call_once with profiling flag"
67 atf_set "require.progs" "c++"
68 }
69
70 atf_test_case call_once2_pie
71 call_once2_pie_head() {
72 atf_set "descr" "compile and run position independent (PIE) std::call_once"
73 atf_set "require.progs" "c++"
74 }
75
76 atf_test_case call_once2_32
77 call_once2_32_head() {
78 atf_set "descr" "compile and run std::call_once for/in netbsd32 emulation"
79 atf_set "require.progs" "c++ file diff cat"
80 }
81
82 atf_test_case call_once2_static
83 call_once2_static_head() {
84 atf_set "descr" "compile and run std::call_once with static flag"
85 atf_set "require.progs" "c++"
86 }
87
88 call_once2_body() {
89 cat > test.cpp << EOF
90 #include <mutex>
91 #include <thread>
92 #include <iostream>
93 std::once_flag flag, flag_throw;
94 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
95 void throw_once(void) { throw std::exception(); }
96 int main(void) {
97 static const int nr_threads(4);
98 std::thread threads[nr_threads];
99
100 for (int i = 0; i < nr_threads; ++i) {
101 threads[i] = std::thread(print_once);
102 }
103 for (int i = 0; i < nr_threads; ++i) {
104 threads[i].join();
105 }
106
107 try {
108 std::call_once(flag_throw, throw_once);
109 } catch (...) {
110 std::cout << "world!" << std::endl;
111 }
112 return 0;
113 }
114 EOF
115 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2 test.cpp -pthread
116 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
117 }
118
119 call_once2_profile_body() {
120 atf_expect_fail "profiling option doesn't work with shared libraries"
121 cat > test.cpp << EOF
122 #include <mutex>
123 #include <thread>
124 #include <iostream>
125 std::once_flag flag, flag_throw;
126 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
127 void throw_once(void) { throw std::exception(); }
128 int main(void) {
129 static const int nr_threads(4);
130 std::thread threads[nr_threads];
131
132 for (int i = 0; i < nr_threads; ++i) {
133 threads[i] = std::thread(print_once);
134 }
135 for (int i = 0; i < nr_threads; ++i) {
136 threads[i].join();
137 }
138
139 try {
140 std::call_once(flag_throw, throw_once);
141 } catch (...) {
142 std::cout << "world!" << std::endl;
143 }
144 return 0;
145 }
146 EOF
147 atf_check -s exit:0 -o ignore -e ignore c++ -pg -o call_once2 test.cpp -pthread
148 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
149 }
150
151 call_once2_profile_32_body() {
152 atf_expect_fail "profiling option doesn't work now"
153 # check whether this arch is 64bit
154 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
155 atf_skip "this is not a 64 bit architecture"
156 fi
157 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
158 atf_skip "c++ -m32 not supported on this architecture"
159 else
160 if fgrep -q _LP64 ./def32; then
161 atf_fail "c++ -m32 does not generate netbsd32 binaries"
162 fi
163 fi
164
165 cat > test.cpp << EOF
166 #include <mutex>
167 #include <thread>
168 #include <iostream>
169 std::once_flag flag, flag_throw;
170 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
171 void throw_once(void) { throw std::exception(); }
172 int main(void) {
173 static const int nr_threads(4);
174 std::thread threads[nr_threads];
175
176 for (int i = 0; i < nr_threads; ++i) {
177 threads[i] = std::thread(print_once);
178 }
179 for (int i = 0; i < nr_threads; ++i) {
180 threads[i].join();
181 }
182
183 try {
184 std::call_once(flag_throw, throw_once);
185 } catch (...) {
186 std::cout << "world!" << std::endl;
187 }
188 return 0;
189 }
190 EOF
191 atf_check -s exit:0 -o ignore -e ignore c++ -m32 -pg -o call_once2 test.cpp -pthread
192 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
193 atf_expect_fail "The combination of 32-bit and profiling should be fail"
194 }
195
196 call_once2_pic_body() {
197 cat > test.cpp << EOF
198 #include <stdlib.h>
199 int callpic(void);
200 int main(void) {callpic();exit(0);}
201 EOF
202 cat > pic.cpp << EOF
203 #include <mutex>
204 #include <thread>
205 #include <iostream>
206 std::once_flag flag, flag_throw;
207 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
208 void throw_once(void) { throw std::exception(); }
209 int callpic(void) {
210 static const int nr_threads(4);
211 std::thread threads[nr_threads];
212
213 for (int i = 0; i < nr_threads; ++i) {
214 threads[i] = std::thread(print_once);
215 }
216 for (int i = 0; i < nr_threads; ++i) {
217 threads[i].join();
218 }
219
220 try {
221 std::call_once(flag_throw, throw_once);
222 } catch (...) {
223 std::cout << "world!" << std::endl;
224 }
225 return 0;
226 }
227 EOF
228
229 atf_check -s exit:0 -o ignore -e ignore \
230 c++ -fPIC -shared -o libtest.so pic.cpp
231 atf_check -s exit:0 -o ignore -e ignore \
232 c++ -o call_once2 test.cpp -L. -ltest -pthread
233
234 export LD_LIBRARY_PATH=.
235 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
236 }
237
238 call_once2_pic_32_body() {
239 # check whether this arch is 64bit
240 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
241 atf_skip "this is not a 64 bit architecture"
242 fi
243 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
244 atf_skip "c++ -m32 not supported on this architecture"
245 else
246 if fgrep -q _LP64 ./def32; then
247 atf_fail "c++ -m32 does not generate netbsd32 binaries"
248 fi
249 fi
250
251 cat > test.cpp << EOF
252 #include <stdlib.h>
253 int callpic(void);
254 int main(void) {callpic();exit(0);}
255 EOF
256 cat > pic.cpp << EOF
257 #include <mutex>
258 #include <thread>
259 #include <iostream>
260 std::once_flag flag, flag_throw;
261 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
262 void throw_once(void) { throw std::exception(); }
263 int callpic(void) {
264 static const int nr_threads(4);
265 std::thread threads[nr_threads];
266
267 for (int i = 0; i < nr_threads; ++i) {
268 threads[i] = std::thread(print_once);
269 }
270 for (int i = 0; i < nr_threads; ++i) {
271 threads[i].join();
272 }
273
274 try {
275 std::call_once(flag_throw, throw_once);
276 } catch (...) {
277 std::cout << "world!" << std::endl;
278 }
279 return 0;
280 }
281 EOF
282
283 atf_check -s exit:0 -o ignore -e ignore \
284 c++ -m32 -fPIC -shared -o libtest.so pic.cpp
285 atf_check -s exit:0 -o ignore -e ignore \
286 c++ -m32 -o call_once2 test.cpp -L. -ltest -pthread
287
288 export LD_LIBRARY_PATH=.
289 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
290 }
291
292 call_once2_pic_profile_body() {
293 atf_expect_fail "profiling option doesn't work with pic"
294 cat > test.cpp << EOF
295 #include <stdlib.h>
296 int callpic(void);
297 int main(void) {callpic();exit(0);}
298 EOF
299 cat > pic.cpp << EOF
300 #include <mutex>
301 #include <thread>
302 #include <iostream>
303 std::once_flag flag, flag_throw;
304 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
305 void throw_once(void) { throw std::exception(); }
306 int callpic(void) {
307 static const int nr_threads(4);
308 std::thread threads[nr_threads];
309
310 for (int i = 0; i < nr_threads; ++i) {
311 threads[i] = std::thread(print_once);
312 }
313 for (int i = 0; i < nr_threads; ++i) {
314 threads[i].join();
315 }
316
317 try {
318 std::call_once(flag_throw, throw_once);
319 } catch (...) {
320 std::cout << "world!" << std::endl;
321 }
322 return 0;
323 }
324 EOF
325
326 atf_check -s exit:0 -o ignore -e ignore \
327 c++ -pg -fPIC -shared -o libtest.so pic.cpp
328 atf_check -s exit:0 -o ignore -e ignore \
329 c++ -pg -o call_once2 test.cpp -L. -ltest -pthread
330
331 export LD_LIBRARY_PATH=.
332 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
333 }
334
335 call_once2_pic_profile_32_body() {
336 atf_expect_fail "profiling option doesn't work with shared libraries"
337 # check whether this arch is 64bit
338 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
339 atf_skip "this is not a 64 bit architecture"
340 fi
341 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
342 atf_skip "c++ -m32 not supported on this architecture"
343 else
344 if fgrep -q _LP64 ./def32; then
345 atf_fail "c++ -m32 does not generate netbsd32 binaries"
346 fi
347 fi
348
349 cat > test.cpp << EOF
350 #include <stdlib.h>
351 int callpic(void);
352 int main(void) {callpic();exit(0);}
353 EOF
354 cat > pic.cpp << EOF
355 #include <mutex>
356 #include <thread>
357 #include <iostream>
358 std::once_flag flag, flag_throw;
359 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
360 void throw_once(void) { throw std::exception(); }
361 int callpic(void) {
362 static const int nr_threads(4);
363 std::thread threads[nr_threads];
364
365 for (int i = 0; i < nr_threads; ++i) {
366 threads[i] = std::thread(print_once);
367 }
368 for (int i = 0; i < nr_threads; ++i) {
369 threads[i].join();
370 }
371
372 try {
373 std::call_once(flag_throw, throw_once);
374 } catch (...) {
375 std::cout << "world!" << std::endl;
376 }
377 return 0;
378 }
379 EOF
380
381 atf_check -s exit:0 -o ignore -e ignore \
382 c++ -m32 -pg -fPIC -shared -o libtest.so pic.cpp
383 atf_check -s exit:0 -o ignore -e ignore \
384 c++ -m32 -pg -o call_once2 test.cpp -L. -ltest -pthread
385
386 export LD_LIBRARY_PATH=.
387 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
388 }
389
390 call_once2_pie_body() {
391 # check whether this arch supports -pie
392 if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
393 atf_skip "c++ -pie not supported on this architecture"
394 fi
395 cat > test.cpp << EOF
396 #include <mutex>
397 #include <thread>
398 #include <iostream>
399 std::once_flag flag, flag_throw;
400 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
401 void throw_once(void) { throw std::exception(); }
402 int main(void) {
403 static const int nr_threads(4);
404 std::thread threads[nr_threads];
405
406 for (int i = 0; i < nr_threads; ++i) {
407 threads[i] = std::thread(print_once);
408 }
409 for (int i = 0; i < nr_threads; ++i) {
410 threads[i].join();
411 }
412
413 try {
414 std::call_once(flag_throw, throw_once);
415 } catch (...) {
416 std::cout << "world!" << std::endl;
417 }
418 return 0;
419 }
420 EOF
421 atf_check -s exit:0 -o ignore -e ignore c++ -fpie -pie -o call_once2 test.cpp -pthread
422 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
423 }
424
425 call_once2_32_body() {
426 # check whether this arch is 64bit
427 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
428 atf_skip "this is not a 64 bit architecture"
429 fi
430 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
431 atf_skip "c++ -m32 not supported on this architecture"
432 else
433 if fgrep -q _LP64 ./def32; then
434 atf_fail "c++ -m32 does not generate netbsd32 binaries"
435 fi
436 fi
437
438 cat > test.cpp << EOF
439 #include <mutex>
440 #include <thread>
441 #include <iostream>
442 std::once_flag flag, flag_throw;
443 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
444 void throw_once(void) { throw std::exception(); }
445 int main(void) {
446 static const int nr_threads(4);
447 std::thread threads[nr_threads];
448
449 for (int i = 0; i < nr_threads; ++i) {
450 threads[i] = std::thread(print_once);
451 }
452 for (int i = 0; i < nr_threads; ++i) {
453 threads[i].join();
454 }
455
456 try {
457 std::call_once(flag_throw, throw_once);
458 } catch (...) {
459 std::cout << "world!" << std::endl;
460 }
461 return 0;
462 }
463 EOF
464 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2_32 -m32 test.cpp -pthread
465 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2_64 test.cpp -pthread
466 file -b ./call_once2_32 > ./ftype32
467 file -b ./call_once2_64 > ./ftype64
468 if diff ./ftype32 ./ftype64 >/dev/null; then
469 atf_fail "generated binaries do not differ"
470 fi
471 echo "32bit binaries on this platform are:"
472 cat ./ftype32
473 echo "While native (64bit) binaries are:"
474 cat ./ftype64
475 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2_32
476
477 # do another test with static 32bit binaries
478 cat > test.cpp << EOF
479 #include <mutex>
480 #include <thread>
481 #include <iostream>
482 std::once_flag flag, flag_throw;
483 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
484 void throw_once(void) { throw std::exception(); }
485 int main(void) {
486 static const int nr_threads(4);
487 std::thread threads[nr_threads];
488
489 for (int i = 0; i < nr_threads; ++i) {
490 threads[i] = std::thread(print_once);
491 }
492 for (int i = 0; i < nr_threads; ++i) {
493 threads[i].join();
494 }
495
496 try {
497 std::call_once(flag_throw, throw_once);
498 } catch (...) {
499 std::cout << "world!" << std::endl;
500 }
501 return 0;
502 }
503 EOF
504 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2 -m32 -pthread \
505 -static test.cpp
506 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
507 }
508
509 call_once2_static_body() {
510 cat > test.cpp << EOF
511 #include <mutex>
512 #include <thread>
513 #include <iostream>
514 std::once_flag flag, flag_throw;
515 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
516 void throw_once(void) { throw std::exception(); }
517 int main(void) {
518 static const int nr_threads(4);
519 std::thread threads[nr_threads];
520
521 for (int i = 0; i < nr_threads; ++i) {
522 threads[i] = std::thread(print_once);
523 }
524 for (int i = 0; i < nr_threads; ++i) {
525 threads[i].join();
526 }
527
528 try {
529 std::call_once(flag_throw, throw_once);
530 } catch (...) {
531 std::cout << "world!" << std::endl;
532 }
533 return 0;
534 }
535 EOF
536 atf_check -s exit:0 -o ignore -e ignore c++ -static -o call_once2 test.cpp -pthread
537 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
538 }
539
540 atf_init_test_cases()
541 {
542
543 atf_add_test_case call_once2
544 atf_add_test_case call_once2_profile
545 atf_add_test_case call_once2_pic
546 atf_add_test_case call_once2_pie
547 atf_add_test_case call_once2_32
548 atf_add_test_case call_once2_static
549 atf_add_test_case call_once2_pic_32
550 atf_add_test_case call_once2_pic_profile
551 atf_add_test_case call_once2_pic_profile_32
552 atf_add_test_case call_once2_profile_32
553 }
554