t_call_once2.sh revision 1.2
11.2Schristos#	$NetBSD: t_call_once2.sh,v 1.2 2019/05/15 13:43:45 christos Exp $
21.1Skamil#
31.1Skamil# Copyright (c) 2018 The NetBSD Foundation, Inc.
41.1Skamil# All rights reserved.
51.1Skamil#
61.1Skamil# Redistribution and use in source and binary forms, with or without
71.1Skamil# modification, are permitted provided that the following conditions
81.1Skamil# are met:
91.1Skamil# 1. Redistributions of source code must retain the above copyright
101.1Skamil#    notice, this list of conditions and the following disclaimer.
111.1Skamil# 2. Redistributions in binary form must reproduce the above copyright
121.1Skamil#    notice, this list of conditions and the following disclaimer in the
131.1Skamil#    documentation and/or other materials provided with the distribution.
141.1Skamil#
151.1Skamil# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
161.1Skamil# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
171.1Skamil# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
181.1Skamil# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
191.1Skamil# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
201.1Skamil# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
211.1Skamil# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
221.1Skamil# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
231.1Skamil# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
241.1Skamil# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
251.1Skamil# POSSIBILITY OF SUCH DAMAGE.
261.1Skamil#
271.1Skamil
281.1Skamilatf_test_case call_once2
291.1Skamilcall_once2_head() {
301.1Skamil	atf_set "descr" "compile and run std::call_once"
311.1Skamil	atf_set "require.progs" "c++"
321.1Skamil}
331.1Skamil
341.1Skamilatf_test_case call_once2_profile
351.1Skamilcall_once2_profile_head() {
361.1Skamil	atf_set "descr" "compile and run std::call_once with profiling option"
371.1Skamil	atf_set "require.progs" "c++"
381.1Skamil}
391.1Skamil
401.1Skamilatf_test_case call_once2_pic
411.1Skamilcall_once2_pic_head() {
421.1Skamil	atf_set "descr" "compile and run PIC std::call_once"
431.1Skamil	atf_set "require.progs" "c++"
441.1Skamil}
451.1Skamil
461.1Skamilatf_test_case call_once2_pic_32
471.1Skamilcall_once2_pic_32_head() {
481.1Skamil	atf_set "descr" "compile and run 32-bit PIC std::call_once"
491.1Skamil	atf_set "require.progs" "c++"
501.1Skamil}
511.1Skamil
521.1Skamilatf_test_case call_once2_pic_profile
531.1Skamilcall_once2_pic_head() {
541.1Skamil	atf_set "descr" "compile and run PIC std::call_once with profiling flag"
551.1Skamil	atf_set "require.progs" "c++"
561.1Skamil}
571.1Skamil
581.1Skamilatf_test_case call_once2_pic_profile_32
591.1Skamilcall_once2_pic_profile_32_head() {
601.1Skamil	atf_set "descr" "compile and run 32-bit PIC std::call_once with profiling flag"
611.1Skamil	atf_set "require.progs" "c++"
621.1Skamil}
631.1Skamil
641.1Skamilatf_test_case call_once2_profile_32
651.1Skamilcall_once2_profile_32_head() {
661.1Skamil	atf_set "descr" "compile and run 32-bit std::call_once with profiling flag"
671.1Skamil	atf_set "require.progs" "c++"
681.1Skamil}
691.1Skamil
701.1Skamilatf_test_case call_once2_pie
711.1Skamilcall_once2_pie_head() {
721.1Skamil	atf_set "descr" "compile and run position independent (PIE) std::call_once"
731.1Skamil	atf_set "require.progs" "c++"
741.1Skamil}
751.1Skamil
761.1Skamilatf_test_case call_once2_32
771.1Skamilcall_once2_32_head() {
781.1Skamil	atf_set "descr" "compile and run std::call_once for/in netbsd32 emulation"
791.1Skamil	atf_set "require.progs" "c++ file diff cat"
801.1Skamil}
811.1Skamil
821.1Skamilatf_test_case call_once2_static
831.1Skamilcall_once2_static_head() {
841.1Skamil	atf_set "descr" "compile and run std::call_once with static flag"
851.1Skamil	atf_set "require.progs" "c++"
861.1Skamil}
871.1Skamil
881.1Skamilcall_once2_body() {
891.1Skamil	cat > test.cpp << EOF
901.1Skamil#include <mutex>
911.1Skamil#include <thread>
921.1Skamil#include <iostream>
931.1Skamilstd::once_flag flag, flag_throw;
941.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
951.1Skamilvoid throw_once(void) { throw std::exception(); }
961.1Skamilint main(void) {
971.1Skamil        static const int nr_threads(4);
981.1Skamil        std::thread threads[nr_threads];
991.1Skamil
1001.1Skamil        for (int i = 0; i < nr_threads; ++i) {
1011.1Skamil                threads[i] = std::thread(print_once);
1021.1Skamil        }
1031.1Skamil        for (int i = 0; i < nr_threads; ++i) {
1041.1Skamil                threads[i].join();
1051.1Skamil        }
1061.1Skamil
1071.1Skamil        try {
1081.1Skamil                std::call_once(flag_throw, throw_once);
1091.1Skamil        } catch (...) {
1101.1Skamil                std::cout << "world!" << std::endl;
1111.1Skamil        }
1121.1Skamil        return 0;
1131.1Skamil}
1141.1SkamilEOF
1151.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2 test.cpp -pthread
1161.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
1171.1Skamil}
1181.1Skamil
1191.1Skamilcall_once2_profile_body() {
1201.2Schristos	atf_expect_fail "profiling option doesn't work with shared libraries"
1211.1Skamil	cat > test.cpp << EOF
1221.1Skamil#include <mutex>
1231.1Skamil#include <thread>
1241.1Skamil#include <iostream>
1251.1Skamilstd::once_flag flag, flag_throw;
1261.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
1271.1Skamilvoid throw_once(void) { throw std::exception(); }
1281.1Skamilint main(void) {
1291.1Skamil        static const int nr_threads(4);
1301.1Skamil        std::thread threads[nr_threads];
1311.1Skamil
1321.1Skamil        for (int i = 0; i < nr_threads; ++i) {
1331.1Skamil                threads[i] = std::thread(print_once);
1341.1Skamil        }
1351.1Skamil        for (int i = 0; i < nr_threads; ++i) {
1361.1Skamil                threads[i].join();
1371.1Skamil        }
1381.1Skamil
1391.1Skamil        try {
1401.1Skamil                std::call_once(flag_throw, throw_once);
1411.1Skamil        } catch (...) {
1421.1Skamil                std::cout << "world!" << std::endl;
1431.1Skamil        }
1441.1Skamil        return 0;
1451.1Skamil}
1461.1SkamilEOF
1471.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -pg -o call_once2 test.cpp -pthread
1481.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
1491.1Skamil}
1501.1Skamil
1511.1Skamilcall_once2_profile_32_body() {
1521.1Skamil	atf_expect_fail "profiling option doesn't work now"
1531.1Skamil	# check whether this arch is 64bit
1541.1Skamil	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
1551.1Skamil		atf_skip "this is not a 64 bit architecture"
1561.1Skamil	fi
1571.1Skamil	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
1581.1Skamil		atf_skip "c++ -m32 not supported on this architecture"
1591.1Skamil	else
1601.1Skamil		if fgrep -q _LP64 ./def32; then
1611.1Skamil			atf_fail "c++ -m32 does not generate netbsd32 binaries"
1621.1Skamil		fi
1631.1Skamil	fi
1641.1Skamil
1651.1Skamil	cat > test.cpp << EOF
1661.1Skamil#include <mutex>
1671.1Skamil#include <thread>
1681.1Skamil#include <iostream>
1691.1Skamilstd::once_flag flag, flag_throw;
1701.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
1711.1Skamilvoid throw_once(void) { throw std::exception(); }
1721.1Skamilint main(void) {
1731.1Skamil        static const int nr_threads(4);
1741.1Skamil        std::thread threads[nr_threads];
1751.1Skamil
1761.1Skamil        for (int i = 0; i < nr_threads; ++i) {
1771.1Skamil                threads[i] = std::thread(print_once);
1781.1Skamil        }
1791.1Skamil        for (int i = 0; i < nr_threads; ++i) {
1801.1Skamil                threads[i].join();
1811.1Skamil        }
1821.1Skamil
1831.1Skamil        try {
1841.1Skamil                std::call_once(flag_throw, throw_once);
1851.1Skamil        } catch (...) {
1861.1Skamil                std::cout << "world!" << std::endl;
1871.1Skamil        }
1881.1Skamil        return 0;
1891.1Skamil}
1901.1SkamilEOF
1911.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -m32 -pg -o call_once2 test.cpp -pthread
1921.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
1931.1Skamil	atf_expect_fail "The combination of 32-bit and profiling should be fail"
1941.1Skamil}
1951.1Skamil
1961.1Skamilcall_once2_pic_body() {
1971.1Skamil	cat > test.cpp << EOF
1981.1Skamil#include <stdlib.h>
1991.1Skamilint callpic(void);
2001.1Skamilint main(void) {callpic();exit(0);}
2011.1SkamilEOF
2021.1Skamil	cat > pic.cpp << EOF
2031.1Skamil#include <mutex>
2041.1Skamil#include <thread>
2051.1Skamil#include <iostream>
2061.1Skamilstd::once_flag flag, flag_throw;
2071.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
2081.1Skamilvoid throw_once(void) { throw std::exception(); }
2091.1Skamilint callpic(void) {
2101.1Skamil        static const int nr_threads(4);
2111.1Skamil        std::thread threads[nr_threads];
2121.1Skamil
2131.1Skamil        for (int i = 0; i < nr_threads; ++i) {
2141.1Skamil                threads[i] = std::thread(print_once);
2151.1Skamil        }
2161.1Skamil        for (int i = 0; i < nr_threads; ++i) {
2171.1Skamil                threads[i].join();
2181.1Skamil        }
2191.1Skamil
2201.1Skamil        try {
2211.1Skamil                std::call_once(flag_throw, throw_once);
2221.1Skamil        } catch (...) {
2231.1Skamil                std::cout << "world!" << std::endl;
2241.1Skamil        }
2251.1Skamil        return 0;
2261.1Skamil}
2271.1SkamilEOF
2281.1Skamil
2291.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
2301.1Skamil	    c++ -fPIC -shared -o libtest.so pic.cpp
2311.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
2321.1Skamil	    c++ -o call_once2 test.cpp -L. -ltest -pthread
2331.1Skamil
2341.1Skamil	export LD_LIBRARY_PATH=.
2351.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
2361.1Skamil}
2371.1Skamil
2381.1Skamilcall_once2_pic_32_body() {
2391.1Skamil	# check whether this arch is 64bit
2401.1Skamil	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
2411.1Skamil		atf_skip "this is not a 64 bit architecture"
2421.1Skamil	fi
2431.1Skamil	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
2441.1Skamil		atf_skip "c++ -m32 not supported on this architecture"
2451.1Skamil	else
2461.1Skamil		if fgrep -q _LP64 ./def32; then
2471.1Skamil			atf_fail "c++ -m32 does not generate netbsd32 binaries"
2481.1Skamil		fi
2491.1Skamil	fi
2501.1Skamil
2511.1Skamil	cat > test.cpp << EOF
2521.1Skamil#include <stdlib.h>
2531.1Skamilint callpic(void);
2541.1Skamilint main(void) {callpic();exit(0);}
2551.1SkamilEOF
2561.1Skamil	cat > pic.cpp << EOF
2571.1Skamil#include <mutex>
2581.1Skamil#include <thread>
2591.1Skamil#include <iostream>
2601.1Skamilstd::once_flag flag, flag_throw;
2611.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
2621.1Skamilvoid throw_once(void) { throw std::exception(); }
2631.1Skamilint callpic(void) {
2641.1Skamil        static const int nr_threads(4);
2651.1Skamil        std::thread threads[nr_threads];
2661.1Skamil
2671.1Skamil        for (int i = 0; i < nr_threads; ++i) {
2681.1Skamil                threads[i] = std::thread(print_once);
2691.1Skamil        }
2701.1Skamil        for (int i = 0; i < nr_threads; ++i) {
2711.1Skamil                threads[i].join();
2721.1Skamil        }
2731.1Skamil
2741.1Skamil        try {
2751.1Skamil                std::call_once(flag_throw, throw_once);
2761.1Skamil        } catch (...) {
2771.1Skamil                std::cout << "world!" << std::endl;
2781.1Skamil        }
2791.1Skamil        return 0;
2801.1Skamil}
2811.1SkamilEOF
2821.1Skamil
2831.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
2841.1Skamil	    c++ -m32 -fPIC -shared -o libtest.so pic.cpp
2851.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
2861.1Skamil	    c++ -m32 -o call_once2 test.cpp -L. -ltest -pthread
2871.1Skamil
2881.1Skamil	export LD_LIBRARY_PATH=.
2891.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
2901.1Skamil}
2911.1Skamil
2921.1Skamilcall_once2_pic_profile_body() {
2931.2Schristos	atf_expect_fail "profiling option doesn't work with pic"
2941.1Skamil	cat > test.cpp << EOF
2951.1Skamil#include <stdlib.h>
2961.1Skamilint callpic(void);
2971.1Skamilint main(void) {callpic();exit(0);}
2981.1SkamilEOF
2991.1Skamil	cat > pic.cpp << EOF
3001.1Skamil#include <mutex>
3011.1Skamil#include <thread>
3021.1Skamil#include <iostream>
3031.1Skamilstd::once_flag flag, flag_throw;
3041.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
3051.1Skamilvoid throw_once(void) { throw std::exception(); }
3061.1Skamilint callpic(void) {
3071.1Skamil        static const int nr_threads(4);
3081.1Skamil        std::thread threads[nr_threads];
3091.1Skamil
3101.1Skamil        for (int i = 0; i < nr_threads; ++i) {
3111.1Skamil                threads[i] = std::thread(print_once);
3121.1Skamil        }
3131.1Skamil        for (int i = 0; i < nr_threads; ++i) {
3141.1Skamil                threads[i].join();
3151.1Skamil        }
3161.1Skamil
3171.1Skamil        try {
3181.1Skamil                std::call_once(flag_throw, throw_once);
3191.1Skamil        } catch (...) {
3201.1Skamil                std::cout << "world!" << std::endl;
3211.1Skamil        }
3221.1Skamil        return 0;
3231.1Skamil}
3241.1SkamilEOF
3251.1Skamil
3261.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
3271.1Skamil	    c++ -pg -fPIC -shared -o libtest.so pic.cpp
3281.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
3291.1Skamil	    c++ -pg -o call_once2 test.cpp -L. -ltest -pthread
3301.1Skamil
3311.1Skamil	export LD_LIBRARY_PATH=.
3321.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
3331.1Skamil}
3341.1Skamil
3351.1Skamilcall_once2_pic_profile_32_body() {
3361.2Schristos	atf_expect_fail "profiling option doesn't work with shared libraries"
3371.1Skamil	# check whether this arch is 64bit
3381.1Skamil	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
3391.1Skamil		atf_skip "this is not a 64 bit architecture"
3401.1Skamil	fi
3411.1Skamil	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
3421.1Skamil		atf_skip "c++ -m32 not supported on this architecture"
3431.1Skamil	else
3441.1Skamil		if fgrep -q _LP64 ./def32; then
3451.1Skamil			atf_fail "c++ -m32 does not generate netbsd32 binaries"
3461.1Skamil		fi
3471.1Skamil	fi
3481.1Skamil
3491.1Skamil	cat > test.cpp << EOF
3501.1Skamil#include <stdlib.h>
3511.1Skamilint callpic(void);
3521.1Skamilint main(void) {callpic();exit(0);}
3531.1SkamilEOF
3541.1Skamil	cat > pic.cpp << EOF
3551.1Skamil#include <mutex>
3561.1Skamil#include <thread>
3571.1Skamil#include <iostream>
3581.1Skamilstd::once_flag flag, flag_throw;
3591.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
3601.1Skamilvoid throw_once(void) { throw std::exception(); }
3611.1Skamilint callpic(void) {
3621.1Skamil        static const int nr_threads(4);
3631.1Skamil        std::thread threads[nr_threads];
3641.1Skamil
3651.1Skamil        for (int i = 0; i < nr_threads; ++i) {
3661.1Skamil                threads[i] = std::thread(print_once);
3671.1Skamil        }
3681.1Skamil        for (int i = 0; i < nr_threads; ++i) {
3691.1Skamil                threads[i].join();
3701.1Skamil        }
3711.1Skamil
3721.1Skamil        try {
3731.1Skamil                std::call_once(flag_throw, throw_once);
3741.1Skamil        } catch (...) {
3751.1Skamil                std::cout << "world!" << std::endl;
3761.1Skamil        }
3771.1Skamil        return 0;
3781.1Skamil}
3791.1SkamilEOF
3801.1Skamil
3811.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
3821.1Skamil	    c++ -m32 -pg -fPIC -shared -o libtest.so pic.cpp
3831.1Skamil	atf_check -s exit:0 -o ignore -e ignore \
3841.1Skamil	    c++ -m32 -pg -o call_once2 test.cpp -L. -ltest -pthread
3851.1Skamil
3861.1Skamil	export LD_LIBRARY_PATH=.
3871.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
3881.1Skamil}
3891.1Skamil
3901.1Skamilcall_once2_pie_body() {
3911.1Skamil	# check whether this arch supports -pie
3921.1Skamil	if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
3931.1Skamil		atf_skip "c++ -pie not supported on this architecture"
3941.1Skamil	fi
3951.1Skamil	cat > test.cpp << EOF
3961.1Skamil#include <mutex>
3971.1Skamil#include <thread>
3981.1Skamil#include <iostream>
3991.1Skamilstd::once_flag flag, flag_throw;
4001.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
4011.1Skamilvoid throw_once(void) { throw std::exception(); }
4021.1Skamilint main(void) {
4031.1Skamil        static const int nr_threads(4);
4041.1Skamil        std::thread threads[nr_threads];
4051.1Skamil
4061.1Skamil        for (int i = 0; i < nr_threads; ++i) {
4071.1Skamil                threads[i] = std::thread(print_once);
4081.1Skamil        }
4091.1Skamil        for (int i = 0; i < nr_threads; ++i) {
4101.1Skamil                threads[i].join();
4111.1Skamil        }
4121.1Skamil
4131.1Skamil        try {
4141.1Skamil                std::call_once(flag_throw, throw_once);
4151.1Skamil        } catch (...) {
4161.1Skamil                std::cout << "world!" << std::endl;
4171.1Skamil        }
4181.1Skamil        return 0;
4191.1Skamil}
4201.1SkamilEOF
4211.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -fpie -pie -o call_once2 test.cpp -pthread
4221.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
4231.1Skamil}
4241.1Skamil
4251.1Skamilcall_once2_32_body() {
4261.1Skamil	# check whether this arch is 64bit
4271.1Skamil	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
4281.1Skamil		atf_skip "this is not a 64 bit architecture"
4291.1Skamil	fi
4301.1Skamil	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
4311.1Skamil		atf_skip "c++ -m32 not supported on this architecture"
4321.1Skamil	else
4331.1Skamil		if fgrep -q _LP64 ./def32; then
4341.1Skamil			atf_fail "c++ -m32 does not generate netbsd32 binaries"
4351.1Skamil		fi
4361.1Skamil	fi
4371.1Skamil
4381.1Skamil	cat > test.cpp << EOF
4391.1Skamil#include <mutex>
4401.1Skamil#include <thread>
4411.1Skamil#include <iostream>
4421.1Skamilstd::once_flag flag, flag_throw;
4431.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
4441.1Skamilvoid throw_once(void) { throw std::exception(); }
4451.1Skamilint main(void) {
4461.1Skamil        static const int nr_threads(4);
4471.1Skamil        std::thread threads[nr_threads];
4481.1Skamil
4491.1Skamil        for (int i = 0; i < nr_threads; ++i) {
4501.1Skamil                threads[i] = std::thread(print_once);
4511.1Skamil        }
4521.1Skamil        for (int i = 0; i < nr_threads; ++i) {
4531.1Skamil                threads[i].join();
4541.1Skamil        }
4551.1Skamil
4561.1Skamil        try {
4571.1Skamil                std::call_once(flag_throw, throw_once);
4581.1Skamil        } catch (...) {
4591.1Skamil                std::cout << "world!" << std::endl;
4601.1Skamil        }
4611.1Skamil        return 0;
4621.1Skamil}
4631.1SkamilEOF
4641.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2_32 -m32 test.cpp -pthread
4651.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2_64 test.cpp -pthread
4661.1Skamil	file -b ./call_once2_32 > ./ftype32
4671.1Skamil	file -b ./call_once2_64 > ./ftype64
4681.1Skamil	if diff ./ftype32 ./ftype64 >/dev/null; then
4691.1Skamil		atf_fail "generated binaries do not differ"
4701.1Skamil	fi
4711.1Skamil	echo "32bit binaries on this platform are:"
4721.1Skamil	cat ./ftype32
4731.1Skamil	echo "While native (64bit) binaries are:"
4741.1Skamil	cat ./ftype64
4751.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2_32
4761.1Skamil
4771.1Skamil	# do another test with static 32bit binaries
4781.1Skamil	cat > test.cpp << EOF
4791.1Skamil#include <mutex>
4801.1Skamil#include <thread>
4811.1Skamil#include <iostream>
4821.1Skamilstd::once_flag flag, flag_throw;
4831.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
4841.1Skamilvoid throw_once(void) { throw std::exception(); }
4851.1Skamilint main(void) {
4861.1Skamil        static const int nr_threads(4);
4871.1Skamil        std::thread threads[nr_threads];
4881.1Skamil
4891.1Skamil        for (int i = 0; i < nr_threads; ++i) {
4901.1Skamil                threads[i] = std::thread(print_once);
4911.1Skamil        }
4921.1Skamil        for (int i = 0; i < nr_threads; ++i) {
4931.1Skamil                threads[i].join();
4941.1Skamil        }
4951.1Skamil
4961.1Skamil        try {
4971.1Skamil                std::call_once(flag_throw, throw_once);
4981.1Skamil        } catch (...) {
4991.1Skamil                std::cout << "world!" << std::endl;
5001.1Skamil        }
5011.1Skamil        return 0;
5021.1Skamil}
5031.1SkamilEOF
5041.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2 -m32 -pthread \
5051.1Skamil	    -static test.cpp
5061.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
5071.1Skamil}
5081.1Skamil
5091.1Skamilcall_once2_static_body() {
5101.1Skamil	cat > test.cpp << EOF
5111.1Skamil#include <mutex>
5121.1Skamil#include <thread>
5131.1Skamil#include <iostream>
5141.1Skamilstd::once_flag flag, flag_throw;
5151.1Skamilvoid print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); }
5161.1Skamilvoid throw_once(void) { throw std::exception(); }
5171.1Skamilint main(void) {
5181.1Skamil        static const int nr_threads(4);
5191.1Skamil        std::thread threads[nr_threads];
5201.1Skamil
5211.1Skamil        for (int i = 0; i < nr_threads; ++i) {
5221.1Skamil                threads[i] = std::thread(print_once);
5231.1Skamil        }
5241.1Skamil        for (int i = 0; i < nr_threads; ++i) {
5251.1Skamil                threads[i].join();
5261.1Skamil        }
5271.1Skamil
5281.1Skamil        try {
5291.1Skamil                std::call_once(flag_throw, throw_once);
5301.1Skamil        } catch (...) {
5311.1Skamil                std::cout << "world!" << std::endl;
5321.1Skamil        }
5331.1Skamil        return 0;
5341.1Skamil}
5351.1SkamilEOF
5361.1Skamil	atf_check -s exit:0 -o ignore -e ignore c++ -static -o call_once2 test.cpp -pthread
5371.1Skamil	atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2
5381.1Skamil}
5391.1Skamil
5401.1Skamilatf_init_test_cases()
5411.1Skamil{
5421.1Skamil
5431.1Skamil	atf_add_test_case call_once2
5441.1Skamil	atf_add_test_case call_once2_profile
5451.1Skamil	atf_add_test_case call_once2_pic
5461.1Skamil	atf_add_test_case call_once2_pie
5471.1Skamil	atf_add_test_case call_once2_32
5481.1Skamil	atf_add_test_case call_once2_static
5491.1Skamil	atf_add_test_case call_once2_pic_32
5501.1Skamil	atf_add_test_case call_once2_pic_profile
5511.1Skamil	atf_add_test_case call_once2_pic_profile_32
5521.1Skamil	atf_add_test_case call_once2_profile_32
5531.1Skamil}
554