ManagedStatic.cpp 2.3 KB

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