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