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