100 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// UNSUPPORTED: no-threads10//11// <memory>12//13// class shared_ptr14//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 26typedef std::shared_ptr<int> Ptr;27typedef std::weak_ptr<int> WeakPtr;28 29std::atomic_bool Start;30std::atomic_bool KeepRunning;31 32struct TestRunner {33 TestRunner(Ptr xx) : x(xx) {}34 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 count40 WeakPtr x3 = x; // increment weak count41 Ptr x4 = x3.lock(); // increment shared count via lock42 WeakPtr x5 = x3; // increment weak count43 }44 }45 }46 Ptr x;47};48 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 both59 // 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_ptr65 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_ptr71 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 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