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 28atf_test_case call_once2 29call_once2_head() { 30 atf_set "descr" "compile and run std::call_once" 31 atf_set "require.progs" "c++" 32} 33 34atf_test_case call_once2_profile 35call_once2_profile_head() { 36 atf_set "descr" "compile and run std::call_once with profiling option" 37 atf_set "require.progs" "c++" 38} 39 40atf_test_case call_once2_pic 41call_once2_pic_head() { 42 atf_set "descr" "compile and run PIC std::call_once" 43 atf_set "require.progs" "c++" 44} 45 46atf_test_case call_once2_pic_32 47call_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 52atf_test_case call_once2_pic_profile 53call_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 58atf_test_case call_once2_pic_profile_32 59call_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 64atf_test_case call_once2_profile_32 65call_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 70atf_test_case call_once2_pie 71call_once2_pie_head() { 72 atf_set "descr" "compile and run position independent (PIE) std::call_once" 73 atf_set "require.progs" "c++" 74} 75 76atf_test_case call_once2_32 77call_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 82atf_test_case call_once2_static 83call_once2_static_head() { 84 atf_set "descr" "compile and run std::call_once with static flag" 85 atf_set "require.progs" "c++" 86} 87 88call_once2_body() { 89 cat > test.cpp << EOF 90#include <mutex> 91#include <thread> 92#include <iostream> 93std::once_flag flag, flag_throw; 94void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 95void throw_once(void) { throw std::exception(); } 96int 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} 114EOF 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 119call_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> 125std::once_flag flag, flag_throw; 126void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 127void throw_once(void) { throw std::exception(); } 128int 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} 146EOF 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 151call_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> 169std::once_flag flag, flag_throw; 170void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 171void throw_once(void) { throw std::exception(); } 172int 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} 190EOF 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 196call_once2_pic_body() { 197 cat > test.cpp << EOF 198#include <stdlib.h> 199int callpic(void); 200int main(void) {callpic();exit(0);} 201EOF 202 cat > pic.cpp << EOF 203#include <mutex> 204#include <thread> 205#include <iostream> 206std::once_flag flag, flag_throw; 207void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 208void throw_once(void) { throw std::exception(); } 209int 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} 227EOF 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 238call_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> 253int callpic(void); 254int main(void) {callpic();exit(0);} 255EOF 256 cat > pic.cpp << EOF 257#include <mutex> 258#include <thread> 259#include <iostream> 260std::once_flag flag, flag_throw; 261void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 262void throw_once(void) { throw std::exception(); } 263int 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} 281EOF 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 292call_once2_pic_profile_body() { 293 atf_expect_fail "profiling option doesn't work with pic" 294 cat > test.cpp << EOF 295#include <stdlib.h> 296int callpic(void); 297int main(void) {callpic();exit(0);} 298EOF 299 cat > pic.cpp << EOF 300#include <mutex> 301#include <thread> 302#include <iostream> 303std::once_flag flag, flag_throw; 304void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 305void throw_once(void) { throw std::exception(); } 306int 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} 324EOF 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 335call_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> 351int callpic(void); 352int main(void) {callpic();exit(0);} 353EOF 354 cat > pic.cpp << EOF 355#include <mutex> 356#include <thread> 357#include <iostream> 358std::once_flag flag, flag_throw; 359void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 360void throw_once(void) { throw std::exception(); } 361int 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} 379EOF 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 390call_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> 399std::once_flag flag, flag_throw; 400void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 401void throw_once(void) { throw std::exception(); } 402int 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} 420EOF 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 425call_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> 442std::once_flag flag, flag_throw; 443void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 444void throw_once(void) { throw std::exception(); } 445int 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} 463EOF 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> 482std::once_flag flag, flag_throw; 483void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 484void throw_once(void) { throw std::exception(); } 485int 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} 503EOF 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 509call_once2_static_body() { 510 cat > test.cpp << EOF 511#include <mutex> 512#include <thread> 513#include <iostream> 514std::once_flag flag, flag_throw; 515void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 516void throw_once(void) { throw std::exception(); } 517int 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} 535EOF 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 540atf_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