brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · f78b13d Raw
109 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// UNSUPPORTED: c++03, c++1111 12// <shared_mutex>13 14// class shared_timed_mutex;15 16// void lock();17 18#include <shared_mutex>19#include <atomic>20#include <cassert>21#include <chrono>22#include <thread>23#include <vector>24 25#include "make_test_thread.h"26 27int main(int, char**) {28  // Exclusive-lock a mutex that is not locked yet. This should succeed.29  {30    std::shared_timed_mutex m;31    m.lock();32    m.unlock();33  }34 35  // Exclusive-lock a mutex that is already locked exclusively. This should block until it is unlocked.36  {37    std::atomic<bool> ready(false);38    std::shared_timed_mutex m;39    m.lock();40    std::atomic<bool> is_locked_from_main(true);41 42    std::thread t = support::make_test_thread([&] {43      ready = true;44      m.lock();45      assert(!is_locked_from_main);46      m.unlock();47    });48 49    while (!ready)50      /* spin */;51 52    // We would rather signal this after we unlock, but that would create a race condition.53    // We instead signal it before we unlock, which means that it's technically possible for the thread54    // to take the lock while we're still holding it and for the test to still pass.55    is_locked_from_main = false;56    m.unlock();57 58    t.join();59  }60 61  // Exclusive-lock a mutex that is already share-locked. This should block until it is unlocked.62  {63    std::atomic<bool> ready(false);64    std::shared_timed_mutex m;65    m.lock_shared();66    std::atomic<bool> is_locked_from_main(true);67 68    std::thread t = support::make_test_thread([&] {69      ready = true;70      m.lock();71      assert(!is_locked_from_main);72      m.unlock();73    });74 75    while (!ready)76      /* spin */;77 78    // We would rather signal this after we unlock, but that would create a race condition.79    // We instead signal it before we unlock, which means that it's technically possible for80    // the thread to take the lock while we're still holding it and for the test to still pass.81    is_locked_from_main = false;82    m.unlock_shared();83 84    t.join();85  }86 87  // Make sure that at most one thread can acquire the mutex concurrently.88  {89    std::atomic<int> counter(0);90    std::shared_timed_mutex mutex;91 92    std::vector<std::thread> threads;93    for (int i = 0; i != 10; ++i) {94      threads.push_back(support::make_test_thread([&] {95        mutex.lock();96        counter++;97        assert(counter == 1);98        counter--;99        mutex.unlock();100      }));101    }102 103    for (auto& t : threads)104      t.join();105  }106 107  return 0;108}109