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)47 void 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()81 int 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