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