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