xref: /optee_os/core/include/kernel/mutex.h (revision 51f49692723419b40830e2652b9773b45c9b97d4)
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