xref: /haiku/headers/private/kernel/util/AutoLock.h (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
1 /*
2  * Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de.
3  * Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 #ifndef KERNEL_UTIL_AUTO_LOCKER_H
8 #define KERNEL_UTIL_AUTO_LOCKER_H
9 
10 
11 #include <KernelExport.h>
12 
13 #include <shared/AutoLocker.h>
14 
15 #include <int.h>
16 #include <lock.h>
17 
18 
19 namespace BPrivate {
20 
21 
22 class MutexLocking {
23 public:
24 	inline bool Lock(mutex *lockable)
25 	{
26 		return mutex_lock(lockable) == B_OK;
27 	}
28 
29 	inline void Unlock(mutex *lockable)
30 	{
31 		mutex_unlock(lockable);
32 	}
33 };
34 
35 typedef AutoLocker<mutex, MutexLocking> MutexLocker;
36 
37 
38 class MutexTryLocking {
39 public:
40 	inline bool Lock(mutex *lockable)
41 	{
42 		return mutex_trylock(lockable) == B_OK;
43 	}
44 
45 	inline void Unlock(mutex *lockable)
46 	{
47 		mutex_unlock(lockable);
48 	}
49 };
50 
51 typedef AutoLocker<mutex, MutexTryLocking> MutexTryLocker;
52 
53 
54 class RecursiveLockLocking {
55 public:
56 	inline bool Lock(recursive_lock *lockable)
57 	{
58 		return recursive_lock_lock(lockable) == B_OK;
59 	}
60 
61 	inline void Unlock(recursive_lock *lockable)
62 	{
63 		recursive_lock_unlock(lockable);
64 	}
65 };
66 
67 typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker;
68 
69 
70 class ReadWriteLockReadLocking {
71 public:
72 	inline bool Lock(rw_lock *lockable)
73 	{
74 		return rw_lock_read_lock(lockable) == B_OK;
75 	}
76 
77 	inline void Unlock(rw_lock *lockable)
78 	{
79 		rw_lock_read_unlock(lockable);
80 	}
81 };
82 
83 class ReadWriteLockWriteLocking {
84 public:
85 	inline bool Lock(rw_lock *lockable)
86 	{
87 		return rw_lock_write_lock(lockable) == B_OK;
88 	}
89 
90 	inline void Unlock(rw_lock *lockable)
91 	{
92 		rw_lock_write_unlock(lockable);
93 	}
94 };
95 
96 typedef AutoLocker<rw_lock, ReadWriteLockReadLocking> ReadLocker;
97 typedef AutoLocker<rw_lock, ReadWriteLockWriteLocking> WriteLocker;
98 
99 
100 class InterruptsLocking {
101 public:
102 	inline bool Lock(int* lockable)
103 	{
104 		*lockable = disable_interrupts();
105 		return true;
106 	}
107 
108 	inline void Unlock(int* lockable)
109 	{
110 		restore_interrupts(*lockable);
111 	}
112 };
113 
114 
115 class InterruptsLocker : public AutoLocker<int, InterruptsLocking> {
116 public:
117 	inline InterruptsLocker(bool alreadyLocked = false,
118 		bool lockIfNotLocked = true)
119 		: AutoLocker<int, InterruptsLocking>(&fState, alreadyLocked,
120 			lockIfNotLocked)
121 	{
122 	}
123 
124 private:
125 	int	fState;
126 };
127 
128 
129 class SpinLocking {
130 public:
131 	inline bool Lock(spinlock* lockable)
132 	{
133 		acquire_spinlock(lockable);
134 		return true;
135 	}
136 
137 	inline void Unlock(spinlock* lockable)
138 	{
139 		release_spinlock(lockable);
140 	}
141 };
142 
143 typedef AutoLocker<spinlock, SpinLocking> SpinLocker;
144 
145 
146 class InterruptsSpinLocking {
147 public:
148 // NOTE: work-around for annoying GCC 4+ "fState may be used uninitialized"
149 // warning.
150 #if __GNUC__ >= 4
151 	InterruptsSpinLocking()
152 		:
153 		fState(0)
154 	{
155 	}
156 #endif
157 
158 	inline bool Lock(spinlock* lockable)
159 	{
160 		fState = disable_interrupts();
161 		acquire_spinlock(lockable);
162 		return true;
163 	}
164 
165 	inline void Unlock(spinlock* lockable)
166 	{
167 		release_spinlock(lockable);
168 		restore_interrupts(fState);
169 	}
170 
171 private:
172 	int	fState;
173 };
174 
175 typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker;
176 
177 
178 class ReadSpinLocking {
179 public:
180 	inline bool Lock(rw_spinlock* lockable)
181 	{
182 		acquire_read_spinlock(lockable);
183 		return true;
184 	}
185 
186 	inline void Unlock(rw_spinlock* lockable)
187 	{
188 		release_read_spinlock(lockable);
189 	}
190 };
191 
192 typedef AutoLocker<rw_spinlock, ReadSpinLocking> ReadSpinLocker;
193 
194 
195 class InterruptsReadSpinLocking {
196 public:
197 	InterruptsReadSpinLocking()
198 		:
199 		fState(0)
200 	{
201 	}
202 
203 	inline bool Lock(rw_spinlock* lockable)
204 	{
205 		fState = disable_interrupts();
206 		acquire_read_spinlock(lockable);
207 		return true;
208 	}
209 
210 	inline void Unlock(rw_spinlock* lockable)
211 	{
212 		release_read_spinlock(lockable);
213 		restore_interrupts(fState);
214 	}
215 
216 private:
217 	int	fState;
218 };
219 
220 typedef AutoLocker<rw_spinlock, InterruptsReadSpinLocking>
221 	InterruptsReadSpinLocker;
222 
223 
224 class WriteSpinLocking {
225 public:
226 	inline bool Lock(rw_spinlock* lockable)
227 	{
228 		acquire_write_spinlock(lockable);
229 		return true;
230 	}
231 
232 	inline void Unlock(rw_spinlock* lockable)
233 	{
234 		release_write_spinlock(lockable);
235 	}
236 };
237 
238 typedef AutoLocker<rw_spinlock, WriteSpinLocking> WriteSpinLocker;
239 
240 
241 class InterruptsWriteSpinLocking {
242 public:
243 	InterruptsWriteSpinLocking()
244 		:
245 		fState(0)
246 	{
247 	}
248 
249 	inline bool Lock(rw_spinlock* lockable)
250 	{
251 		fState = disable_interrupts();
252 		acquire_write_spinlock(lockable);
253 		return true;
254 	}
255 
256 	inline void Unlock(rw_spinlock* lockable)
257 	{
258 		release_write_spinlock(lockable);
259 		restore_interrupts(fState);
260 	}
261 
262 private:
263 	int	fState;
264 };
265 
266 typedef AutoLocker<rw_spinlock, InterruptsWriteSpinLocking>
267 	InterruptsWriteSpinLocker;
268 
269 
270 class WriteSequentialLocking {
271 public:
272 	inline bool Lock(seqlock* lockable)
273 	{
274 		acquire_write_seqlock(lockable);
275 		return true;
276 	}
277 
278 	inline void Unlock(seqlock* lockable)
279 	{
280 		release_write_seqlock(lockable);
281 	}
282 };
283 
284 typedef AutoLocker<seqlock, WriteSequentialLocking> WriteSequentialLocker;
285 
286 
287 class InterruptsWriteSequentialLocking {
288 public:
289 	InterruptsWriteSequentialLocking()
290 		:
291 		fState(0)
292 	{
293 	}
294 
295 	inline bool Lock(seqlock* lockable)
296 	{
297 		fState = disable_interrupts();
298 		acquire_write_seqlock(lockable);
299 		return true;
300 	}
301 
302 	inline void Unlock(seqlock* lockable)
303 	{
304 		release_write_seqlock(lockable);
305 		restore_interrupts(fState);
306 	}
307 
308 private:
309 	int	fState;
310 };
311 
312 typedef AutoLocker<seqlock, InterruptsWriteSequentialLocking>
313 	InterruptsWriteSequentialLocker;
314 
315 
316 }	// namespace BPrivate
317 
318 using BPrivate::AutoLocker;
319 using BPrivate::MutexLocker;
320 using BPrivate::MutexTryLocker;
321 using BPrivate::RecursiveLocker;
322 using BPrivate::ReadLocker;
323 using BPrivate::WriteLocker;
324 using BPrivate::InterruptsLocker;
325 using BPrivate::SpinLocker;
326 using BPrivate::InterruptsSpinLocker;
327 using BPrivate::ReadSpinLocker;
328 using BPrivate::InterruptsReadSpinLocker;
329 using BPrivate::WriteSpinLocker;
330 using BPrivate::InterruptsWriteSpinLocker;
331 using BPrivate::WriteSequentialLocker;
332 using BPrivate::InterruptsWriteSequentialLocker;
333 
334 
335 #endif	// KERNEL_UTIL_AUTO_LOCKER_H
336