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_