Unify implementation for *nix platforms

This commit is contained in:
gingerBill
2022-04-30 13:09:24 +01:00
parent 78a8da5fea
commit 4e39629a9a
5 changed files with 67 additions and 225 deletions
-38
View File
@@ -17,41 +17,3 @@ _current_thread_id :: proc "contextless" () -> int {
pthread_threadid_np(nil, &tid) pthread_threadid_np(nil, &tid)
return int(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)
}
-36
View File
@@ -8,39 +8,3 @@ import "core:time"
_current_thread_id :: proc "contextless" () -> int { _current_thread_id :: proc "contextless" () -> int {
return os.current_thread_id() 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)
}
+67 -78
View File
@@ -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 {
_Recursive_Mutex :: struct { owner: Futex,
owner: Futex, recursion: i32,
recursion: i32, }
}
_recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
tid := Futex(current_thread_id()) tid := Futex(current_thread_id())
for { 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())
prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire)
switch prev_owner { switch prev_owner {
case 0, tid: case 0, tid:
m.impl.recursion += 1 m.impl.recursion += 1
// inside the lock // 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) { futex_wait(&m.impl.owner, u32(prev_owner))
tid := current_thread_id() }
if tid != m.impl.owner { }
mutex_lock(&m.impl.mutex)
} _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
// inside the lock m.impl.recursion -= 1
m.impl.owner = tid 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 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 // inside the lock
m.impl.owner = tid
m.impl.recursion += 1
return true return true
} }
return false
} }
when ODIN_OS != .Windows { 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 { _RW_Mutex :: struct {
mutex: Atomic_RW_Mutex, mutex: Atomic_RW_Mutex,
} }
@@ -140,5 +130,4 @@ when ODIN_OS != .Windows {
_rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool { _rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex) return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex)
} }
} }
-37
View File
@@ -8,40 +8,3 @@ import "core:time"
_current_thread_id :: proc "contextless" () -> int { _current_thread_id :: proc "contextless" () -> int {
return unix.sys_gettid() 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)
}
-36
View File
@@ -8,39 +8,3 @@ import "core:time"
_current_thread_id :: proc "contextless" () -> int { _current_thread_id :: proc "contextless" () -> int {
return os.current_thread_id() 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)
}