blob: 96af56a7be18adf3b23f8588947ef4d6e466ad83 [file] [log] [blame]
Howard Hinnant4a889712011-05-24 22:01:161//===----------------------------- 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>
Nick Lewycky6fde1502011-06-04 18:01:2413#include <thread>
Howard Hinnant4a889712011-05-24 22:01:1614
Nick Lewycky6fde1502011-06-04 18:01:2415// Ensure that we initialize each variable once and only once.
Howard Hinnant4a889712011-05-24 22:01:1616namespace 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
Nick Lewycky6fde1502011-06-04 18:01:2437// When initialization fails, ensure that we try to initialize it again next
38// time.
Howard Hinnant4a889712011-05-24 22:01:1639namespace 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
Nick Lewycky6fde1502011-06-04 18:01:2459// 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;
Howard Hinnant575498b2011-06-07 19:56:4981 return 0;
Nick Lewycky6fde1502011-06-04 18:01:2482 }
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();
Howard Hinnant575498b2011-06-07 19:56:4992 assert(run_count == 1);
Nick Lewycky6fde1502011-06-04 18:01:2493 }
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();
Howard Hinnant575498b2011-06-07 19:56:49107 return 0;
Nick Lewycky6fde1502011-06-04 18:01:24108 }
109
110 void another_helper() {
111 static int a = one();
112 }
113
114 void helper() {
115 static int a = one();
Howard Hinnant575498b2011-06-07 19:56:49116 std::thread t(another_helper);
117 t.join();
Nick Lewycky6fde1502011-06-04 18:01:24118 }
119
120 void test() {
121 std::thread t(helper);
122 t.join();
Howard Hinnant575498b2011-06-07 19:56:49123 assert(run_count == 1);
Nick Lewycky6fde1502011-06-04 18:01:24124 }
125}
126
Howard Hinnant4a889712011-05-24 22:01:16127int main()
128{
129 test1::test();
130 test2::test();
Nick Lewycky6fde1502011-06-04 18:01:24131 test3::test();
132 test4::test();
133 test5::test();
Howard Hinnant4a889712011-05-24 22:01:16134}