ManagedStatic.cpp 2.4 KB

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