xref: /llvm-project/libcxx/test/support/checking_mutex.h (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 #ifndef TEST_SUPPORT_CHECKING_MUTEX_H
10*9ff04684SNikolas Klauser #define TEST_SUPPORT_CHECKING_MUTEX_H
11*9ff04684SNikolas Klauser 
12*9ff04684SNikolas Klauser #include <cassert>
13*9ff04684SNikolas Klauser #include <chrono>
14*9ff04684SNikolas Klauser 
15*9ff04684SNikolas Klauser struct checking_mutex {
16*9ff04684SNikolas Klauser   enum state {
17*9ff04684SNikolas Klauser     locked_via_lock,
18*9ff04684SNikolas Klauser     locked_via_try_lock,
19*9ff04684SNikolas Klauser     locked_via_try_lock_for,
20*9ff04684SNikolas Klauser     locked_via_try_lock_until,
21*9ff04684SNikolas Klauser     unlocked,
22*9ff04684SNikolas Klauser     none,
23*9ff04684SNikolas Klauser   };
24*9ff04684SNikolas Klauser 
25*9ff04684SNikolas Klauser   state current_state = unlocked;
26*9ff04684SNikolas Klauser   state last_try      = none;
27*9ff04684SNikolas Klauser   bool reject         = false;
28*9ff04684SNikolas Klauser 
29*9ff04684SNikolas Klauser   checking_mutex()                      = default;
30*9ff04684SNikolas Klauser   checking_mutex(const checking_mutex&) = delete;
31*9ff04684SNikolas Klauser   ~checking_mutex() { assert(current_state == unlocked); }
32*9ff04684SNikolas Klauser 
33*9ff04684SNikolas Klauser   void lock() {
34*9ff04684SNikolas Klauser     assert(current_state == unlocked);
35*9ff04684SNikolas Klauser     assert(!reject);
36*9ff04684SNikolas Klauser     current_state = locked_via_lock;
37*9ff04684SNikolas Klauser     last_try      = locked_via_lock;
38*9ff04684SNikolas Klauser     reject        = true;
39*9ff04684SNikolas Klauser   }
40*9ff04684SNikolas Klauser 
41*9ff04684SNikolas Klauser   void unlock() {
42*9ff04684SNikolas Klauser     assert(current_state != unlocked && current_state != none);
43*9ff04684SNikolas Klauser     last_try      = unlocked;
44*9ff04684SNikolas Klauser     current_state = unlocked;
45*9ff04684SNikolas Klauser     reject        = false;
46*9ff04684SNikolas Klauser   }
47*9ff04684SNikolas Klauser 
48*9ff04684SNikolas Klauser   bool try_lock() {
49*9ff04684SNikolas Klauser     last_try = locked_via_try_lock;
50*9ff04684SNikolas Klauser     if (reject)
51*9ff04684SNikolas Klauser       return false;
52*9ff04684SNikolas Klauser     current_state = locked_via_try_lock;
53*9ff04684SNikolas Klauser     return true;
54*9ff04684SNikolas Klauser   }
55*9ff04684SNikolas Klauser 
56*9ff04684SNikolas Klauser   template <class Rep, class Period>
57*9ff04684SNikolas Klauser   bool try_lock_for(const std::chrono::duration<Rep, Period>&) {
58*9ff04684SNikolas Klauser     last_try = locked_via_try_lock_for;
59*9ff04684SNikolas Klauser     if (reject)
60*9ff04684SNikolas Klauser       return false;
61*9ff04684SNikolas Klauser     current_state = locked_via_try_lock_for;
62*9ff04684SNikolas Klauser     return true;
63*9ff04684SNikolas Klauser   }
64*9ff04684SNikolas Klauser 
65*9ff04684SNikolas Klauser   template <class Clock, class Duration>
66*9ff04684SNikolas Klauser   bool try_lock_until(const std::chrono::time_point<Clock, Duration>&) {
67*9ff04684SNikolas Klauser     last_try = locked_via_try_lock_until;
68*9ff04684SNikolas Klauser     if (reject)
69*9ff04684SNikolas Klauser       return false;
70*9ff04684SNikolas Klauser     current_state = locked_via_try_lock_until;
71*9ff04684SNikolas Klauser     return true;
72*9ff04684SNikolas Klauser   }
73*9ff04684SNikolas Klauser 
74*9ff04684SNikolas Klauser   checking_mutex* operator&() = delete;
75*9ff04684SNikolas Klauser 
76*9ff04684SNikolas Klauser   template <class T>
77*9ff04684SNikolas Klauser   void operator,(const T&) = delete;
78*9ff04684SNikolas Klauser };
79*9ff04684SNikolas Klauser 
80*9ff04684SNikolas Klauser #endif // TEST_SUPPORT_CHECKING_MUTEX_H
81