1e57d8977SPavithra Gurushankar /* SPDX-License-Identifier: GPL-2.0 */ 2e57d8977SPavithra Gurushankar #ifndef __PERF_MUTEX_H 3e57d8977SPavithra Gurushankar #define __PERF_MUTEX_H 4e57d8977SPavithra Gurushankar 5e57d8977SPavithra Gurushankar #include <pthread.h> 6e57d8977SPavithra Gurushankar #include <stdbool.h> 7e57d8977SPavithra Gurushankar 8e57d8977SPavithra Gurushankar /* 9*bfa339ceSIan Rogers * A function-like feature checking macro that is a wrapper around 10*bfa339ceSIan Rogers * `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a 11*bfa339ceSIan Rogers * nonzero constant integer if the attribute is supported or 0 if not. 12*bfa339ceSIan Rogers */ 13*bfa339ceSIan Rogers #ifdef __has_attribute 14*bfa339ceSIan Rogers #define HAVE_ATTRIBUTE(x) __has_attribute(x) 15*bfa339ceSIan Rogers #else 16*bfa339ceSIan Rogers #define HAVE_ATTRIBUTE(x) 0 17*bfa339ceSIan Rogers #endif 18*bfa339ceSIan Rogers 19*bfa339ceSIan Rogers #if HAVE_ATTRIBUTE(guarded_by) && HAVE_ATTRIBUTE(pt_guarded_by) && \ 20*bfa339ceSIan Rogers HAVE_ATTRIBUTE(lockable) && HAVE_ATTRIBUTE(exclusive_lock_function) && \ 21*bfa339ceSIan Rogers HAVE_ATTRIBUTE(exclusive_trylock_function) && HAVE_ATTRIBUTE(exclusive_locks_required) && \ 22*bfa339ceSIan Rogers HAVE_ATTRIBUTE(no_thread_safety_analysis) 23*bfa339ceSIan Rogers 24*bfa339ceSIan Rogers /* Documents if a shared field or global variable needs to be protected by a mutex. */ 25*bfa339ceSIan Rogers #define GUARDED_BY(x) __attribute__((guarded_by(x))) 26*bfa339ceSIan Rogers 27*bfa339ceSIan Rogers /* 28*bfa339ceSIan Rogers * Documents if the memory location pointed to by a pointer should be guarded by 29*bfa339ceSIan Rogers * a mutex when dereferencing the pointer. 30*bfa339ceSIan Rogers */ 31*bfa339ceSIan Rogers #define PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) 32*bfa339ceSIan Rogers 33*bfa339ceSIan Rogers /* Documents if a type is a lockable type. */ 34*bfa339ceSIan Rogers #define LOCKABLE __attribute__((lockable)) 35*bfa339ceSIan Rogers 36*bfa339ceSIan Rogers /* Documents functions that acquire a lock in the body of a function, and do not release it. */ 37*bfa339ceSIan Rogers #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__))) 38*bfa339ceSIan Rogers 39*bfa339ceSIan Rogers /* 40*bfa339ceSIan Rogers * Documents functions that expect a lock to be held on entry to the function, 41*bfa339ceSIan Rogers * and release it in the body of the function. 42*bfa339ceSIan Rogers */ 43*bfa339ceSIan Rogers #define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) 44*bfa339ceSIan Rogers 45*bfa339ceSIan Rogers /* Documents functions that try to acquire a lock, and return success or failure. */ 46*bfa339ceSIan Rogers #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \ 47*bfa339ceSIan Rogers __attribute__((exclusive_trylock_function(__VA_ARGS__))) 48*bfa339ceSIan Rogers 49*bfa339ceSIan Rogers /* Documents a function that expects a mutex to be held prior to entry. */ 50*bfa339ceSIan Rogers #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__))) 51*bfa339ceSIan Rogers 52*bfa339ceSIan Rogers /* Turns off thread safety checking within the body of a particular function. */ 53*bfa339ceSIan Rogers #define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 54*bfa339ceSIan Rogers 55*bfa339ceSIan Rogers #else 56*bfa339ceSIan Rogers 57*bfa339ceSIan Rogers #define GUARDED_BY(x) 58*bfa339ceSIan Rogers #define PT_GUARDED_BY(x) 59*bfa339ceSIan Rogers #define LOCKABLE 60*bfa339ceSIan Rogers #define EXCLUSIVE_LOCK_FUNCTION(...) 61*bfa339ceSIan Rogers #define UNLOCK_FUNCTION(...) 62*bfa339ceSIan Rogers #define EXCLUSIVE_TRYLOCK_FUNCTION(...) 63*bfa339ceSIan Rogers #define EXCLUSIVE_LOCKS_REQUIRED(...) 64*bfa339ceSIan Rogers #define NO_THREAD_SAFETY_ANALYSIS 65*bfa339ceSIan Rogers 66*bfa339ceSIan Rogers #endif 67*bfa339ceSIan Rogers 68*bfa339ceSIan Rogers /* 69e57d8977SPavithra Gurushankar * A wrapper around the mutex implementation that allows perf to error check 70e57d8977SPavithra Gurushankar * usage, etc. 71e57d8977SPavithra Gurushankar */ 72*bfa339ceSIan Rogers struct LOCKABLE mutex { 73e57d8977SPavithra Gurushankar pthread_mutex_t lock; 74e57d8977SPavithra Gurushankar }; 75e57d8977SPavithra Gurushankar 76e57d8977SPavithra Gurushankar /* A wrapper around the condition variable implementation. */ 77e57d8977SPavithra Gurushankar struct cond { 78e57d8977SPavithra Gurushankar pthread_cond_t cond; 79e57d8977SPavithra Gurushankar }; 80e57d8977SPavithra Gurushankar 81e57d8977SPavithra Gurushankar /* Default initialize the mtx struct. */ 82e57d8977SPavithra Gurushankar void mutex_init(struct mutex *mtx); 83e57d8977SPavithra Gurushankar /* 84e57d8977SPavithra Gurushankar * Initialize the mtx struct and set the process-shared rather than default 85e57d8977SPavithra Gurushankar * process-private attribute. 86e57d8977SPavithra Gurushankar */ 87e57d8977SPavithra Gurushankar void mutex_init_pshared(struct mutex *mtx); 88e57d8977SPavithra Gurushankar void mutex_destroy(struct mutex *mtx); 89e57d8977SPavithra Gurushankar 90*bfa339ceSIan Rogers void mutex_lock(struct mutex *mtx) EXCLUSIVE_LOCK_FUNCTION(*mtx); 91*bfa339ceSIan Rogers void mutex_unlock(struct mutex *mtx) UNLOCK_FUNCTION(*mtx); 92e57d8977SPavithra Gurushankar /* Tries to acquire the lock and returns true on success. */ 93*bfa339ceSIan Rogers bool mutex_trylock(struct mutex *mtx) EXCLUSIVE_TRYLOCK_FUNCTION(true, *mtx); 94e57d8977SPavithra Gurushankar 95e57d8977SPavithra Gurushankar /* Default initialize the cond struct. */ 96e57d8977SPavithra Gurushankar void cond_init(struct cond *cnd); 97e57d8977SPavithra Gurushankar /* 98e57d8977SPavithra Gurushankar * Initialize the cond struct and specify the process-shared rather than default 99e57d8977SPavithra Gurushankar * process-private attribute. 100e57d8977SPavithra Gurushankar */ 101e57d8977SPavithra Gurushankar void cond_init_pshared(struct cond *cnd); 102e57d8977SPavithra Gurushankar void cond_destroy(struct cond *cnd); 103e57d8977SPavithra Gurushankar 104*bfa339ceSIan Rogers void cond_wait(struct cond *cnd, struct mutex *mtx) EXCLUSIVE_LOCKS_REQUIRED(mtx); 105e57d8977SPavithra Gurushankar void cond_signal(struct cond *cnd); 106e57d8977SPavithra Gurushankar void cond_broadcast(struct cond *cnd); 107e57d8977SPavithra Gurushankar 108e57d8977SPavithra Gurushankar #endif /* __PERF_MUTEX_H */ 109