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