Branch data Line data Source code
1 : : // This file is a part of Julia. License is MIT: https://julialang.org/license 2 : : 3 : : #ifndef JL_LOCKS_H 4 : : #define JL_LOCKS_H 5 : : 6 : : #include "julia_assert.h" 7 : : 8 : : #ifdef __cplusplus 9 : : extern "C" { 10 : : #endif 11 : : 12 : : // Lock acquire and release primitives 13 : : 14 : : // JL_LOCK and jl_mutex_lock are GC safe points, use uv_mutex_t if that is not desired. 15 : : // Always use JL_LOCK unless no one holding the lock can trigger a GC or GC 16 : : // safepoint. uv_mutex_t should only be needed for GC internal locks. 17 : : // The JL_LOCK* and JL_UNLOCK* macros are no-op for non-threading build 18 : : // while the jl_mutex_* functions are always locking and unlocking the locks. 19 : : 20 : : JL_DLLEXPORT void _jl_mutex_wait(jl_task_t *self, jl_mutex_t *lock, int safepoint); 21 : : JL_DLLEXPORT void _jl_mutex_lock(jl_task_t *self, jl_mutex_t *lock); 22 : : JL_DLLEXPORT int _jl_mutex_trylock_nogc(jl_task_t *self, jl_mutex_t *lock) JL_NOTSAFEPOINT; 23 : : JL_DLLEXPORT int _jl_mutex_trylock(jl_task_t *self, jl_mutex_t *lock); 24 : : JL_DLLEXPORT void _jl_mutex_unlock(jl_task_t *self, jl_mutex_t *lock); 25 : : JL_DLLEXPORT void _jl_mutex_unlock_nogc(jl_mutex_t *lock) JL_NOTSAFEPOINT; 26 : : 27 : 1393 : static inline void jl_mutex_wait(jl_mutex_t *lock, int safepoint) 28 : : { 29 : 1393 : _jl_mutex_wait(jl_current_task, lock, safepoint); 30 : 1393 : } 31 : : 32 : 1393 : static inline void jl_mutex_lock_nogc(jl_mutex_t *lock) JL_NOTSAFEPOINT 33 : : { 34 : : #ifndef __clang_gcanalyzer__ 35 : : // Hide this body from the analyzer, otherwise it complains that we're calling 36 : : // a non-safepoint from this function. The 0 arguments guarantees that we do 37 : : // not reach the safepoint, but the analyzer can't figure that out 38 : 1393 : jl_mutex_wait(lock, 0); 39 : : #endif 40 : 1393 : } 41 : : 42 : : #define JL_SIGATOMIC_BEGIN() do { \ 43 : : jl_current_task->ptls->defer_signal++; \ 44 : : jl_signal_fence(); \ 45 : : } while (0) 46 : : #define JL_SIGATOMIC_END() do { \ 47 : : jl_signal_fence(); \ 48 : : if (--jl_current_task->ptls->defer_signal == 0) { \ 49 : : jl_sigint_safepoint(jl_current_task->ptls); \ 50 : : } \ 51 : : } while (0) 52 : : 53 : : #define JL_SIGATOMIC_BEGIN_self() do { \ 54 : : self->ptls->defer_signal++; \ 55 : : jl_signal_fence(); \ 56 : : } while (0) 57 : : #define JL_SIGATOMIC_END_self() do { \ 58 : : jl_signal_fence(); \ 59 : : if (--self->ptls->defer_signal == 0) { \ 60 : : jl_sigint_safepoint(self->ptls); \ 61 : : } \ 62 : : } while (0) 63 : : 64 : 318367350 : static inline void jl_mutex_lock(jl_mutex_t *lock) 65 : : { 66 : 318367350 : _jl_mutex_lock(jl_current_task, lock); 67 : 318367350 : } 68 : : 69 : : static inline int jl_mutex_trylock_nogc(jl_mutex_t *lock) JL_NOTSAFEPOINT 70 : : { 71 : : return _jl_mutex_trylock_nogc(jl_current_task, lock); 72 : : } 73 : : 74 : 62442 : static inline int jl_mutex_trylock(jl_mutex_t *lock) 75 : : { 76 : 62442 : return _jl_mutex_trylock(jl_current_task, lock); 77 : : } 78 : : 79 : 318425670 : static inline void jl_mutex_unlock(jl_mutex_t *lock) 80 : : { 81 : 318425670 : _jl_mutex_unlock(jl_current_task, lock); 82 : 318425670 : } 83 : : 84 : 5515 : static inline void jl_mutex_unlock_nogc(jl_mutex_t *lock) JL_NOTSAFEPOINT 85 : : { 86 : 5515 : _jl_mutex_unlock_nogc(lock); 87 : 5515 : } 88 : : 89 : 76885 : static inline void jl_mutex_init(jl_mutex_t *lock) JL_NOTSAFEPOINT 90 : : { 91 : 76885 : jl_atomic_store_relaxed(&lock->owner, (jl_task_t*)NULL); 92 : 76885 : lock->count = 0; 93 : 76885 : } 94 : : 95 : : #define JL_MUTEX_INIT(m) jl_mutex_init(m) 96 : : #define JL_LOCK(m) jl_mutex_lock(m) 97 : : #define JL_UNLOCK(m) jl_mutex_unlock(m) 98 : : #define JL_LOCK_NOGC(m) jl_mutex_lock_nogc(m) 99 : : #define JL_UNLOCK_NOGC(m) jl_mutex_unlock_nogc(m) 100 : : 101 : : #ifdef __cplusplus 102 : : } 103 : : #endif 104 : : 105 : : #endif