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