1 //===----------------------------- test_guard.cpp -------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "cxxabi.h" 11 12 #include <cassert> 13 #include <thread> 14 15 // Ensure that we initialize each variable once and only once. 16 namespace test1 { 17 static int run_count = 0; increment()18 int increment() { 19 ++run_count; 20 return 0; 21 } helper()22 void helper() { 23 static int a = increment(); 24 } test()25 void test() { 26 static int a = increment(); 27 assert(run_count == 1); 28 static int b = increment(); 29 assert(run_count == 2); 30 helper(); 31 assert(run_count == 3); 32 helper(); 33 assert(run_count == 3); 34 } 35 } 36 37 // When initialization fails, ensure that we try to initialize it again next 38 // time. 39 namespace test2 { 40 static int run_count = 0; increment()41 int increment() { 42 ++run_count; 43 throw 0; 44 } helper()45 void helper() { 46 try { 47 static int a = increment(); 48 assert(0); 49 } catch (...) {} 50 } test()51 void test() { 52 helper(); 53 assert(run_count == 1); 54 helper(); 55 assert(run_count == 2); 56 } 57 } 58 59 // Check that we can initialize a second value while initializing a first. 60 namespace test3 { zero()61 int zero() { 62 return 0; 63 } 64 one()65 int one() { 66 static int b = zero(); 67 return 0; 68 } 69 test()70 void test() { 71 static int a = one(); 72 } 73 } 74 75 // A simple thread test of two threads racing to initialize a variable. This 76 // isn't guaranteed to catch any particular threading problems. 77 namespace test4 { 78 static int run_count = 0; increment()79 int increment() { 80 ++run_count; 81 return 0; 82 } 83 helper()84 void helper() { 85 static int a = increment(); 86 } 87 test()88 void test() { 89 std::thread t1(helper), t2(helper); 90 t1.join(); 91 t2.join(); 92 assert(run_count == 1); 93 } 94 } 95 96 // Check that we don't re-initialize a static variable even when it's 97 // encountered from two different threads. 98 namespace test5 { 99 static int run_count = 0; zero()100 int zero() { 101 ++run_count; 102 return 0; 103 } 104 one()105 int one() { 106 static int b = zero(); 107 return 0; 108 } 109 another_helper()110 void another_helper() { 111 static int a = one(); 112 } 113 helper()114 void helper() { 115 static int a = one(); 116 std::thread t(another_helper); 117 t.join(); 118 } 119 test()120 void test() { 121 std::thread t(helper); 122 t.join(); 123 assert(run_count == 1); 124 } 125 } 126 main()127int main() 128 { 129 test1::test(); 130 test2::test(); 131 test3::test(); 132 test4::test(); 133 test5::test(); 134 } 135