1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // UNSUPPORTED: libcpp-has-no-threads 11 // 12 // <memory> 13 // 14 // class shared_ptr 15 // 16 // This test attempts to create a race condition surrounding use_count() 17 // with the hope that TSAN will diagnose it. 18 19 #include <memory> 20 #include <atomic> 21 #include <thread> 22 #include <cassert> 23 24 typedef std::shared_ptr<int> Ptr; 25 typedef std::weak_ptr<int> WeakPtr; 26 27 std::atomic_bool Start; 28 std::atomic_bool KeepRunning; 29 30 struct TestRunner { TestRunnerTestRunner31 TestRunner(Ptr xx) : x(xx) {} operator ()TestRunner32 void operator()() { 33 while (Start == false) {} 34 while (KeepRunning) { 35 // loop to prevent always checking the atomic. 36 for (int i=0; i < 100000; ++i) { 37 Ptr x2 = x; // increment shared count 38 WeakPtr x3 = x; // increment weak count 39 Ptr x4 = x3.lock(); // increment shared count via lock 40 WeakPtr x5 = x3; // increment weak count 41 } 42 } 43 } 44 Ptr x; 45 }; 46 run_test(Ptr p)47void run_test(Ptr p) { 48 Start = false; 49 KeepRunning = true; 50 assert(p.use_count() == 2); 51 TestRunner r(p); 52 assert(p.use_count() == 3); 53 std::thread t1(r); // Start the test thread. 54 assert(p.use_count() == 4); 55 Start = true; 56 // Run until we witness 25 use count changes via both 57 // shared and weak pointer methods. 58 WeakPtr w = p; 59 int shared_changes_count = 0; 60 int weak_changes_count = 0; 61 while (shared_changes_count < 25 && weak_changes_count < 25) { 62 // check use_count on the shared_ptr 63 int last = p.use_count(); 64 int new_val = p.use_count(); 65 assert(last >= 4); 66 assert(new_val >= 4); 67 if (last != new_val) ++shared_changes_count; 68 // Check use_count on the weak_ptr 69 last = w.use_count(); 70 new_val = w.use_count(); 71 assert(last >= 4); 72 assert(new_val >= 4); 73 if (last != new_val) ++weak_changes_count; 74 } 75 // kill the test thread. 76 KeepRunning = false; 77 t1.join(); 78 assert(p.use_count() == 3); 79 } 80 main()81int main() { 82 { 83 // Test with out-of-place shared_count. 84 Ptr p(new int(42)); 85 run_test(p); 86 assert(p.use_count() == 1); 87 } 88 { 89 // Test with in-place shared_count. 90 Ptr p = std::make_shared<int>(42); 91 run_test(p); 92 assert(p.use_count() == 1); 93 } 94 } 95