18#ifndef COAP_MUTEX_INTERNAL_H_
19#define COAP_MUTEX_INTERNAL_H_
27#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
32#define coap_mutex_init(a) pthread_mutex_init(a, NULL)
33#define coap_mutex_destroy(a) pthread_mutex_destroy(a)
34#define coap_mutex_lock(a) pthread_mutex_lock(a)
35#define coap_mutex_trylock(a) pthread_mutex_trylock(a)
36#define coap_mutex_unlock(a) pthread_mutex_unlock(a)
37#define coap_thread_pid_t pthread_t
38#define coap_thread_pid pthread_self()
40#elif defined(RIOT_VERSION)
46#define coap_mutex_init(a) mutex_init(a)
47#define coap_mutex_destroy(a)
48#define coap_mutex_lock(a) mutex_lock(a)
49#define coap_mutex_trylock(a) mutex_trylock(a)
50#define coap_mutex_unlock(a) mutex_unlock(a)
51#define coap_thread_pid_t kernel_pid_t
52#define coap_thread_pid thread_getpid()
54#elif defined(WITH_LWIP)
59#error Multi-threading not supported (no mutex support)
64#define coap_mutex_init(a) *(a) = 0
65#define coap_mutex_destroy(a) *(a) = 0
66#define coap_mutex_lock(a) *(a) = 1
67#define coap_mutex_trylock(a) *(a) = 1
68#define coap_mutex_unlock(a) *(a) = 0
69#define coap_thread_pid_t int
70#define coap_thread_pid 1
78#define coap_mutex_init(a) pthread_mutex_init(a, NULL)
79#define coap_mutex_destroy(a) pthread_mutex_destroy(a)
80#define coap_mutex_lock(a) pthread_mutex_lock(a)
81#define coap_mutex_trylock(a) pthread_mutex_trylock(a)
82#define coap_mutex_unlock(a) pthread_mutex_unlock(a)
83#define coap_thread_pid_t pthread_t
84#define coap_thread_pid pthread_self()
88#define coap_mutex_init(a) sys_mutex_new(a)
89#define coap_mutex_destroy(a) sys_mutex_set_invalid(a)
90#define coap_mutex_lock(a) sys_mutex_lock(a)
91#define coap_mutex_unlock(a) sys_mutex_unlock(a)
92#define coap_thread_pid_t sys_thread_t
93#define coap_thread_pid (coap_thread_pid_t)1
95#if COAP_THREAD_RECURSIVE_CHECK
96#error COAP_THREAD_RECURSIVE_CHECK not supported (no coap_mutex_trylock())
101#elif defined(WITH_CONTIKI)
103#error Multi-threading not supported (no mutex support)
108#define coap_mutex_init(a) *(a) = 0
109#define coap_mutex_destroy(a) *(a) = 0
110#define coap_mutex_lock(a) *(a) = 1
111#define coap_mutex_trylock(a) *(a) = 1
112#define coap_mutex_unlock(a) *(a) = 0
113#define coap_thread_pid_t int
114#define coap_thread_pid 1
116#elif defined(__ZEPHYR__)
117#include <zephyr/sys/mutex.h>
121#define coap_mutex_init(a) sys_mutex_init(a)
122#define coap_mutex_destroy(a)
123#define coap_mutex_lock(a) sys_mutex_lock(a, K_FOREVER)
124#define coap_mutex_trylock(a) sys_mutex_lock(a, K_NO_WAIT)
125#define coap_mutex_unlock(a) sys_mutex_unlock(a)
130#error Multi-threading not supported (no mutex support)
132#if COAP_CONSTRAINED_STACK
133#warning "stub mutex functions"
138#define coap_mutex_init(a) *(a) = 0
139#define coap_mutex_destroy(a) *(a) = 0
140#define coap_mutex_lock(a) *(a) = 1
141#define coap_mutex_trylock(a) *(a) = 1
142#define coap_mutex_unlock(a) *(a) = 0
143#define coap_thread_pid_t int
144#define coap_thread_pid 1
148#if COAP_CONSTRAINED_STACK
205# if COAP_THREAD_RECURSIVE_CHECK
214 const char *lock_file;
215 unsigned int lock_line;
216 unsigned int unlock_line;
217 const char *unlock_file;
218 const char *callback_file;
219 unsigned int callback_line;
220 unsigned int being_freed;
221 unsigned int in_callback;
222 unsigned int lock_count;
225void coap_lock_unlock_func(
coap_lock_t *lock,
const char *file,
int line);
226int coap_lock_lock_func(
coap_lock_t *lock,
const char *file,
int line);
228#define coap_lock_lock(s,failed) do { \
230 if (!coap_lock_lock_func(&(s)->lock, __FILE__, __LINE__)) { \
235#define coap_lock_unlock(s) do { \
237 coap_lock_unlock_func(&(s)->lock, __FILE__, __LINE__); \
240#define coap_lock_callback(s,func) do { \
241 coap_lock_check_locked(s); \
242 (s)->lock.in_callback++; \
243 (s)->lock.callback_file = __FILE__; \
244 (s)->lock.callback_line = __LINE__; \
246 (s)->lock.in_callback--; \
249#define coap_lock_callback_ret(r,s,func) do { \
250 coap_lock_check_locked(s); \
251 (s)->lock.in_callback++; \
252 (s)->lock.callback_file = __FILE__; \
253 (s)->lock.callback_line = __LINE__; \
255 (s)->lock.in_callback--; \
267 uint32_t being_freed;
268 uint32_t in_callback;
269 volatile uint32_t lock_count;
275#define coap_lock_lock(s,failed) do { \
277 if (!coap_lock_lock_func(&(s)->lock)) { \
282#define coap_lock_unlock(s) do { \
284 coap_lock_unlock_func(&(s)->lock); \
287#define coap_lock_callback(s,func) do { \
288 coap_lock_check_locked(s); \
289 (s)->lock.in_callback++; \
291 (s)->lock.in_callback--; \
294#define coap_lock_callback_ret(r,s,func) do { \
295 coap_lock_check_locked(s); \
296 (s)->lock.in_callback++; \
298 (s)->lock.in_callback--; \
303#define coap_lock_init(s) do { \
305 memset(&((s)->lock), 0, sizeof((s)->lock)); \
306 coap_mutex_init(&(s)->lock.mutex); \
309#define coap_lock_being_freed(s,failed) do { \
310 coap_lock_lock(s,failed); \
311 (s)->lock.being_freed = 1; \
312 (s)->lock.freeing_pid = coap_thread_pid; \
313 coap_lock_unlock(s); \
316#define coap_lock_check_locked(s) do { \
317 assert ((s) && (s)->lock.being_freed ? coap_thread_pid == (s)->lock.freeing_pid: coap_thread_pid == (s)->lock.pid); \
320#define coap_lock_invert(s,func,f) do { \
321 coap_lock_check_locked(s); \
322 if (!(s)->lock.being_freed) { \
323 coap_lock_unlock(s); \
325 coap_lock_lock(s,f); \
338#define coap_lock_lock(s,failed)
339#define coap_lock_unlock(s)
340#define coap_lock_init(s)
341#define coap_lock_being_freed(s,failed)
342#define coap_lock_check_locked(s) {}
343#define coap_lock_callback(s,func) func
344#define coap_lock_callback_ret(r,s,func) ret = func
345#define coap_lock_invert(s,func,f) func
#define coap_thread_pid_t