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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // UNSUPPORTED: no-threads 10 // UNSUPPORTED: c++03, c++11 11 12 // shared_timed_mutex was introduced in macosx10.12 13 // UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11}} 14 15 // <shared_mutex> 16 17 // class shared_timed_mutex; 18 19 #include <shared_mutex> 20 21 #include <atomic> 22 #include <chrono> 23 #include <thread> 24 #include <cstdlib> 25 #include <cassert> 26 27 #include "make_test_thread.h" 28 #include "test_macros.h" 29 30 std::shared_timed_mutex m; 31 32 const int total_readers = 2; 33 std::atomic<int> readers_started(0); 34 std::atomic<int> readers_finished(0); 35 36 // Wait for the readers to start then try and acquire the write lock. writer_one()37void writer_one() { 38 while (readers_started != total_readers) {} 39 bool b = m.try_lock_for(std::chrono::milliseconds(500)); 40 assert(b == false); 41 } 42 blocked_reader()43void blocked_reader() { 44 ++readers_started; 45 // Wait until writer_one is waiting for the write lock. 46 while (m.try_lock_shared()) { 47 m.unlock_shared(); 48 } 49 // Attempt to get the read lock. writer_one should be blocking us because 50 // writer_one is blocked by main. 51 m.lock_shared(); 52 ++readers_finished; 53 m.unlock_shared(); 54 } 55 main(int,char **)56int main(int, char**) 57 { 58 typedef std::chrono::steady_clock Clock; 59 60 m.lock_shared(); 61 std::thread t1 = support::make_test_thread(writer_one); 62 // create some readers 63 std::thread t2 = support::make_test_thread(blocked_reader); 64 std::thread t3 = support::make_test_thread(blocked_reader); 65 // Kill the test after 10 seconds if it hasn't completed. 66 auto end_point = Clock::now() + std::chrono::seconds(10); 67 while (readers_finished != total_readers && Clock::now() < end_point) { 68 std::this_thread::sleep_for(std::chrono::seconds(1)); 69 } 70 assert(readers_finished == total_readers); 71 m.unlock_shared(); 72 t1.join(); 73 t2.join(); 74 t3.join(); 75 76 return 0; 77 } 78