1 /* 2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. 3 * Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. 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 // MutexLocking 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 // MutexLocker 37 typedef AutoLocker<mutex, MutexLocking> MutexLocker; 38 39 // RecursiveLockLocking 40 class RecursiveLockLocking { 41 public: 42 inline bool Lock(recursive_lock *lockable) 43 { 44 return recursive_lock_lock(lockable) == B_OK; 45 } 46 47 inline void Unlock(recursive_lock *lockable) 48 { 49 recursive_lock_unlock(lockable); 50 } 51 }; 52 53 // RecursiveLocker 54 typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker; 55 56 class ReadWriteLockReadLocking { 57 public: 58 inline bool Lock(rw_lock *lockable) 59 { 60 return rw_lock_read_lock(lockable) == B_OK; 61 } 62 63 inline void Unlock(rw_lock *lockable) 64 { 65 rw_lock_read_unlock(lockable); 66 } 67 }; 68 69 class ReadWriteLockWriteLocking { 70 public: 71 inline bool Lock(rw_lock *lockable) 72 { 73 return rw_lock_write_lock(lockable) == B_OK; 74 } 75 76 inline void Unlock(rw_lock *lockable) 77 { 78 rw_lock_write_unlock(lockable); 79 } 80 }; 81 82 typedef AutoLocker<rw_lock, ReadWriteLockReadLocking> ReadLocker; 83 typedef AutoLocker<rw_lock, ReadWriteLockWriteLocking> WriteLocker; 84 85 // InterruptsLocking 86 class InterruptsLocking { 87 public: 88 inline bool Lock(int* lockable) 89 { 90 *lockable = disable_interrupts(); 91 return true; 92 } 93 94 inline void Unlock(int* lockable) 95 { 96 restore_interrupts(*lockable); 97 } 98 }; 99 100 // InterruptsLocker 101 class InterruptsLocker : public AutoLocker<int, InterruptsLocking> { 102 public: 103 inline InterruptsLocker(bool alreadyLocked = false, 104 bool lockIfNotLocked = true) 105 : AutoLocker<int, InterruptsLocking>(&fState, alreadyLocked, 106 lockIfNotLocked) 107 { 108 } 109 110 private: 111 int fState; 112 }; 113 114 // SpinLocking 115 class SpinLocking { 116 public: 117 inline bool Lock(spinlock* lockable) 118 { 119 acquire_spinlock(lockable); 120 return true; 121 } 122 123 inline void Unlock(spinlock* lockable) 124 { 125 release_spinlock(lockable); 126 } 127 }; 128 129 // SpinLocker 130 typedef AutoLocker<spinlock, SpinLocking> SpinLocker; 131 132 // InterruptsSpinLocking 133 class InterruptsSpinLocking { 134 public: 135 // NOTE: work-around for annoying GCC 4 "fState may be used uninitialized" 136 // warning. 137 #if __GNUC__ == 4 138 InterruptsSpinLocking() 139 : 140 fState(0) 141 { 142 } 143 #endif 144 145 inline bool Lock(spinlock* lockable) 146 { 147 fState = disable_interrupts(); 148 acquire_spinlock(lockable); 149 return true; 150 } 151 152 inline void Unlock(spinlock* lockable) 153 { 154 release_spinlock(lockable); 155 restore_interrupts(fState); 156 } 157 158 private: 159 int fState; 160 }; 161 162 // InterruptsSpinLocker 163 typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker; 164 165 // ThreadCPUPinLocking 166 class ThreadCPUPinLocking { 167 public: 168 inline bool Lock(struct thread* thread) 169 { 170 thread_pin_to_current_cpu(thread); 171 return true; 172 } 173 174 inline void Unlock(struct thread* thread) 175 { 176 thread_unpin_from_current_cpu(thread); 177 } 178 }; 179 180 // MutexLocker 181 typedef AutoLocker<struct thread, ThreadCPUPinLocking> ThreadCPUPinner; 182 183 } // namespace BPrivate 184 185 using BPrivate::AutoLocker; 186 using BPrivate::MutexLocker; 187 using BPrivate::RecursiveLocker; 188 using BPrivate::ReadLocker; 189 using BPrivate::WriteLocker; 190 using BPrivate::InterruptsLocker; 191 using BPrivate::SpinLocker; 192 using BPrivate::InterruptsSpinLocker; 193 using BPrivate::ThreadCPUPinner; 194 195 #endif // KERNEL_UTIL_AUTO_LOCKER_H 196