1 /* 2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _LOCKS_H_ 6 #define _LOCKS_H_ 7 8 #include <OS.h> 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 typedef struct mutex { 15 const char* name; 16 int32 lock; 17 uint32 flags; 18 } mutex; 19 20 #define MUTEX_FLAG_CLONE_NAME 0x1 21 #define MUTEX_FLAG_ADAPTIVE 0x2 22 #define MUTEX_INITIALIZER(name) { name, 0, 0 } 23 24 #define mutex_init(lock, name) __mutex_init(lock, name) 25 #define mutex_init_etc(lock, name, flags) __mutex_init_etc(lock, name, flags) 26 #define mutex_destroy(lock) __mutex_destroy(lock) 27 #define mutex_lock(lock) __mutex_lock(lock) 28 #define mutex_unlock(lock) __mutex_unlock(lock) 29 30 void __mutex_init(mutex *lock, const char *name); 31 void __mutex_init_etc(mutex *lock, const char *name, uint32 flags); 32 void __mutex_destroy(mutex *lock); 33 status_t __mutex_lock(mutex *lock); 34 void __mutex_unlock(mutex *lock); 35 36 37 typedef struct rw_lock { 38 mutex lock; 39 struct rw_lock_waiter * waiters; 40 struct rw_lock_waiter * last_waiter; 41 thread_id holder; 42 int32 reader_count; 43 int32 writer_count; 44 int32 owner_count; 45 } rw_lock; 46 47 #define RW_LOCK_FLAG_CLONE_NAME MUTEX_FLAG_CLONE_NAME 48 #define RW_LOCK_INITIALIZER(name) { MUTEX_INITIALIZER(name), NULL, \ 49 NULL, -1, 0, 0, 0 } 50 51 #define rw_lock_init(lock, name) __rw_lock_init(lock, name) 52 #define rw_lock_init_etc(lock, name, flags) \ 53 __rw_lock_init_etc(lock, name, flags) 54 #define rw_lock_destroy(lock) __rw_lock_destroy(lock) 55 #define rw_lock_read_lock(lock) __rw_lock_read_lock(lock) 56 #define rw_lock_read_unlock(lock) __rw_lock_read_unlock(lock) 57 #define rw_lock_write_lock(lock) __rw_lock_write_lock(lock) 58 #define rw_lock_write_unlock(lock) __rw_lock_write_unlock(lock) 59 60 void __rw_lock_init(rw_lock *lock, const char *name); 61 void __rw_lock_init_etc(rw_lock *lock, const char *name, uint32 flags); 62 void __rw_lock_destroy(rw_lock *lock); 63 status_t __rw_lock_read_lock(rw_lock *lock); 64 status_t __rw_lock_read_unlock(rw_lock *lock); 65 status_t __rw_lock_write_lock(rw_lock *lock); 66 status_t __rw_lock_write_unlock(rw_lock *lock); 67 68 69 typedef struct recursive_lock { 70 mutex lock; 71 thread_id holder; 72 int32 recursion; 73 } recursive_lock; 74 75 #define RECURSIVE_LOCK_FLAG_CLONE_NAME MUTEX_FLAG_CLONE_NAME 76 #define RECURSIVE_LOCK_INITIALIZER(name) { MUTEX_INITIALIZER(name), -1, 0 } 77 78 #define recursive_lock_init(lock, name) __recursive_lock_init(lock, name) 79 #define recursive_lock_init_etc(lock, name, flags) \ 80 __recursive_lock_init_etc(lock, name, flags) 81 #define recursive_lock_destroy(lock) __recursive_lock_destroy(lock) 82 #define recursive_lock_lock(lock) __recursive_lock_lock(lock) 83 #define recursive_lock_unlock(lock) __recursive_lock_unlock(lock) 84 #define recursive_lock_get_recursion(lock) __recursive_lock_get_recursion(lock) 85 86 void __recursive_lock_init(recursive_lock *lock, const char *name); 87 void __recursive_lock_init_etc(recursive_lock *lock, const char *name, 88 uint32 flags); 89 void __recursive_lock_destroy(recursive_lock *lock); 90 status_t __recursive_lock_lock(recursive_lock *lock); 91 void __recursive_lock_unlock(recursive_lock *lock); 92 int32 __recursive_lock_get_recursion(recursive_lock *lock); 93 94 95 #define INIT_ONCE_UNINITIALIZED -1 96 #define INIT_ONCE_INITIALIZED -4 97 98 status_t __init_once(int32* control, status_t (*initRoutine)(void*), 99 void* data); 100 101 #ifdef __cplusplus 102 } // extern "C" 103 104 105 #include <AutoLocker.h> 106 107 class MutexLocking { 108 public: 109 inline bool Lock(struct mutex *lock) 110 { 111 return mutex_lock(lock) == B_OK; 112 } 113 114 inline void Unlock(struct mutex *lock) 115 { 116 mutex_unlock(lock); 117 } 118 }; 119 120 typedef AutoLocker<mutex, MutexLocking> MutexLocker; 121 122 123 class RecursiveLockLocking { 124 public: 125 inline bool Lock(recursive_lock *lockable) 126 { 127 return recursive_lock_lock(lockable) == B_OK; 128 } 129 130 inline void Unlock(recursive_lock *lockable) 131 { 132 recursive_lock_unlock(lockable); 133 } 134 }; 135 136 typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker; 137 138 139 class RWLockReadLocking { 140 public: 141 inline bool Lock(struct rw_lock *lock) 142 { 143 return rw_lock_read_lock(lock) == B_OK; 144 } 145 146 inline void Unlock(struct rw_lock *lock) 147 { 148 rw_lock_read_unlock(lock); 149 } 150 }; 151 152 153 class RWLockWriteLocking { 154 public: 155 inline bool Lock(struct rw_lock *lock) 156 { 157 return rw_lock_write_lock(lock) == B_OK; 158 } 159 160 inline void Unlock(struct rw_lock *lock) 161 { 162 rw_lock_write_unlock(lock); 163 } 164 }; 165 166 167 typedef AutoLocker<rw_lock, RWLockReadLocking> ReadLocker; 168 typedef AutoLocker<rw_lock, RWLockWriteLocking> WriteLocker; 169 170 #endif // __cplusplus 171 172 #endif // _LOCKS_H_ 173