Unify default Sema and Atomic_Sema behaviour

This commit is contained in:
gingerBill
2022-04-27 15:03:48 +01:00
parent 904f0407f8
commit bd73b2845b
2 changed files with 34 additions and 73 deletions
+30 -35
View File
@@ -400,30 +400,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)
} }
} }
@@ -431,25 +429,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
} }
+4 -38
View File
@@ -6,53 +6,19 @@ import "core:time"
when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) {
_Sema :: struct { _Sema :: struct {
count: Futex, atomic: Atomic_Sema,
} }
_sema_post :: proc(s: ^Sema, count := 1) { _sema_post :: proc(s: ^Sema, count := 1) {
atomic_add_explicit(&s.impl.count, Futex(count), .Release) atomic_sema_post(&s.impl.atomic, count)
if count == 1 {
futex_signal(&s.impl.count)
} else {
futex_broadcast(&s.impl.count)
}
} }
_sema_wait :: proc(s: ^Sema) { _sema_wait :: proc(s: ^Sema) {
for { atomic_sema_wait(&s.impl.atomic)
original_count := atomic_load_explicit(&s.impl.count, .Relaxed)
for original_count == 0 {
futex_wait(&s.impl.count, u32(original_count))
original_count = s.impl.count
}
if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) {
return
}
}
} }
_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
if duration <= 0 { return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
return false
}
for {
original_count := atomic_load_explicit(&s.impl.count, .Relaxed)
for start := time.tick_now(); original_count == 0; /**/ {
remaining := duration - time.tick_since(start)
if remaining < 0 {
return false
}
if !futex_wait_with_timeout(&s.impl.count, u32(original_count), remaining) {
return false
}
original_count = s.impl.count
}
if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) {
return true
}
}
} }
} else { } else {
_Sema :: struct { _Sema :: struct {