151f49692SMarouene Boubakri /* SPDX-License-Identifier: BSD-2-Clause */ 251f49692SMarouene Boubakri /* 351f49692SMarouene Boubakri * Copyright (c) 2014-2017, Linaro Limited 451f49692SMarouene Boubakri */ 5d50fee03SEtienne Carriere #ifndef __KERNEL_MUTEX_H 6d50fee03SEtienne Carriere #define __KERNEL_MUTEX_H 751f49692SMarouene Boubakri 851f49692SMarouene Boubakri #include <kernel/refcount.h> 951f49692SMarouene Boubakri #include <kernel/wait_queue.h> 1051f49692SMarouene Boubakri #include <sys/queue.h> 1151f49692SMarouene Boubakri #include <types_ext.h> 1251f49692SMarouene Boubakri 1351f49692SMarouene Boubakri struct mutex { 1451f49692SMarouene Boubakri unsigned spin_lock; /* used when operating on this struct */ 1551f49692SMarouene Boubakri struct wait_queue wq; 1651f49692SMarouene Boubakri short state; /* -1: write, 0: unlocked, > 0: readers */ 1751f49692SMarouene Boubakri }; 1851f49692SMarouene Boubakri 1951f49692SMarouene Boubakri #define MUTEX_INITIALIZER { .wq = WAIT_QUEUE_INITIALIZER } 2051f49692SMarouene Boubakri 2151f49692SMarouene Boubakri struct recursive_mutex { 2251f49692SMarouene Boubakri struct mutex m; /* used when lock_depth goes 0 -> 1 or 1 -> 0 */ 2351f49692SMarouene Boubakri short int owner; 2451f49692SMarouene Boubakri struct refcount lock_depth; 2551f49692SMarouene Boubakri }; 2651f49692SMarouene Boubakri 2751f49692SMarouene Boubakri #define RECURSIVE_MUTEX_INITIALIZER { .m = MUTEX_INITIALIZER, \ 2851f49692SMarouene Boubakri .owner = THREAD_ID_INVALID } 2951f49692SMarouene Boubakri 3051f49692SMarouene Boubakri TAILQ_HEAD(mutex_head, mutex); 3151f49692SMarouene Boubakri 3251f49692SMarouene Boubakri void mutex_init(struct mutex *m); 3351f49692SMarouene Boubakri void mutex_destroy(struct mutex *m); 3451f49692SMarouene Boubakri 3551f49692SMarouene Boubakri void mutex_init_recursive(struct recursive_mutex *m); 3651f49692SMarouene Boubakri void mutex_destroy_recursive(struct recursive_mutex *m); 3751f49692SMarouene Boubakri unsigned int mutex_get_recursive_lock_depth(struct recursive_mutex *m); 3851f49692SMarouene Boubakri 3951f49692SMarouene Boubakri #ifdef CFG_MUTEX_DEBUG 4051f49692SMarouene Boubakri void mutex_unlock_debug(struct mutex *m, const char *fname, int lineno); 4151f49692SMarouene Boubakri #define mutex_unlock(m) mutex_unlock_debug((m), __FILE__, __LINE__) 4251f49692SMarouene Boubakri 4351f49692SMarouene Boubakri void mutex_lock_debug(struct mutex *m, const char *fname, int lineno); 4451f49692SMarouene Boubakri #define mutex_lock(m) mutex_lock_debug((m), __FILE__, __LINE__) 4551f49692SMarouene Boubakri 4651f49692SMarouene Boubakri bool mutex_trylock_debug(struct mutex *m, const char *fname, int lineno); 4751f49692SMarouene Boubakri #define mutex_trylock(m) mutex_trylock_debug((m), __FILE__, __LINE__) 4851f49692SMarouene Boubakri 4951f49692SMarouene Boubakri void mutex_read_unlock_debug(struct mutex *m, const char *fname, int lineno); 5051f49692SMarouene Boubakri #define mutex_read_unlock(m) mutex_read_unlock_debug((m), __FILE__, __LINE__) 5151f49692SMarouene Boubakri 5251f49692SMarouene Boubakri void mutex_read_lock_debug(struct mutex *m, const char *fname, int lineno); 5351f49692SMarouene Boubakri #define mutex_read_lock(m) mutex_read_lock_debug((m), __FILE__, __LINE__) 5451f49692SMarouene Boubakri 5551f49692SMarouene Boubakri bool mutex_read_trylock_debug(struct mutex *m, const char *fname, int lineno); 5651f49692SMarouene Boubakri #define mutex_read_trylock(m) mutex_read_trylock_debug((m), __FILE__, __LINE__) 5751f49692SMarouene Boubakri 5851f49692SMarouene Boubakri void mutex_unlock_recursive_debug(struct recursive_mutex *m, const char *fname, 5951f49692SMarouene Boubakri int lineno); 6051f49692SMarouene Boubakri #define mutex_unlock_recursive(m) mutex_unlock_recursive_debug((m), __FILE__, \ 6151f49692SMarouene Boubakri __LINE__) 6251f49692SMarouene Boubakri 6351f49692SMarouene Boubakri void mutex_lock_recursive_debug(struct recursive_mutex *m, const char *fname, 6451f49692SMarouene Boubakri int lineno); 6551f49692SMarouene Boubakri #define mutex_lock_recursive(m) mutex_lock_recursive_debug((m), __FILE__, \ 6651f49692SMarouene Boubakri __LINE__) 6751f49692SMarouene Boubakri #else 6851f49692SMarouene Boubakri void mutex_unlock(struct mutex *m); 6951f49692SMarouene Boubakri void mutex_lock(struct mutex *m); 7051f49692SMarouene Boubakri bool mutex_trylock(struct mutex *m); 7151f49692SMarouene Boubakri void mutex_read_unlock(struct mutex *m); 7251f49692SMarouene Boubakri void mutex_read_lock(struct mutex *m); 7351f49692SMarouene Boubakri bool mutex_read_trylock(struct mutex *m); 7451f49692SMarouene Boubakri 7551f49692SMarouene Boubakri void mutex_unlock_recursive(struct recursive_mutex *m); 7651f49692SMarouene Boubakri void mutex_lock_recursive(struct recursive_mutex *m); 7751f49692SMarouene Boubakri #endif 7851f49692SMarouene Boubakri 7951f49692SMarouene Boubakri struct condvar { 8051f49692SMarouene Boubakri unsigned spin_lock; 8151f49692SMarouene Boubakri struct mutex *m; 8251f49692SMarouene Boubakri }; 8351f49692SMarouene Boubakri #define CONDVAR_INITIALIZER { .m = NULL } 8451f49692SMarouene Boubakri 8551f49692SMarouene Boubakri void condvar_init(struct condvar *cv); 8651f49692SMarouene Boubakri void condvar_destroy(struct condvar *cv); 8751f49692SMarouene Boubakri 8851f49692SMarouene Boubakri #ifdef CFG_MUTEX_DEBUG 8951f49692SMarouene Boubakri void condvar_signal_debug(struct condvar *cv, const char *fname, int lineno); 9051f49692SMarouene Boubakri #define condvar_signal(cv) condvar_signal_debug((cv), __FILE__, __LINE__) 9151f49692SMarouene Boubakri 9251f49692SMarouene Boubakri void condvar_broadcast_debug(struct condvar *cv, const char *fname, int lineno); 9351f49692SMarouene Boubakri #define condvar_broadcast(cv) condvar_broadcast_debug((cv), __FILE__, __LINE__) 9451f49692SMarouene Boubakri 9551f49692SMarouene Boubakri void condvar_wait_debug(struct condvar *cv, struct mutex *m, 9651f49692SMarouene Boubakri const char *fname, int lineno); 9751f49692SMarouene Boubakri #define condvar_wait(cv, m) condvar_wait_debug((cv), (m), __FILE__, __LINE__) 98*ea413ca5SGavin Liu 99*ea413ca5SGavin Liu /* 100*ea413ca5SGavin Liu * Return TEE_ERROR_TIMEOUT if the normal world returns before 101*ea413ca5SGavin Liu * the condvar has been signaled. 102*ea413ca5SGavin Liu */ 103*ea413ca5SGavin Liu TEE_Result condvar_wait_timeout_debug(struct condvar *cv, struct mutex *m, 104*ea413ca5SGavin Liu uint32_t timeout_ms, const char *fname, 105*ea413ca5SGavin Liu int lineno); 106*ea413ca5SGavin Liu #define condvar_wait_timeout(cv, m, timeout_ms) \ 107*ea413ca5SGavin Liu condvar_wait_timeout_debug((cv), (m), (timeout_ms), __FILE__, __LINE__) 10851f49692SMarouene Boubakri #else 10951f49692SMarouene Boubakri void condvar_signal(struct condvar *cv); 11051f49692SMarouene Boubakri void condvar_broadcast(struct condvar *cv); 11151f49692SMarouene Boubakri void condvar_wait(struct condvar *cv, struct mutex *m); 112*ea413ca5SGavin Liu /* 113*ea413ca5SGavin Liu * Return TEE_ERROR_TIMEOUT if the normal world returns before 114*ea413ca5SGavin Liu * the condvar has been signaled. 115*ea413ca5SGavin Liu */ 116*ea413ca5SGavin Liu TEE_Result condvar_wait_timeout(struct condvar *cv, struct mutex *m, 117*ea413ca5SGavin Liu uint32_t timeout_ms); 11851f49692SMarouene Boubakri #endif 11951f49692SMarouene Boubakri 120d50fee03SEtienne Carriere #endif /*__KERNEL_MUTEX_H*/ 12151f49692SMarouene Boubakri 122