1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2014-2017, Linaro Limited 4 */ 5 #ifndef KERNEL_MUTEX_H 6 #define KERNEL_MUTEX_H 7 8 #include <kernel/refcount.h> 9 #include <kernel/wait_queue.h> 10 #include <sys/queue.h> 11 #include <types_ext.h> 12 13 struct mutex { 14 unsigned spin_lock; /* used when operating on this struct */ 15 struct wait_queue wq; 16 short state; /* -1: write, 0: unlocked, > 0: readers */ 17 }; 18 19 #define MUTEX_INITIALIZER { .wq = WAIT_QUEUE_INITIALIZER } 20 21 struct recursive_mutex { 22 struct mutex m; /* used when lock_depth goes 0 -> 1 or 1 -> 0 */ 23 short int owner; 24 struct refcount lock_depth; 25 }; 26 27 #define RECURSIVE_MUTEX_INITIALIZER { .m = MUTEX_INITIALIZER, \ 28 .owner = THREAD_ID_INVALID } 29 30 TAILQ_HEAD(mutex_head, mutex); 31 32 void mutex_init(struct mutex *m); 33 void mutex_destroy(struct mutex *m); 34 35 void mutex_init_recursive(struct recursive_mutex *m); 36 void mutex_destroy_recursive(struct recursive_mutex *m); 37 unsigned int mutex_get_recursive_lock_depth(struct recursive_mutex *m); 38 39 #ifdef CFG_MUTEX_DEBUG 40 void mutex_unlock_debug(struct mutex *m, const char *fname, int lineno); 41 #define mutex_unlock(m) mutex_unlock_debug((m), __FILE__, __LINE__) 42 43 void mutex_lock_debug(struct mutex *m, const char *fname, int lineno); 44 #define mutex_lock(m) mutex_lock_debug((m), __FILE__, __LINE__) 45 46 bool mutex_trylock_debug(struct mutex *m, const char *fname, int lineno); 47 #define mutex_trylock(m) mutex_trylock_debug((m), __FILE__, __LINE__) 48 49 void mutex_read_unlock_debug(struct mutex *m, const char *fname, int lineno); 50 #define mutex_read_unlock(m) mutex_read_unlock_debug((m), __FILE__, __LINE__) 51 52 void mutex_read_lock_debug(struct mutex *m, const char *fname, int lineno); 53 #define mutex_read_lock(m) mutex_read_lock_debug((m), __FILE__, __LINE__) 54 55 bool mutex_read_trylock_debug(struct mutex *m, const char *fname, int lineno); 56 #define mutex_read_trylock(m) mutex_read_trylock_debug((m), __FILE__, __LINE__) 57 58 void mutex_unlock_recursive_debug(struct recursive_mutex *m, const char *fname, 59 int lineno); 60 #define mutex_unlock_recursive(m) mutex_unlock_recursive_debug((m), __FILE__, \ 61 __LINE__) 62 63 void mutex_lock_recursive_debug(struct recursive_mutex *m, const char *fname, 64 int lineno); 65 #define mutex_lock_recursive(m) mutex_lock_recursive_debug((m), __FILE__, \ 66 __LINE__) 67 #else 68 void mutex_unlock(struct mutex *m); 69 void mutex_lock(struct mutex *m); 70 bool mutex_trylock(struct mutex *m); 71 void mutex_read_unlock(struct mutex *m); 72 void mutex_read_lock(struct mutex *m); 73 bool mutex_read_trylock(struct mutex *m); 74 75 void mutex_unlock_recursive(struct recursive_mutex *m); 76 void mutex_lock_recursive(struct recursive_mutex *m); 77 #endif 78 79 struct condvar { 80 unsigned spin_lock; 81 struct mutex *m; 82 }; 83 #define CONDVAR_INITIALIZER { .m = NULL } 84 85 void condvar_init(struct condvar *cv); 86 void condvar_destroy(struct condvar *cv); 87 88 #ifdef CFG_MUTEX_DEBUG 89 void condvar_signal_debug(struct condvar *cv, const char *fname, int lineno); 90 #define condvar_signal(cv) condvar_signal_debug((cv), __FILE__, __LINE__) 91 92 void condvar_broadcast_debug(struct condvar *cv, const char *fname, int lineno); 93 #define condvar_broadcast(cv) condvar_broadcast_debug((cv), __FILE__, __LINE__) 94 95 void condvar_wait_debug(struct condvar *cv, struct mutex *m, 96 const char *fname, int lineno); 97 #define condvar_wait(cv, m) condvar_wait_debug((cv), (m), __FILE__, __LINE__) 98 #else 99 void condvar_signal(struct condvar *cv); 100 void condvar_broadcast(struct condvar *cv); 101 void condvar_wait(struct condvar *cv, struct mutex *m); 102 #endif 103 104 #endif /*KERNEL_MUTEX_H*/ 105 106