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 11extern "C" { 12#endif 13 14typedef 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 30void __mutex_init(mutex *lock, const char *name); 31void __mutex_init_etc(mutex *lock, const char *name, uint32 flags); 32void __mutex_destroy(mutex *lock); 33status_t __mutex_lock(mutex *lock); 34void __mutex_unlock(mutex *lock); 35 36 37typedef 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 60void __rw_lock_init(rw_lock *lock, const char *name); 61void __rw_lock_init_etc(rw_lock *lock, const char *name, uint32 flags); 62void __rw_lock_destroy(rw_lock *lock); 63status_t __rw_lock_read_lock(rw_lock *lock); 64status_t __rw_lock_read_unlock(rw_lock *lock); 65status_t __rw_lock_write_lock(rw_lock *lock); 66status_t __rw_lock_write_unlock(rw_lock *lock); 67 68 69typedef 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 86void __recursive_lock_init(recursive_lock *lock, const char *name); 87void __recursive_lock_init_etc(recursive_lock *lock, const char *name, 88 uint32 flags); 89void __recursive_lock_destroy(recursive_lock *lock); 90status_t __recursive_lock_lock(recursive_lock *lock); 91void __recursive_lock_unlock(recursive_lock *lock); 92int32 __recursive_lock_get_recursion(recursive_lock *lock); 93 94 95#define INIT_ONCE_UNINITIALIZED -1 96#define INIT_ONCE_INITIALIZED -4 97 98status_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 107class MutexLocking { 108public: 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 120typedef AutoLocker<mutex, MutexLocking> MutexLocker; 121 122 123class RecursiveLockLocking { 124public: 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 136typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker; 137 138 139class RWLockReadLocking { 140public: 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 153class RWLockWriteLocking { 154public: 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 167typedef AutoLocker<rw_lock, RWLockReadLocking> ReadLocker; 168typedef AutoLocker<rw_lock, RWLockWriteLocking> WriteLocker; 169 170#endif // __cplusplus 171 172#endif // _LOCKS_H_ 173