xref: /haiku/headers/private/kernel/util/AutoLock.h (revision ddac407426cd3b3d0b4589d7a161b300b3539a2a)
1 /*
2  * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
3  * Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved.
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 // MutexLocking
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 // MutexLocker
37 typedef AutoLocker<mutex, MutexLocking> MutexLocker;
38 
39 // RecursiveLockLocking
40 class RecursiveLockLocking {
41 public:
42 	inline bool Lock(recursive_lock *lockable)
43 	{
44 		return recursive_lock_lock(lockable) == B_OK;
45 	}
46 
47 	inline void Unlock(recursive_lock *lockable)
48 	{
49 		recursive_lock_unlock(lockable);
50 	}
51 };
52 
53 // RecursiveLocker
54 typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker;
55 
56 class ReadWriteLockReadLocking {
57 public:
58 	inline bool Lock(rw_lock *lockable)
59 	{
60 		return rw_lock_read_lock(lockable) == B_OK;
61 	}
62 
63 	inline void Unlock(rw_lock *lockable)
64 	{
65 		rw_lock_read_unlock(lockable);
66 	}
67 };
68 
69 class ReadWriteLockWriteLocking {
70 public:
71 	inline bool Lock(rw_lock *lockable)
72 	{
73 		return rw_lock_write_lock(lockable) == B_OK;
74 	}
75 
76 	inline void Unlock(rw_lock *lockable)
77 	{
78 		rw_lock_write_unlock(lockable);
79 	}
80 };
81 
82 typedef AutoLocker<rw_lock, ReadWriteLockReadLocking> ReadLocker;
83 typedef AutoLocker<rw_lock, ReadWriteLockWriteLocking> WriteLocker;
84 
85 // InterruptsLocking
86 class InterruptsLocking {
87 public:
88 	inline bool Lock(int* lockable)
89 	{
90 		*lockable = disable_interrupts();
91 		return true;
92 	}
93 
94 	inline void Unlock(int* lockable)
95 	{
96 		restore_interrupts(*lockable);
97 	}
98 };
99 
100 // InterruptsLocker
101 class InterruptsLocker : public AutoLocker<int, InterruptsLocking> {
102 public:
103 	inline InterruptsLocker(bool alreadyLocked = false,
104 		bool lockIfNotLocked = true)
105 		: AutoLocker<int, InterruptsLocking>(&fState, alreadyLocked,
106 			lockIfNotLocked)
107 	{
108 	}
109 
110 private:
111 	int	fState;
112 };
113 
114 // SpinLocking
115 class SpinLocking {
116 public:
117 	inline bool Lock(spinlock* lockable)
118 	{
119 		acquire_spinlock(lockable);
120 		return true;
121 	}
122 
123 	inline void Unlock(spinlock* lockable)
124 	{
125 		release_spinlock(lockable);
126 	}
127 };
128 
129 // SpinLocker
130 typedef AutoLocker<spinlock, SpinLocking> SpinLocker;
131 
132 // InterruptsSpinLocking
133 class InterruptsSpinLocking {
134 public:
135 // NOTE: work-around for annoying GCC 4 "fState may be used uninitialized"
136 // warning.
137 #if __GNUC__ == 4
138 	InterruptsSpinLocking()
139 		:
140 		fState(0)
141 	{
142 	}
143 #endif
144 
145 	inline bool Lock(spinlock* lockable)
146 	{
147 		fState = disable_interrupts();
148 		acquire_spinlock(lockable);
149 		return true;
150 	}
151 
152 	inline void Unlock(spinlock* lockable)
153 	{
154 		release_spinlock(lockable);
155 		restore_interrupts(fState);
156 	}
157 
158 private:
159 	int	fState;
160 };
161 
162 // InterruptsSpinLocker
163 typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker;
164 
165 // ThreadCPUPinLocking
166 class ThreadCPUPinLocking {
167 public:
168 	inline bool Lock(struct thread* thread)
169 	{
170 		thread_pin_to_current_cpu(thread);
171 		return true;
172 	}
173 
174 	inline void Unlock(struct thread* thread)
175 	{
176 		thread_unpin_from_current_cpu(thread);
177 	}
178 };
179 
180 // MutexLocker
181 typedef AutoLocker<struct thread, ThreadCPUPinLocking> ThreadCPUPinner;
182 
183 }	// namespace BPrivate
184 
185 using BPrivate::AutoLocker;
186 using BPrivate::MutexLocker;
187 using BPrivate::RecursiveLocker;
188 using BPrivate::ReadLocker;
189 using BPrivate::WriteLocker;
190 using BPrivate::InterruptsLocker;
191 using BPrivate::SpinLocker;
192 using BPrivate::InterruptsSpinLocker;
193 using BPrivate::ThreadCPUPinner;
194 
195 #endif	// KERNEL_UTIL_AUTO_LOCKER_H
196