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 ThreadCPUPinLocking { 164 public: 165 inline bool Lock(Thread* thread) 166 { 167 thread_pin_to_current_cpu(thread); 168 return true; 169 } 170 171 inline void Unlock(Thread* thread) 172 { 173 thread_unpin_from_current_cpu(thread); 174 } 175 }; 176 177 typedef AutoLocker<Thread, ThreadCPUPinLocking> ThreadCPUPinner; 178 179 180 typedef AutoLocker<Team> TeamLocker; 181 typedef AutoLocker<Thread> ThreadLocker; 182 183 184 } // namespace BPrivate 185 186 using BPrivate::AutoLocker; 187 using BPrivate::MutexLocker; 188 using BPrivate::RecursiveLocker; 189 using BPrivate::ReadLocker; 190 using BPrivate::WriteLocker; 191 using BPrivate::InterruptsLocker; 192 using BPrivate::SpinLocker; 193 using BPrivate::InterruptsSpinLocker; 194 using BPrivate::ThreadCPUPinner; 195 using BPrivate::TeamLocker; 196 using BPrivate::ThreadLocker; 197 198 199 #endif // KERNEL_UTIL_AUTO_LOCKER_H 200