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