From 4e39629a9a316817b20387b2dc7860f95ab110b4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Apr 2022 13:09:24 +0100 Subject: [PATCH] Unify implementation for *nix platforms --- core/sync/primitives_darwin.odin | 38 -------- core/sync/primitives_freebsd.odin | 36 ------- core/sync/primitives_internal.odin | 145 +++++++++++++---------------- core/sync/primitives_linux.odin | 37 -------- core/sync/primitives_openbsd.odin | 36 ------- 5 files changed, 67 insertions(+), 225 deletions(-) diff --git a/core/sync/primitives_darwin.odin b/core/sync/primitives_darwin.odin index 514f66f3e..521c8fe35 100644 --- a/core/sync/primitives_darwin.odin +++ b/core/sync/primitives_darwin.odin @@ -17,41 +17,3 @@ _current_thread_id :: proc "contextless" () -> int { pthread_threadid_np(nil, &tid) return int(tid) } - - - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -} diff --git a/core/sync/primitives_freebsd.odin b/core/sync/primitives_freebsd.odin index b88fca181..9fdabb7c9 100644 --- a/core/sync/primitives_freebsd.odin +++ b/core/sync/primitives_freebsd.odin @@ -8,39 +8,3 @@ import "core:time" _current_thread_id :: proc "contextless" () -> int { return os.current_thread_id() } - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -} diff --git a/core/sync/primitives_internal.odin b/core/sync/primitives_internal.odin index deacf632c..ba17c2eb5 100644 --- a/core/sync/primitives_internal.odin +++ b/core/sync/primitives_internal.odin @@ -20,99 +20,89 @@ _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { } -when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { - _Recursive_Mutex :: struct { - owner: Futex, - recursion: i32, - } +_Recursive_Mutex :: struct { + owner: Futex, + recursion: i32, +} - _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { - tid := Futex(current_thread_id()) - for { - prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) - switch prev_owner { - case 0, tid: - m.impl.recursion += 1 - // inside the lock - return - } - - futex_wait(&m.impl.owner, u32(prev_owner)) - } - } - - _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { - m.impl.recursion -= 1 - if m.impl.recursion != 0 { - return - } - atomic_exchange_explicit(&m.impl.owner, 0, .Release) - - futex_signal(&m.impl.owner) - // outside the lock - - } - - _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { - tid := Futex(current_thread_id()) +_recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { + tid := Futex(current_thread_id()) + for { prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) switch prev_owner { case 0, tid: m.impl.recursion += 1 // inside the lock - return true + return } - return false - } -} else { - _Recursive_Mutex :: struct { - owner: int, - recursion: int, - mutex: Mutex, - } - _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { - tid := current_thread_id() - if tid != m.impl.owner { - mutex_lock(&m.impl.mutex) - } - // inside the lock - m.impl.owner = tid + futex_wait(&m.impl.owner, u32(prev_owner)) + } +} + +_recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { + m.impl.recursion -= 1 + if m.impl.recursion != 0 { + return + } + atomic_exchange_explicit(&m.impl.owner, 0, .Release) + + futex_signal(&m.impl.owner) + // outside the lock + +} + +_recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { + tid := Futex(current_thread_id()) + prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) + switch prev_owner { + case 0, tid: m.impl.recursion += 1 - } - - _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { - tid := current_thread_id() - assert(tid == m.impl.owner) - m.impl.recursion -= 1 - recursion := m.impl.recursion - if recursion == 0 { - m.impl.owner = 0 - } - if recursion == 0 { - mutex_unlock(&m.impl.mutex) - } - // outside the lock - - } - - _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { - tid := current_thread_id() - if m.impl.owner == tid { - return mutex_try_lock(&m.impl.mutex) - } - if !mutex_try_lock(&m.impl.mutex) { - return false - } // inside the lock - m.impl.owner = tid - m.impl.recursion += 1 return true } + return false } when ODIN_OS != .Windows { + _Mutex :: struct { + mutex: Atomic_Mutex, + } + + _mutex_lock :: proc(m: ^Mutex) { + atomic_mutex_lock(&m.impl.mutex) + } + + _mutex_unlock :: proc(m: ^Mutex) { + atomic_mutex_unlock(&m.impl.mutex) + } + + _mutex_try_lock :: proc(m: ^Mutex) -> bool { + return atomic_mutex_try_lock(&m.impl.mutex) + } + + _Cond :: struct { + cond: Atomic_Cond, + } + + _cond_wait :: proc(c: ^Cond, m: ^Mutex) { + atomic_cond_wait(&c.impl.cond, &m.impl.mutex) + } + + _cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { + return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) + } + + _cond_signal :: proc(c: ^Cond) { + atomic_cond_signal(&c.impl.cond) + } + + _cond_broadcast :: proc(c: ^Cond) { + atomic_cond_broadcast(&c.impl.cond) + } + + _RW_Mutex :: struct { mutex: Atomic_RW_Mutex, } @@ -140,5 +130,4 @@ when ODIN_OS != .Windows { _rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool { return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex) } - } \ No newline at end of file diff --git a/core/sync/primitives_linux.odin b/core/sync/primitives_linux.odin index 0a9f0cc33..4cc99bdf1 100644 --- a/core/sync/primitives_linux.odin +++ b/core/sync/primitives_linux.odin @@ -8,40 +8,3 @@ import "core:time" _current_thread_id :: proc "contextless" () -> int { return unix.sys_gettid() } - - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -} diff --git a/core/sync/primitives_openbsd.odin b/core/sync/primitives_openbsd.odin index 7794016f8..fd56a4837 100644 --- a/core/sync/primitives_openbsd.odin +++ b/core/sync/primitives_openbsd.odin @@ -8,39 +8,3 @@ import "core:time" _current_thread_id :: proc "contextless" () -> int { return os.current_thread_id() } - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -}