1 //===- llvm/unittest/Support/ManagedStatic.cpp - ManagedStatic tests ------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Support/ManagedStatic.h" 10 #include "llvm/Config/config.h" 11 #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS 12 #include "llvm/Support/Allocator.h" 13 #include "gtest/gtest.h" 14 #ifdef HAVE_PTHREAD_H 15 #include <pthread.h> 16 #endif 17 18 #include "gtest/gtest.h" 19 20 using namespace llvm; 21 22 namespace { 23 24 #if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H) && \ 25 !__has_feature(memory_sanitizer) 26 namespace test1 { 27 llvm::ManagedStatic<int> ms; 28 void *helper(void*) { 29 *ms; 30 return nullptr; 31 } 32 33 // Valgrind's leak checker complains glibc's stack allocation. 34 // To appease valgrind, we provide our own stack for each thread. 35 void *allocate_stack(pthread_attr_t &a, size_t n = 65536) { 36 void *stack = safe_malloc(n); 37 pthread_attr_init(&a); 38 #if defined(__linux__) 39 pthread_attr_setstack(&a, stack, n); 40 #endif 41 return stack; 42 } 43 } 44 45 TEST(Initialize, MultipleThreads) { 46 // Run this test under tsan: http://code.google.com/p/data-race-test/ 47 48 pthread_attr_t a1, a2; 49 void *p1 = test1::allocate_stack(a1); 50 void *p2 = test1::allocate_stack(a2); 51 52 pthread_t t1, t2; 53 pthread_create(&t1, &a1, test1::helper, nullptr); 54 pthread_create(&t2, &a2, test1::helper, nullptr); 55 pthread_join(t1, nullptr); 56 pthread_join(t2, nullptr); 57 free(p1); 58 free(p2); 59 } 60 #endif 61 62 namespace NestedStatics { 63 static ManagedStatic<int> Ms1; 64 struct Nest { 65 Nest() { 66 ++(*Ms1); 67 } 68 69 ~Nest() { 70 assert(Ms1.isConstructed()); 71 ++(*Ms1); 72 } 73 }; 74 static ManagedStatic<Nest> Ms2; 75 76 TEST(ManagedStaticTest, NestedStatics) { 77 EXPECT_FALSE(Ms1.isConstructed()); 78 EXPECT_FALSE(Ms2.isConstructed()); 79 80 *Ms2; 81 EXPECT_TRUE(Ms1.isConstructed()); 82 EXPECT_TRUE(Ms2.isConstructed()); 83 } 84 } // namespace NestedStatics 85 86 namespace CustomCreatorDeletor { 87 struct CustomCreate { 88 static void *call() { 89 void *Mem = safe_malloc(sizeof(int)); 90 *((int *)Mem) = 42; 91 return Mem; 92 } 93 }; 94 struct CustomDelete { 95 static void call(void *P) { std::free(P); } 96 }; 97 static ManagedStatic<int, CustomCreate, CustomDelete> Custom; 98 TEST(ManagedStaticTest, CustomCreatorDeletor) { 99 EXPECT_EQ(42, *Custom); 100 } 101 } // namespace CustomCreatorDeletor 102 103 } // anonymous namespace 104