192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//===----------------------------- test_guard.cpp -------------------------===// 292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// 392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// The LLVM Compiler Infrastructure 492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// 592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant// 892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant//===----------------------------------------------------------------------===// 992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant 10e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert#include "../src/config.h" 1192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant#include "cxxabi.h" 1292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant 1392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant#include <cassert> 14e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert 15e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert#if !LIBCXXABI_HAS_NO_THREADS 165dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky#include <thread> 17e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert#endif 1892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant 195dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// Ensure that we initialize each variable once and only once. 2092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantnamespace test1 { 2192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant static int run_count = 0; 2292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant int increment() { 2392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant ++run_count; 2492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant return 0; 2592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant } 2692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant void helper() { 2792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant static int a = increment(); 2892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant } 2992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant void test() { 3092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant static int a = increment(); 3192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant assert(run_count == 1); 3292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant static int b = increment(); 3392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant assert(run_count == 2); 3492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant helper(); 3592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant assert(run_count == 3); 3692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant helper(); 3792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant assert(run_count == 3); 3892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant } 3992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant} 4092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant 415dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// When initialization fails, ensure that we try to initialize it again next 425dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// time. 4392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantnamespace test2 { 4492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant static int run_count = 0; 4592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant int increment() { 4692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant ++run_count; 4792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant throw 0; 4892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant } 4992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant void helper() { 5092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant try { 5192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant static int a = increment(); 5292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant assert(0); 5392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant } catch (...) {} 5492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant } 5592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant void test() { 5692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant helper(); 5792827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant assert(run_count == 1); 5892827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant helper(); 5992827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant assert(run_count == 2); 6092827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant } 6192827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant} 6292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant 635dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// Check that we can initialize a second value while initializing a first. 645dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewyckynamespace test3 { 655dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky int zero() { 665dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky return 0; 675dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 685dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 695dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky int one() { 705dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int b = zero(); 715dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky return 0; 725dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 735dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 745dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky void test() { 755dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int a = one(); 765dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 775dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky} 785dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 79e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert#if !LIBCXXABI_HAS_NO_THREADS 805dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// A simple thread test of two threads racing to initialize a variable. This 815dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// isn't guaranteed to catch any particular threading problems. 825dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewyckynamespace test4 { 835dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int run_count = 0; 845dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky int increment() { 855dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky ++run_count; 8625f180797ba296e6cd3aa45e1fef9321b828301aHoward Hinnant return 0; 875dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 885dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 895dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky void helper() { 905dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int a = increment(); 915dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 925dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 935dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky void test() { 945dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky std::thread t1(helper), t2(helper); 955dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky t1.join(); 965dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky t2.join(); 9725f180797ba296e6cd3aa45e1fef9321b828301aHoward Hinnant assert(run_count == 1); 985dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 995dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky} 1005dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 1015dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// Check that we don't re-initialize a static variable even when it's 1025dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky// encountered from two different threads. 1035dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewyckynamespace test5 { 1045dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int run_count = 0; 1055dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky int zero() { 1065dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky ++run_count; 1075dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky return 0; 1085dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 1095dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 1105dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky int one() { 1115dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int b = zero(); 11225f180797ba296e6cd3aa45e1fef9321b828301aHoward Hinnant return 0; 1135dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 1145dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 1155dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky void another_helper() { 1165dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int a = one(); 1175dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 1185dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 1195dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky void helper() { 1205dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky static int a = one(); 12125f180797ba296e6cd3aa45e1fef9321b828301aHoward Hinnant std::thread t(another_helper); 12225f180797ba296e6cd3aa45e1fef9321b828301aHoward Hinnant t.join(); 1235dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 1245dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 1255dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky void test() { 1265dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky std::thread t(helper); 1275dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky t.join(); 12825f180797ba296e6cd3aa45e1fef9321b828301aHoward Hinnant assert(run_count == 1); 1295dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky } 1305dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky} 131e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert#endif /* LIBCXXABI_HAS_NO_THREADS */ 1325dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky 13392827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnantint main() 13492827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant{ 13592827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant test1::test(); 13692827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant test2::test(); 1375dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky test3::test(); 138e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert#if !LIBCXXABI_HAS_NO_THREADS 1395dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky test4::test(); 1405dfef8de38c88d0bbccdb0b0f86a696f6d53dba8Nick Lewycky test5::test(); 141e571c0cb34dbc3799349cf2166fb422ff9d2c08dDan Albert#endif 14292827189cbb1e63dfebf0a46aac4372c3089ff11Howard Hinnant} 143