82 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: c++0310// UNSUPPORTED: no-threads11 12// <mutex>13 14// class timed_mutex;15 16// void lock();17 18#include <mutex>19#include <atomic>20#include <cassert>21#include <thread>22#include <vector>23 24#include "make_test_thread.h"25 26int main(int, char**) {27 // Lock a mutex that is not locked yet. This should succeed.28 {29 std::timed_mutex m;30 m.lock();31 m.unlock();32 }33 34 // Lock a mutex that is already locked. This should block until it is unlocked.35 {36 std::atomic<bool> ready(false);37 std::timed_mutex m;38 m.lock();39 std::atomic<bool> is_locked_from_main(true);40 41 std::thread t = support::make_test_thread([&] {42 ready = true;43 m.lock();44 assert(!is_locked_from_main);45 m.unlock();46 });47 48 while (!ready)49 /* spin */;50 51 // We would rather signal this after we unlock, but that would create a race condition.52 // We instead signal it before we unlock, which means that it's technically possible for53 // the thread to take the lock while main is still holding it yet for the test to still pass.54 is_locked_from_main = false;55 m.unlock();56 57 t.join();58 }59 60 // Make sure that at most one thread can acquire the mutex concurrently.61 {62 std::atomic<int> counter(0);63 std::timed_mutex mutex;64 65 std::vector<std::thread> threads;66 for (int i = 0; i != 10; ++i) {67 threads.push_back(support::make_test_thread([&] {68 mutex.lock();69 counter++;70 assert(counter == 1);71 counter--;72 mutex.unlock();73 }));74 }75 76 for (auto& t : threads)77 t.join();78 }79 80 return 0;81}82