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 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 atf_set "timeout" "600" 33} 34 35atf_test_case call_once2_profile 36call_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 42atf_test_case call_once2_pic 43call_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 49atf_test_case call_once2_pic_32 50call_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 56atf_test_case call_once2_pic_profile 57call_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 63atf_test_case call_once2_pic_profile_32 64call_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 70atf_test_case call_once2_profile_32 71call_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 77atf_test_case call_once2_pie 78call_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 84atf_test_case call_once2_32 85call_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 91atf_test_case call_once2_static 92call_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 98call_once2_body() { 99 cat > test.cpp << EOF 100#include <mutex> 101#include <thread> 102#include <iostream> 103std::once_flag flag, flag_throw; 104void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 105void throw_once(void) { throw std::exception(); } 106int 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} 124EOF 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 129call_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> 135std::once_flag flag, flag_throw; 136void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 137void throw_once(void) { throw std::exception(); } 138int 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} 156EOF 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 161call_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> 179std::once_flag flag, flag_throw; 180void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 181void throw_once(void) { throw std::exception(); } 182int 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} 200EOF 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 206call_once2_pic_body() { 207 cat > test.cpp << EOF 208#include <stdlib.h> 209int callpic(void); 210int main(void) {callpic();exit(0);} 211EOF 212 cat > pic.cpp << EOF 213#include <mutex> 214#include <thread> 215#include <iostream> 216std::once_flag flag, flag_throw; 217void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 218void throw_once(void) { throw std::exception(); } 219int 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} 237EOF 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 248call_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> 263int callpic(void); 264int main(void) {callpic();exit(0);} 265EOF 266 cat > pic.cpp << EOF 267#include <mutex> 268#include <thread> 269#include <iostream> 270std::once_flag flag, flag_throw; 271void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 272void throw_once(void) { throw std::exception(); } 273int 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} 291EOF 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 302call_once2_pic_profile_body() { 303 atf_expect_fail "profiling option doesn't work with pic" 304 cat > test.cpp << EOF 305#include <stdlib.h> 306int callpic(void); 307int main(void) {callpic();exit(0);} 308EOF 309 cat > pic.cpp << EOF 310#include <mutex> 311#include <thread> 312#include <iostream> 313std::once_flag flag, flag_throw; 314void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 315void throw_once(void) { throw std::exception(); } 316int 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} 334EOF 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 345call_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> 361int callpic(void); 362int main(void) {callpic();exit(0);} 363EOF 364 cat > pic.cpp << EOF 365#include <mutex> 366#include <thread> 367#include <iostream> 368std::once_flag flag, flag_throw; 369void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 370void throw_once(void) { throw std::exception(); } 371int 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} 389EOF 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 400call_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> 409std::once_flag flag, flag_throw; 410void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 411void throw_once(void) { throw std::exception(); } 412int 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} 430EOF 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 435call_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> 452std::once_flag flag, flag_throw; 453void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 454void throw_once(void) { throw std::exception(); } 455int 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} 473EOF 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> 492std::once_flag flag, flag_throw; 493void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 494void throw_once(void) { throw std::exception(); } 495int 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} 513EOF 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 519call_once2_static_body() { 520 cat > test.cpp << EOF 521#include <mutex> 522#include <thread> 523#include <iostream> 524std::once_flag flag, flag_throw; 525void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 526void throw_once(void) { throw std::exception(); } 527int 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} 545EOF 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 550atf_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