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