xref: /llvm-project/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/mutex.pass.cpp (revision 9ff0468436c957fadcd8926683696a879cbc78a0)
1*9ff04684SNikolas Klauser //===----------------------------------------------------------------------===//
2*9ff04684SNikolas Klauser //
3*9ff04684SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*9ff04684SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5*9ff04684SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*9ff04684SNikolas Klauser //
7*9ff04684SNikolas Klauser //===----------------------------------------------------------------------===//
8*9ff04684SNikolas Klauser 
9*9ff04684SNikolas Klauser // UNSUPPORTED: no-threads
10*9ff04684SNikolas Klauser 
11*9ff04684SNikolas Klauser // <mutex>
12*9ff04684SNikolas Klauser 
13*9ff04684SNikolas Klauser // Make sure std::unique_lock works with std::mutex as expected.
14*9ff04684SNikolas Klauser 
15*9ff04684SNikolas Klauser #include <atomic>
16*9ff04684SNikolas Klauser #include <cassert>
17*9ff04684SNikolas Klauser #include <mutex>
18*9ff04684SNikolas Klauser 
19*9ff04684SNikolas Klauser #include "make_test_thread.h"
20*9ff04684SNikolas Klauser 
21*9ff04684SNikolas Klauser std::atomic<bool> keep_waiting;
22*9ff04684SNikolas Klauser std::atomic<bool> child_thread_locked;
23*9ff04684SNikolas Klauser std::mutex mux;
24*9ff04684SNikolas Klauser bool main_thread_unlocked  = false;
25*9ff04684SNikolas Klauser bool child_thread_unlocked = false;
26*9ff04684SNikolas Klauser 
27*9ff04684SNikolas Klauser void lock_thread() {
28*9ff04684SNikolas Klauser   std::unique_lock<std::mutex> lock(mux);
29*9ff04684SNikolas Klauser   assert(main_thread_unlocked);
30*9ff04684SNikolas Klauser   main_thread_unlocked  = false;
31*9ff04684SNikolas Klauser   child_thread_unlocked = true;
32*9ff04684SNikolas Klauser }
33*9ff04684SNikolas Klauser 
34*9ff04684SNikolas Klauser void try_lock_thread() {
35*9ff04684SNikolas Klauser   std::unique_lock<std::mutex> lock(mux, std::try_to_lock_t());
36*9ff04684SNikolas Klauser   assert(lock.owns_lock());
37*9ff04684SNikolas Klauser   child_thread_locked = true;
38*9ff04684SNikolas Klauser 
39*9ff04684SNikolas Klauser   while (keep_waiting)
40*9ff04684SNikolas Klauser     std::this_thread::sleep_for(std::chrono::milliseconds(10));
41*9ff04684SNikolas Klauser 
42*9ff04684SNikolas Klauser   child_thread_unlocked = true;
43*9ff04684SNikolas Klauser }
44*9ff04684SNikolas Klauser 
45*9ff04684SNikolas Klauser int main(int, char**) {
46*9ff04684SNikolas Klauser   {
47*9ff04684SNikolas Klauser     mux.lock();
48*9ff04684SNikolas Klauser     std::thread t        = support::make_test_thread(lock_thread);
49*9ff04684SNikolas Klauser     main_thread_unlocked = true;
50*9ff04684SNikolas Klauser     mux.unlock();
51*9ff04684SNikolas Klauser     t.join();
52*9ff04684SNikolas Klauser     assert(child_thread_unlocked);
53*9ff04684SNikolas Klauser   }
54*9ff04684SNikolas Klauser 
55*9ff04684SNikolas Klauser   {
56*9ff04684SNikolas Klauser     child_thread_unlocked = false;
57*9ff04684SNikolas Klauser     child_thread_locked   = false;
58*9ff04684SNikolas Klauser     keep_waiting          = true;
59*9ff04684SNikolas Klauser     std::thread t         = support::make_test_thread(try_lock_thread);
60*9ff04684SNikolas Klauser     while (!child_thread_locked)
61*9ff04684SNikolas Klauser       std::this_thread::sleep_for(std::chrono::milliseconds(10));
62*9ff04684SNikolas Klauser     assert(!mux.try_lock());
63*9ff04684SNikolas Klauser     keep_waiting = false;
64*9ff04684SNikolas Klauser     t.join();
65*9ff04684SNikolas Klauser     assert(child_thread_unlocked);
66*9ff04684SNikolas Klauser   }
67*9ff04684SNikolas Klauser 
68*9ff04684SNikolas Klauser   return 0;
69*9ff04684SNikolas Klauser }
70