19 #ifndef _BOILERPLATE_LOCK_H
20 #define _BOILERPLATE_LOCK_H
23 #include <boilerplate/atomic.h>
24 #include <boilerplate/wrappers.h>
25 #include <boilerplate/debug.h>
45 #ifdef CONFIG_XENO_ASYNC_CANCEL
47 #define CANCEL_DEFER(__s) \
49 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, \
50 &(__s).cancel_type); \
53 #define CANCEL_RESTORE(__s) \
55 pthread_setcanceltype((__s).cancel_type, NULL); \
61 #define CANCEL_DEFER(__s) do { (void)(__s); } while (0)
63 #define CANCEL_RESTORE(__s) do { } while (0)
67 struct cleanup_block {
68 pthread_mutex_t *lock;
69 void (*handler)(
void *arg);
73 #define __push_cleanup_args(__cb, __lock, __fn, __arg) \
74 ((__cb)->lock = (__lock)), \
75 ((__cb)->handler = (void (*)(void *))(__fn)), \
76 ((__cb)->arg = (__arg))
78 #define push_cleanup_handler(__cb, __lock, __fn, __arg) \
79 pthread_cleanup_push((void (*)(void *))__run_cleanup_block, \
80 (__push_cleanup_args(__cb, __lock, __fn, __arg), (__cb)))
82 #define pop_cleanup_handler(__cb) \
83 pthread_cleanup_pop(0)
85 #define push_cleanup_lock(__lock) \
86 pthread_cleanup_push((void (*)(void *))__RT(pthread_mutex_unlock), (__lock))
88 #define pop_cleanup_lock(__lock) \
89 pthread_cleanup_pop(0)
91 #ifdef CONFIG_XENO_DEBUG
92 int __check_cancel_type(
const char *locktype);
94 #define __check_cancel_type(__locktype) \
95 ({ (void)__locktype; 0; })
98 #define __do_lock(__lock, __op) \
101 __ret = -__RT(pthread_mutex_##__op(__lock)); \
105 #define __do_lock_nocancel(__lock, __type, __op) \
107 __bt(__check_cancel_type(#__op "_nocancel")); \
108 __do_lock(__lock, __op); \
111 #define __do_unlock(__lock) \
114 __ret = -__RT(pthread_mutex_unlock(__lock)); \
136 #define read_lock(__lock) \
137 __do_lock(__lock, lock)
139 #define read_trylock(__lock) \
140 __do_lock(__lock, trylock)
142 #define read_lock_nocancel(__lock) \
143 __do_lock_nocancel(__lock, read_lock, lock)
145 #define read_trylock_nocancel(__lock) \
146 __do_lock_nocancel(__lock, read_trylock, trylock)
148 #define read_unlock(__lock) \
151 #define write_lock(__lock) \
152 __do_lock(__lock, lock)
154 #define write_trylock(__lock) \
155 __do_lock(__lock, trylock)
157 #define write_lock_nocancel(__lock) \
158 __do_lock_nocancel(__lock, write_lock, lock)
160 #define write_trylock_nocancel(__lock) \
161 __do_lock_nocancel(__lock, write_trylock, trylock)
163 #define write_unlock(__lock) \
166 #define __do_lock_safe(__lock, __state, __op) \
168 int __ret, __oldstate; \
169 __bt(__check_cancel_type(#__op "_safe")); \
170 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &__oldstate); \
171 __ret = -__RT(pthread_mutex_##__op(__lock)); \
173 pthread_setcancelstate(__oldstate, NULL); \
174 __state = __oldstate; \
178 #define __do_unlock_safe(__lock, __state) \
180 int __ret, __restored_state = __state; \
181 __ret = -__RT(pthread_mutex_unlock(__lock)); \
182 pthread_setcancelstate(__restored_state, NULL); \
194 #define write_lock_safe(__lock, __state) \
195 __do_lock_safe(__lock, __state, lock)
197 #define write_trylock_safe(__lock, __state) \
198 __do_lock_safe(__lock, __state, trylock)
200 #define write_unlock_safe(__lock, __state) \
201 __do_unlock_safe(__lock, __state)
203 #define read_lock_safe(__lock, __state) \
204 __do_lock_safe(__lock, __state, lock)
206 #define read_unlock_safe(__lock, __state) \
207 __do_unlock_safe(__lock, __state)
209 #ifdef CONFIG_XENO_DEBUG
210 #define mutex_type_attribute PTHREAD_MUTEX_ERRORCHECK
212 #define mutex_type_attribute PTHREAD_MUTEX_NORMAL