brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · b02c71e Raw
152 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <cassert>10#include <cxxabi.h>11 12#include "test_macros.h"13 14#ifndef TEST_HAS_NO_THREADS15#   include <thread>16#   include "make_test_thread.h"17#endif18 19// Ensure that we initialize each variable once and only once.20namespace 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        ((void)a);29    }30    void test() {31        static int a = increment(); ((void)a);32        assert(run_count == 1);33        static int b = increment(); ((void)b);34        assert(run_count == 2);35        helper();36        assert(run_count == 3);37        helper();38        assert(run_count == 3);39    }40}41 42// When initialization fails, ensure that we try to initialize it again next43// time.44namespace test2 {45#ifndef TEST_HAS_NO_EXCEPTIONS46    static int run_count = 0;47    int increment() {48        ++run_count;49        throw 0;50    }51    void helper() {52        try {53            static int a = increment();54            assert(false);55            ((void)a);56        } catch (...) {}57    }58    void test() {59        helper();60        assert(run_count == 1);61        helper();62        assert(run_count == 2);63    }64#else65   void test() {}66#endif67}68 69// Check that we can initialize a second value while initializing a first.70namespace test3 {71    int zero() {72        return 0;73    }74 75    int one() {76        static int b = zero(); ((void)b);77        return 0;78    }79 80    void test() {81        static int a = one(); ((void)a);82    }83}84 85#ifndef TEST_HAS_NO_THREADS86// A simple thread test of two threads racing to initialize a variable. This87// isn't guaranteed to catch any particular threading problems.88namespace test4 {89    static int run_count = 0;90    int increment() {91        ++run_count;92        return 0;93    }94 95    void helper() {96        static int a = increment(); ((void)a);97    }98 99    void test() {100        std::thread t1 = support::make_test_thread(helper);101        std::thread t2 = support::make_test_thread(helper);102        t1.join();103        t2.join();104        assert(run_count == 1);105    }106}107 108// Check that we don't re-initialize a static variable even when it's109// encountered from two different threads.110namespace test5 {111    static int run_count = 0;112    int zero() {113        ++run_count;114        return 0;115    }116 117    int one() {118        static int b = zero(); ((void)b);119        return 0;120    }121 122    void another_helper() {123        static int a = one(); ((void)a);124    }125 126    void helper() {127        static int a = one(); ((void)a);128        std::thread t = support::make_test_thread(another_helper);129        t.join();130    }131 132    void test() {133        std::thread t = support::make_test_thread(helper);134        t.join();135        assert(run_count == 1);136    }137}138#endif /* TEST_HAS_NO_THREADS */139 140int main(int, char**)141{142    test1::test();143    test2::test();144    test3::test();145#ifndef TEST_HAS_NO_THREADS146    test4::test();147    test5::test();148#endif149 150    return 0;151}152