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