test_guard.cpp revision 5dfef8de38c88d0bbccdb0b0f86a696f6d53dba8
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. 16namespace test1 { 17 static int run_count = 0; 18 int increment() { 19 ++run_count; 20 return 0; 21 } 22 void helper() { 23 static int a = increment(); 24 } 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. 39namespace test2 { 40 static int run_count = 0; 41 int increment() { 42 ++run_count; 43 throw 0; 44 } 45 void helper() { 46 try { 47 static int a = increment(); 48 assert(0); 49 } catch (...) {} 50 } 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. 60namespace test3 { 61 int zero() { 62 return 0; 63 } 64 65 int one() { 66 static int b = zero(); 67 return 0; 68 } 69 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. 77namespace test4 { 78 static int run_count = 0; 79 int increment() { 80 ++run_count; 81 return 0; 82 } 83 84 void helper() { 85 static int a = increment(); 86 } 87 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. 98namespace test5 { 99 static int run_count = 0; 100 int zero() { 101 ++run_count; 102 return 0; 103 } 104 105 int one() { 106 static int b = zero(); 107 return 0; 108 } 109 110 void another_helper() { 111 static int a = one(); 112 } 113 114 void helper() { 115 static int a = one(); 116 std::thread t(another_helper); 117 t.join(); 118 } 119 120 void test() { 121 std::thread t(helper); 122 t.join(); 123 assert(run_count == 1); 124 } 125} 126 127int main() 128{ 129 test1::test(); 130 test2::test(); 131 test3::test(); 132 test4::test(); 133 test5::test(); 134} 135