19 #ifndef _BOILERPLATE_LOCK_H
20 #define _BOILERPLATE_LOCK_H
23 #include <boilerplate/wrappers.h>
24 #include <boilerplate/debug.h>
44 #ifdef CONFIG_XENO_ASYNC_CANCEL
46 #define CANCEL_DEFER(__s) \
48 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, \
49 &(__s).cancel_type); \
52 #define CANCEL_RESTORE(__s) \
54 pthread_setcanceltype((__s).cancel_type, NULL); \
60 #define CANCEL_DEFER(__s) do { (void)(__s); } while (0)
62 #define CANCEL_RESTORE(__s) do { } while (0)
66 struct cleanup_block {
67 pthread_mutex_t *lock;
68 void (*handler)(
void *arg);
72 #define __push_cleanup_args(__cb, __lock, __fn, __arg) \
73 ((__cb)->lock = (__lock)), \
74 ((__cb)->handler = (void (*)(void *))(__fn)), \
75 ((__cb)->arg = (__arg))
77 #define push_cleanup_handler(__cb, __lock, __fn, __arg) \
78 pthread_cleanup_push((void (*)(void *))__run_cleanup_block, \
79 (__push_cleanup_args(__cb, __lock, __fn, __arg), (__cb)))
81 #define pop_cleanup_handler(__cb) \
82 pthread_cleanup_pop(0)
84 #define push_cleanup_lock(__lock) \
85 pthread_cleanup_push((void (*)(void *))__RT(pthread_mutex_unlock), (__lock))
87 #define pop_cleanup_lock(__lock) \
88 pthread_cleanup_pop(0)
90 #ifdef CONFIG_XENO_DEBUG
91 int __check_cancel_type(
const char *locktype);
93 #define __check_cancel_type(__locktype) \
94 ({ (void)__locktype; 0; })
97 #define __do_lock(__lock, __op) \
100 __ret = -__RT(pthread_mutex_##__op(__lock)); \
104 #define __do_lock_nocancel(__lock, __type, __op) \
106 __bt(__check_cancel_type(#__op "_nocancel")); \
107 __do_lock(__lock, __op); \
110 #define __do_unlock(__lock) \
113 __ret = -__RT(pthread_mutex_unlock(__lock)); \
135 #define read_lock(__lock) \
136 __do_lock(__lock, lock)
138 #define read_trylock(__lock) \
139 __do_lock(__lock, trylock)
141 #define read_lock_nocancel(__lock) \
142 __do_lock_nocancel(__lock, read_lock, lock)
144 #define read_trylock_nocancel(__lock) \
145 __do_lock_nocancel(__lock, read_trylock, trylock)
147 #define read_unlock(__lock) \
150 #define write_lock(__lock) \
151 __do_lock(__lock, lock)
153 #define write_trylock(__lock) \
154 __do_lock(__lock, trylock)
156 #define write_lock_nocancel(__lock) \
157 __do_lock_nocancel(__lock, write_lock, lock)
159 #define write_trylock_nocancel(__lock) \
160 __do_lock_nocancel(__lock, write_trylock, trylock)
162 #define write_unlock(__lock) \
165 #define __do_lock_safe(__lock, __state, __op) \
167 int __ret, __oldstate; \
168 __bt(__check_cancel_type(#__op "_safe")); \
169 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &__oldstate); \
170 __ret = -__RT(pthread_mutex_##__op(__lock)); \
172 pthread_setcancelstate(__oldstate, NULL); \
173 __state = __oldstate; \
177 #define __do_unlock_safe(__lock, __state) \
179 int __ret, __restored_state = __state; \
180 __ret = -__RT(pthread_mutex_unlock(__lock)); \
181 pthread_setcancelstate(__restored_state, NULL); \
193 #define write_lock_safe(__lock, __state) \
194 __do_lock_safe(__lock, __state, lock)
196 #define write_trylock_safe(__lock, __state) \
197 __do_lock_safe(__lock, __state, trylock)
199 #define write_unlock_safe(__lock, __state) \
200 __do_unlock_safe(__lock, __state)
202 #define read_lock_safe(__lock, __state) \
203 __do_lock_safe(__lock, __state, lock)
205 #define read_unlock_safe(__lock, __state) \
206 __do_unlock_safe(__lock, __state)
208 #ifdef CONFIG_XENO_DEBUG
209 #define mutex_type_attribute PTHREAD_MUTEX_ERRORCHECK
211 #define mutex_type_attribute PTHREAD_MUTEX_NORMAL
218 void __run_cleanup_block(
struct cleanup_block *cb);