• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()127 int main()
128 {
129     test1::test();
130     test2::test();
131     test3::test();
132     test4::test();
133     test5::test();
134 }
135