1 //===----------------------------------------------------------------------===// 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 // UNSUPPORTED: no-threads 10 // 11 // <memory> 12 // 13 // class shared_ptr 14 // 15 // This test attempts to create a race condition surrounding use_count() 16 // with the hope that TSAN will diagnose it. 17 18 #include <memory> 19 #include <atomic> 20 #include <thread> 21 #include <cassert> 22 23 #include "make_test_thread.h" 24 #include "test_macros.h" 25 26 typedef std::shared_ptr<int> Ptr; 27 typedef std::weak_ptr<int> WeakPtr; 28 29 std::atomic_bool Start; 30 std::atomic_bool KeepRunning; 31 32 struct TestRunner { TestRunnerTestRunner33 TestRunner(Ptr xx) : x(xx) {} operator ()TestRunner34 void operator()() { 35 while (Start == false) {} 36 while (KeepRunning) { 37 // loop to prevent always checking the atomic. 38 for (int i=0; i < 100000; ++i) { 39 Ptr x2 = x; // increment shared count 40 WeakPtr x3 = x; // increment weak count 41 Ptr x4 = x3.lock(); // increment shared count via lock 42 WeakPtr x5 = x3; // increment weak count 43 } 44 } 45 } 46 Ptr x; 47 }; 48 run_test(Ptr p)49void run_test(Ptr p) { 50 Start = false; 51 KeepRunning = true; 52 assert(p.use_count() == 2); 53 TestRunner r(p); 54 assert(p.use_count() == 3); 55 std::thread t1 = support::make_test_thread(r); // Start the test thread. 56 assert(p.use_count() == 4); 57 Start = true; 58 // Run until we witness 25 use count changes via both 59 // shared and weak pointer methods. 60 WeakPtr w = p; 61 int shared_changes_count = 0; 62 int weak_changes_count = 0; 63 while (shared_changes_count < 25 && weak_changes_count < 25) { 64 // check use_count on the shared_ptr 65 int last = p.use_count(); 66 int new_val = p.use_count(); 67 assert(last >= 4); 68 assert(new_val >= 4); 69 if (last != new_val) ++shared_changes_count; 70 // Check use_count on the weak_ptr 71 last = w.use_count(); 72 new_val = w.use_count(); 73 assert(last >= 4); 74 assert(new_val >= 4); 75 if (last != new_val) ++weak_changes_count; 76 } 77 // kill the test thread. 78 KeepRunning = false; 79 t1.join(); 80 assert(p.use_count() == 3); 81 } 82 main(int,char **)83int main(int, char**) { 84 { 85 // Test with out-of-place shared_count. 86 Ptr p(new int(42)); 87 run_test(p); 88 assert(p.use_count() == 1); 89 } 90 { 91 // Test with in-place shared_count. 92 int val = 42; 93 Ptr p = std::make_shared<int>(val); 94 run_test(p); 95 assert(p.use_count() == 1); 96 } 97 98 return 0; 99 } 100