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