99 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 timed_mutex;15 16// template <class Rep, class Period>17// shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);18 19#include <thread>20 21#include <atomic>22#include <cassert>23#include <chrono>24#include <cstdlib>25#include <shared_mutex>26#include <vector>27 28#include "make_test_thread.h"29#include "test_macros.h"30 31std::shared_timed_mutex m;32 33typedef std::chrono::steady_clock Clock;34typedef Clock::time_point time_point;35typedef Clock::duration duration;36typedef std::chrono::milliseconds ms;37typedef std::chrono::nanoseconds ns;38 39ms LongTime = ms(5000);40ms ShortTime = ms(50);41 42static const unsigned Threads = 5;43 44std::atomic<unsigned> CountDown(Threads);45 46void f1()47{48 // Preemptive scheduling means that one cannot make assumptions about when49 // code executes and therefore we cannot assume anything about when the mutex50 // starts waiting relative to code in the main thread. We can however prove51 // that a timeout occurred and that implies that this code is waiting.52 // See f2() below.53 //54 // Nevertheless, we should at least try to ensure that the mutex waits and55 // therefore we use an atomic variable to signal to the main thread that this56 // code is just a few instructions away from waiting.57 --CountDown;58 std::shared_lock<std::shared_timed_mutex> lk(m, LongTime);59 assert(lk.owns_lock() == true);60}61 62void f2()63{64 time_point t0 = Clock::now();65 std::shared_lock<std::shared_timed_mutex> lk(m, ShortTime);66 time_point t1 = Clock::now();67 assert(lk.owns_lock() == false);68 assert(t1 - t0 >= ShortTime);69}70 71int main(int, char**)72{73 {74 m.lock();75 std::vector<std::thread> v;76 for (unsigned i = 0; i < Threads; ++i)77 v.push_back(support::make_test_thread(f1));78 while (CountDown > 0)79 std::this_thread::yield();80 // Give one more chance for threads to block and wait for the mutex.81 std::this_thread::yield();82 std::this_thread::sleep_for(ShortTime);83 m.unlock();84 for (auto& t : v)85 t.join();86 }87 {88 m.lock();89 std::vector<std::thread> v;90 for (unsigned i = 0; i < Threads; ++i)91 v.push_back(support::make_test_thread(f2));92 for (auto& t : v)93 t.join();94 m.unlock();95 }96 97 return 0;98}99