mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Simplify Atomic_Sema implementation
This commit is contained in:
@@ -325,30 +325,28 @@ atomic_cond_broadcast :: proc(c: ^Atomic_Cond) {
|
|||||||
//
|
//
|
||||||
// An Atomic_Sema must not be copied after first use
|
// An Atomic_Sema must not be copied after first use
|
||||||
Atomic_Sema :: struct {
|
Atomic_Sema :: struct {
|
||||||
mutex: Atomic_Mutex,
|
count: Futex,
|
||||||
cond: Atomic_Cond,
|
|
||||||
count: int,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_sema_post :: proc(s: ^Atomic_Sema, count := 1) {
|
atomic_sema_post :: proc(s: ^Atomic_Sema, count := 1) {
|
||||||
atomic_mutex_lock(&s.mutex)
|
atomic_add_explicit(&s.count, Futex(count), .Release)
|
||||||
defer atomic_mutex_unlock(&s.mutex)
|
if count == 1 {
|
||||||
|
futex_signal(&s.count)
|
||||||
s.count += count
|
} else {
|
||||||
atomic_cond_signal(&s.cond)
|
futex_broadcast(&s.count)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_sema_wait :: proc(s: ^Atomic_Sema) {
|
atomic_sema_wait :: proc(s: ^Atomic_Sema) {
|
||||||
atomic_mutex_lock(&s.mutex)
|
for {
|
||||||
defer atomic_mutex_unlock(&s.mutex)
|
original_count := atomic_load_explicit(&s.count, .Relaxed)
|
||||||
|
for original_count == 0 {
|
||||||
for s.count == 0 {
|
futex_wait(&s.count, u32(original_count))
|
||||||
atomic_cond_wait(&s.cond, &s.mutex)
|
original_count = s.count
|
||||||
}
|
}
|
||||||
|
if original_count == atomic_compare_exchange_strong_explicit(&s.count, original_count, original_count-1, .Acquire, .Acquire) {
|
||||||
s.count -= 1
|
return
|
||||||
if s.count > 0 {
|
}
|
||||||
atomic_cond_signal(&s.cond)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,25 +354,22 @@ atomic_sema_wait_with_timeout :: proc(s: ^Atomic_Sema, duration: time.Duration)
|
|||||||
if duration <= 0 {
|
if duration <= 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
atomic_mutex_lock(&s.mutex)
|
for {
|
||||||
defer atomic_mutex_unlock(&s.mutex)
|
|
||||||
|
|
||||||
start := time.tick_now()
|
|
||||||
|
|
||||||
for s.count == 0 {
|
original_count := atomic_load_explicit(&s.count, .Relaxed)
|
||||||
remaining := duration - time.tick_since(start)
|
for start := time.tick_now(); original_count == 0; /**/ {
|
||||||
if remaining < 0 {
|
remaining := duration - time.tick_since(start)
|
||||||
return false
|
if remaining < 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !futex_wait_with_timeout(&s.count, u32(original_count), remaining) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
original_count = s.count
|
||||||
}
|
}
|
||||||
|
if original_count == atomic_compare_exchange_strong_explicit(&s.count, original_count, original_count-1, .Acquire, .Acquire) {
|
||||||
if !atomic_cond_wait_with_timeout(&s.cond, &s.mutex, remaining) {
|
return true
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.count -= 1
|
|
||||||
if s.count > 0 {
|
|
||||||
atomic_cond_signal(&s.cond)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user