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 19namespace BPrivate { 20 21 22class MutexLocking { 23public: 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 35typedef AutoLocker<mutex, MutexLocking> MutexLocker; 36 37 38class RecursiveLockLocking { 39public: 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 51typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker; 52 53 54class ReadWriteLockReadLocking { 55public: 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 67class ReadWriteLockWriteLocking { 68public: 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 80typedef AutoLocker<rw_lock, ReadWriteLockReadLocking> ReadLocker; 81typedef AutoLocker<rw_lock, ReadWriteLockWriteLocking> WriteLocker; 82 83 84class InterruptsLocking { 85public: 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 99class InterruptsLocker : public AutoLocker<int, InterruptsLocking> { 100public: 101 inline InterruptsLocker(bool alreadyLocked = false, 102 bool lockIfNotLocked = true) 103 : AutoLocker<int, InterruptsLocking>(&fState, alreadyLocked, 104 lockIfNotLocked) 105 { 106 } 107 108private: 109 int fState; 110}; 111 112 113class SpinLocking { 114public: 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 127typedef AutoLocker<spinlock, SpinLocking> SpinLocker; 128 129 130class InterruptsSpinLocking { 131public: 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 155private: 156 int fState; 157}; 158 159typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker; 160 161 162class ReadSpinLocking { 163public: 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 176typedef AutoLocker<rw_spinlock, ReadSpinLocking> ReadSpinLocker; 177 178 179class InterruptsReadSpinLocking { 180public: 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 200private: 201 int fState; 202}; 203 204typedef AutoLocker<rw_spinlock, InterruptsReadSpinLocking> 205 InterruptsReadSpinLocker; 206 207 208class WriteSpinLocking { 209public: 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 222typedef AutoLocker<rw_spinlock, WriteSpinLocking> WriteSpinLocker; 223 224 225class InterruptsWriteSpinLocking { 226public: 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 246private: 247 int fState; 248}; 249 250typedef AutoLocker<rw_spinlock, InterruptsWriteSpinLocking> 251 InterruptsWriteSpinLocker; 252 253 254class WriteSequentialLocking { 255public: 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 268typedef AutoLocker<seqlock, WriteSequentialLocking> WriteSequentialLocker; 269 270 271class InterruptsWriteSequentialLocking { 272public: 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 292private: 293 int fState; 294}; 295 296typedef AutoLocker<seqlock, InterruptsWriteSequentialLocking> 297 InterruptsWriteSequentialLocker; 298 299 300} // namespace BPrivate 301 302using BPrivate::AutoLocker; 303using BPrivate::MutexLocker; 304using BPrivate::RecursiveLocker; 305using BPrivate::ReadLocker; 306using BPrivate::WriteLocker; 307using BPrivate::InterruptsLocker; 308using BPrivate::SpinLocker; 309using BPrivate::InterruptsSpinLocker; 310using BPrivate::ReadSpinLocker; 311using BPrivate::InterruptsReadSpinLocker; 312using BPrivate::WriteSpinLocker; 313using BPrivate::InterruptsWriteSpinLocker; 314using BPrivate::WriteSequentialLocker; 315using BPrivate::InterruptsWriteSequentialLocker; 316 317 318#endif // KERNEL_UTIL_AUTO_LOCKER_H 319