15a83710eSEric Fiselier //===----------------------------------------------------------------------===// 25a83710eSEric Fiselier // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65a83710eSEric Fiselier // 75a83710eSEric Fiselier //===----------------------------------------------------------------------===// 85a83710eSEric Fiselier // 9*a7f9895cSLouis Dionne // UNSUPPORTED: no-threads 1031cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11 115a83710eSEric Fiselier 12f17eb4ecSLouis Dionne // shared_timed_mutex was introduced in macosx10.12 13c360553cSLouis Dionne // UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11}} 14f17eb4ecSLouis Dionne 151e1e97a3SNikolas Klauser // ALLOW_RETRIES: 3 161e1e97a3SNikolas Klauser 175a83710eSEric Fiselier // <shared_mutex> 185a83710eSEric Fiselier 195a83710eSEric Fiselier // class shared_timed_mutex; 205a83710eSEric Fiselier 215a83710eSEric Fiselier // void lock_shared(); 225a83710eSEric Fiselier 235a83710eSEric Fiselier #include <thread> 24332da1c2SChristopher Di Bella 25332da1c2SChristopher Di Bella #include <atomic> 265a83710eSEric Fiselier #include <cassert> 27332da1c2SChristopher Di Bella #include <cstdlib> 28332da1c2SChristopher Di Bella #include <shared_mutex> 29332da1c2SChristopher Di Bella #include <vector> 305a83710eSEric Fiselier 3156462801SLouis Dionne #include "make_test_thread.h" 32fb65a3a6SEric Fiselier #include "test_macros.h" 33fb65a3a6SEric Fiselier 345a83710eSEric Fiselier std::shared_timed_mutex m; 355a83710eSEric Fiselier 365a83710eSEric Fiselier typedef std::chrono::system_clock Clock; 375a83710eSEric Fiselier typedef Clock::time_point time_point; 385a83710eSEric Fiselier typedef Clock::duration duration; 395a83710eSEric Fiselier typedef std::chrono::milliseconds ms; 405a83710eSEric Fiselier typedef std::chrono::nanoseconds ns; 415a83710eSEric Fiselier 424f4ce139SDavid Zarzycki std::atomic<unsigned> countDown; 434f4ce139SDavid Zarzycki time_point readerStart; // Protected by the above mutex 'm' 444f4ce139SDavid Zarzycki time_point writerStart; // Protected by the above mutex 'm' 45fb65a3a6SEric Fiselier 46fb65a3a6SEric Fiselier ms WaitTime = ms(250); 47fb65a3a6SEric Fiselier readerMustWait()484f4ce139SDavid Zarzyckivoid readerMustWait() { 494f4ce139SDavid Zarzycki --countDown; 505a83710eSEric Fiselier m.lock_shared(); 515a83710eSEric Fiselier time_point t1 = Clock::now(); 524f4ce139SDavid Zarzycki time_point t0 = readerStart; 535a83710eSEric Fiselier m.unlock_shared(); 544f4ce139SDavid Zarzycki assert(t0.time_since_epoch() > ms(0)); 554f4ce139SDavid Zarzycki assert(t1 - t0 >= WaitTime); 565a83710eSEric Fiselier } 575a83710eSEric Fiselier reader()584f4ce139SDavid Zarzyckivoid reader() { 594f4ce139SDavid Zarzycki --countDown; 605a83710eSEric Fiselier m.lock_shared(); 615a83710eSEric Fiselier m.unlock_shared(); 625a83710eSEric Fiselier } 635a83710eSEric Fiselier writerMustWait()644f4ce139SDavid Zarzyckivoid writerMustWait() { 654f4ce139SDavid Zarzycki --countDown; 664f4ce139SDavid Zarzycki m.lock(); 674f4ce139SDavid Zarzycki time_point t1 = Clock::now(); 684f4ce139SDavid Zarzycki time_point t0 = writerStart; 694f4ce139SDavid Zarzycki m.unlock(); 704f4ce139SDavid Zarzycki assert(t0.time_since_epoch() > ms(0)); 714f4ce139SDavid Zarzycki assert(t1 - t0 >= WaitTime); 724f4ce139SDavid Zarzycki } 735a83710eSEric Fiselier main(int,char **)742df59c50SJF Bastienint main(int, char**) 755a83710eSEric Fiselier { 764f4ce139SDavid Zarzycki int threads = 5; 774f4ce139SDavid Zarzycki 784f4ce139SDavid Zarzycki countDown.store(threads); 795a83710eSEric Fiselier m.lock(); 805a83710eSEric Fiselier std::vector<std::thread> v; 814f4ce139SDavid Zarzycki for (int i = 0; i < threads; ++i) 8256462801SLouis Dionne v.push_back(support::make_test_thread(readerMustWait)); 834f4ce139SDavid Zarzycki while (countDown > 0) 844f4ce139SDavid Zarzycki std::this_thread::yield(); 854f4ce139SDavid Zarzycki readerStart = Clock::now(); 86fb65a3a6SEric Fiselier std::this_thread::sleep_for(WaitTime); 875a83710eSEric Fiselier m.unlock(); 885a83710eSEric Fiselier for (auto& t : v) 895a83710eSEric Fiselier t.join(); 904f4ce139SDavid Zarzycki 914f4ce139SDavid Zarzycki countDown.store(threads + 1); 925a83710eSEric Fiselier m.lock_shared(); 935a83710eSEric Fiselier for (auto& t : v) 9456462801SLouis Dionne t = support::make_test_thread(reader); 9556462801SLouis Dionne std::thread q = support::make_test_thread(writerMustWait); 964f4ce139SDavid Zarzycki while (countDown > 0) 974f4ce139SDavid Zarzycki std::this_thread::yield(); 984f4ce139SDavid Zarzycki writerStart = Clock::now(); 99fb65a3a6SEric Fiselier std::this_thread::sleep_for(WaitTime); 1005a83710eSEric Fiselier m.unlock_shared(); 1015a83710eSEric Fiselier for (auto& t : v) 1025a83710eSEric Fiselier t.join(); 1035a83710eSEric Fiselier q.join(); 1042df59c50SJF Bastien 1052df59c50SJF Bastien return 0; 1065a83710eSEric Fiselier } 107