source: mainline/uspace/lib/cpp/include/impl/mutex.hpp@ befead8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since befead8 was 69e5838, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added timed_mutex

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_MUTEX
30#define LIBCPP_MUTEX
31
32#include <internal/common.hpp>
33#include <internal/thread.hpp>
34#include <thread>
35
36namespace std
37{
38 /**
39 * 20.4.1.2.1, class mutex:
40 */
41
42 class mutex
43 {
44 public:
45 constexpr mutex() noexcept
46 : mtx_{}
47 {
48 aux::threading::mutex::init(mtx_);
49 }
50
51 ~mutex();
52
53 mutex(const mutex&) = delete;
54 mutex& operator=(const mutex&) = delete;
55
56 void lock();
57 bool try_lock();
58 void unlock();
59
60 using native_handle_type = aux::mutex_t*;
61 native_handle_type native_handle();
62
63 private:
64 aux::mutex_t mtx_;
65 };
66
67 /**
68 * 30.4.1.2.2, class recursive_mutex:
69 */
70
71 class recursive_mutex
72 {
73 public:
74 constexpr recursive_mutex() noexcept
75 : mtx_{}, lock_level_{}, owner_{}
76 {
77 aux::threading::mutex::init(mtx_);
78 }
79
80 ~recursive_mutex();
81
82 recursive_mutex(const recursive_mutex&) = delete;
83 recursive_mutex& operator=(const recursive_mutex&) = delete;
84
85 void lock();
86 bool try_lock();
87 void unlock();
88
89 using native_handle_type = aux::mutex_t*;
90 native_handle_type native_handle();
91
92 private:
93 aux::mutex_t mtx_;
94 size_t lock_level_;
95 thread::id owner_;
96 };
97
98 /**
99 * 30.4.1.3.1, class timed_mutex:
100 */
101
102 class timed_mutex
103 {
104 public:
105 timed_mutex() noexcept;
106 ~timed_mutex();
107
108 timed_mutex(const timed_mutex&) = delete;
109 timed_mutex& operator=(const timed_mutex&) = delete;
110
111 void lock();
112 bool try_lock();
113 void unlock();
114
115 template<class Rep, class Period>
116 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
117 {
118 auto time = aux::threading::time::convert(rel_time);
119
120 return aux::threading::mutex::try_lock_for(time);
121 }
122
123 template<class Clock, class Duration>
124 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
125 {
126 auto dur = (abs_time - Clock::now());
127 auto time = aux::threading::time::convert(dur);
128
129 return aux::threading::mutex::try_lock_for(time);
130 }
131
132 using native_handle_type = aux::mutex_t*;
133 native_handle_type native_handle();
134
135 private:
136 aux::mutex_t mtx_;
137 };
138
139 /**
140 * 30.4.1.3.2, class recursive_timed_mutex:
141 */
142
143 // TODO: implement
144 class recursive_timed_mutex;
145
146 struct defer_lock_t
147 { /* DUMMY BODY */ };
148
149 struct try_to_lock_t
150 { /* DUMMY BODY */ };
151
152 struct adopt_lock_t
153 { /* DUMMY BODY */ };
154
155 constexpr defer_lock_t defer_lock
156 { /* DUMMY BODY */ };
157
158 constexpr try_to_lock_t try_to_lock
159 { /* DUMMY BODY */ };
160
161 constexpr adopt_lock_t adopt_lock
162 { /* DUMMY BODY */ };
163
164 /**
165 * 30.4.2.1, class template lock_guard:
166 */
167
168 template<class Mutex>
169 class lock_guard
170 {
171 public:
172 using mutex_type = Mutex;
173
174 explicit lock_guard(mutex_type& mtx)
175 : mtx_{mtx}
176 {
177 mtx.lock();
178 }
179
180 lock_guard(mutex_type& mtx, adopt_lock_t)
181 : mtx_{mtx}
182 { /* DUMMY BODY */ }
183
184 ~lock_guard()
185 {
186 mtx_.unlock();
187 }
188
189 lock_guard(const lock_guard&) = delete;
190 lock_guard& operator=(const lock_guard&) = delete;
191
192 private:
193 mutex_type& mtx_;
194 };
195
196 template<class Mutex>
197 class unique_lock;
198
199 template<class Mutex>
200 void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs) noexcept;
201
202 template<class L1, class L2, class... L3>
203 int try_lock(L1& l1, L2& l2, L3&... ls);
204
205 template<class L1, class L2, class... L3>
206 void lock(L1& l1, L2& l2, L3&... ls);
207
208 struct once_flag
209 {
210 constexpr once_flag() noexcept;
211
212 once_flag(const once_flag&) = delete;
213 once_flag& operator=(const once_flag&) = delete;
214 };
215
216 template<class Callable, class... Args>
217 void call_once(once_flag& flag, Callable&& func, Args&&... args);
218}
219
220#endif
Note: See TracBrowser for help on using the repository browser.