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