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