AutoLock.h revision 94887feb
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
20namespace BPrivate {
21
22
23class MutexLocking {
24public:
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
36typedef AutoLocker<mutex, MutexLocking> MutexLocker;
37
38
39class RecursiveLockLocking {
40public:
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
52typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker;
53
54
55class ReadWriteLockReadLocking {
56public:
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
68class ReadWriteLockWriteLocking {
69public:
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
81typedef AutoLocker<rw_lock, ReadWriteLockReadLocking> ReadLocker;
82typedef AutoLocker<rw_lock, ReadWriteLockWriteLocking> WriteLocker;
83
84
85class InterruptsLocking {
86public:
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
100class InterruptsLocker : public AutoLocker<int, InterruptsLocking> {
101public:
102	inline InterruptsLocker(bool alreadyLocked = false,
103		bool lockIfNotLocked = true)
104		: AutoLocker<int, InterruptsLocking>(&fState, alreadyLocked,
105			lockIfNotLocked)
106	{
107	}
108
109private:
110	int	fState;
111};
112
113
114class SpinLocking {
115public:
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
128typedef AutoLocker<spinlock, SpinLocking> SpinLocker;
129
130
131class InterruptsSpinLocking {
132public:
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
156private:
157	int	fState;
158};
159
160typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker;
161
162
163class ReadSpinLocking {
164public:
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
177typedef AutoLocker<rw_spinlock, ReadSpinLocking> ReadSpinLocker;
178
179
180class InterruptsReadSpinLocking {
181public:
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
201private:
202	int	fState;
203};
204
205typedef AutoLocker<rw_spinlock, InterruptsReadSpinLocking>
206	InterruptsReadSpinLocker;
207
208
209class WriteSpinLocking {
210public:
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
223typedef AutoLocker<rw_spinlock, WriteSpinLocking> WriteSpinLocker;
224
225
226class InterruptsWriteSpinLocking {
227public:
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
247private:
248	int	fState;
249};
250
251typedef AutoLocker<rw_spinlock, InterruptsWriteSpinLocking>
252	InterruptsWriteSpinLocker;
253
254
255class WriteSequentialLocking {
256public:
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
269typedef AutoLocker<seqlock, WriteSequentialLocking> WriteSequentialLocker;
270
271
272class InterruptsWriteSequentialLocking {
273public:
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
293private:
294	int	fState;
295};
296
297typedef AutoLocker<seqlock, InterruptsWriteSequentialLocking>
298	InterruptsWriteSequentialLocker;
299
300
301class ThreadCPUPinLocking {
302public:
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
315typedef AutoLocker<Thread, ThreadCPUPinLocking> ThreadCPUPinner;
316
317
318typedef AutoLocker<Team> TeamLocker;
319typedef AutoLocker<Thread> ThreadLocker;
320
321
322}	// namespace BPrivate
323
324using BPrivate::AutoLocker;
325using BPrivate::MutexLocker;
326using BPrivate::RecursiveLocker;
327using BPrivate::ReadLocker;
328using BPrivate::WriteLocker;
329using BPrivate::InterruptsLocker;
330using BPrivate::SpinLocker;
331using BPrivate::InterruptsSpinLocker;
332using BPrivate::ReadSpinLocker;
333using BPrivate::InterruptsReadSpinLocker;
334using BPrivate::WriteSpinLocker;
335using BPrivate::InterruptsWriteSpinLocker;
336using BPrivate::WriteSequentialLocker;
337using BPrivate::InterruptsWriteSequentialLocker;
338using BPrivate::ThreadCPUPinner;
339using BPrivate::TeamLocker;
340using BPrivate::ThreadLocker;
341
342
343#endif	// KERNEL_UTIL_AUTO_LOCKER_H
344