Home | History | Annotate | Line # | Download | only in c++
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