brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · cbecd2d Raw
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