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 24typedef std::shared_ptr<int> Ptr; 25typedef std::weak_ptr<int> WeakPtr; 26 27std::atomic_bool Start; 28std::atomic_bool KeepRunning; 29 30struct TestRunner { 31 TestRunner(Ptr xx) : x(xx) {} 32 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 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 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 int val = 42; 91 Ptr p = std::make_shared<int>(val); 92 run_test(p); 93 assert(p.use_count() == 1); 94 } 95} 96