19 #ifndef _BOILERPLATE_LOCK_H
20 #define _BOILERPLATE_LOCK_H
23 #include <boilerplate/atomic.h>
24 #include <boilerplate/wrappers.h>
25 #include <boilerplate/ancillaries.h>
26 #include <boilerplate/debug.h>
46 #ifdef CONFIG_XENO_ASYNC_CANCEL
48 #define CANCEL_DEFER(__s) \
50 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, \
51 &(__s).cancel_type); \
54 #define CANCEL_RESTORE(__s) \
56 pthread_setcanceltype((__s).cancel_type, NULL); \
62 #define CANCEL_DEFER(__s) do { (void)(__s); } while (0)
64 #define CANCEL_RESTORE(__s) do { } while (0)
68 struct cleanup_block {
69 pthread_mutex_t *lock;
70 void (*handler)(
void *arg);
74 #define __push_cleanup_args(__cb, __lock, __fn, __arg) \
75 ((__cb)->lock = (__lock)), \
76 ((__cb)->handler = (void (*)(void *))(__fn)), \
77 ((__cb)->arg = (__arg))
79 #define push_cleanup_handler(__cb, __lock, __fn, __arg) \
80 pthread_cleanup_push((void (*)(void *))__run_cleanup_block, \
81 (__push_cleanup_args(__cb, __lock, __fn, __arg), (__cb)))
83 #define pop_cleanup_handler(__cb) \
84 pthread_cleanup_pop(0)
86 #define push_cleanup_lock(__lock) \
87 pthread_cleanup_push((void (*)(void *))__RT(pthread_mutex_unlock), (__lock))
89 #define pop_cleanup_lock(__lock) \
90 pthread_cleanup_pop(0)
92 #ifdef CONFIG_XENO_DEBUG
93 int __check_cancel_type(
const char *locktype);
95 #define __check_cancel_type(__locktype) \
96 ({ (void)__locktype; 0; })
99 #define __do_lock(__lock, __op) \
102 __ret = -__RT(pthread_mutex_##__op(__lock)); \
106 #define __do_lock_nocancel(__lock, __type, __op) \
108 __bt(__check_cancel_type(#__op "_nocancel")); \
109 __do_lock(__lock, __op); \
112 #define __do_unlock(__lock) \
115 __ret = -__RT(pthread_mutex_unlock(__lock)); \
137 #define read_lock(__lock) \
138 __do_lock(__lock, lock)
140 #define read_trylock(__lock) \
141 __do_lock(__lock, trylock)
143 #define read_lock_nocancel(__lock) \
144 __do_lock_nocancel(__lock, read_lock, lock)
146 #define read_trylock_nocancel(__lock) \
147 __do_lock_nocancel(__lock, read_trylock, trylock)
149 #define read_unlock(__lock) \
152 #define write_lock(__lock) \
153 __do_lock(__lock, lock)
155 #define write_trylock(__lock) \
156 __do_lock(__lock, trylock)
158 #define write_lock_nocancel(__lock) \
159 __do_lock_nocancel(__lock, write_lock, lock)
161 #define write_trylock_nocancel(__lock) \
162 __do_lock_nocancel(__lock, write_trylock, trylock)
164 #define write_unlock(__lock) \
167 #define __do_lock_safe(__lock, __state, __op) \
169 int __ret, __oldstate; \
170 __bt(__check_cancel_type(#__op "_safe")); \
171 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &__oldstate); \
172 __ret = -__RT(pthread_mutex_##__op(__lock)); \
174 pthread_setcancelstate(__oldstate, NULL); \
175 __state = __oldstate; \
179 #define __do_unlock_safe(__lock, __state) \
181 int __ret, __restored_state = __state; \
182 __ret = -__RT(pthread_mutex_unlock(__lock)); \
183 pthread_setcancelstate(__restored_state, NULL); \
195 #define write_lock_safe(__lock, __state) \
196 __do_lock_safe(__lock, __state, lock)
198 #define write_trylock_safe(__lock, __state) \
199 __do_lock_safe(__lock, __state, trylock)
201 #define write_unlock_safe(__lock, __state) \
202 __do_unlock_safe(__lock, __state)
204 #define read_lock_safe(__lock, __state) \
205 __do_lock_safe(__lock, __state, lock)
207 #define read_unlock_safe(__lock, __state) \
208 __do_unlock_safe(__lock, __state)
210 #ifdef CONFIG_XENO_DEBUG
211 #define mutex_type_attribute PTHREAD_MUTEX_ERRORCHECK
213 #define mutex_type_attribute PTHREAD_MUTEX_NORMAL