diff options
| author | gingerBill <bill@gingerbill.org> | 2021-10-11 20:14:26 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-10-11 20:14:26 +0100 |
| commit | 753acc6971588aed8b90ffec81f63e5a560f84ff (patch) | |
| tree | b592f5cee2e935d33a942bda47b39af4af17b1ac /core/sync/sync2 | |
| parent | 0d258e8b55f95b7e0d47911be9b5b0ab2094cb17 (diff) | |
Add `wait_group_wait_with_timeout`; Allow `Sema` to be implemented as a `Wait_Group`
Diffstat (limited to 'core/sync/sync2')
| -rw-r--r-- | core/sync/sync2/extended.odin | 20 | ||||
| -rw-r--r-- | core/sync/sync2/sema_internal.odin | 52 |
2 files changed, 24 insertions, 48 deletions
diff --git a/core/sync/sync2/extended.odin b/core/sync/sync2/extended.odin index e52da3b22..3ef4c04e5 100644 --- a/core/sync/sync2/extended.odin +++ b/core/sync/sync2/extended.odin @@ -1,5 +1,7 @@ package sync2 +import "core:time" + // A Wait_Group waits for a collection of threads to finish // // A Wait_Group must not be copied after first use @@ -45,6 +47,24 @@ wait_group_wait :: proc(wg: ^Wait_Group) { } } +wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) -> bool { + if duration <= 0 { + return false + } + mutex_lock(&wg.mutex) + defer mutex_unlock(&wg.mutex) + + if wg.counter != 0 { + if !cond_wait_with_timeout(&wg.cond, &wg.mutex, duration) { + return false + } + if wg.counter != 0 { + panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait") + } + } + return true +} + // A barrier enabling multiple threads to synchronize the beginning of some computation diff --git a/core/sync/sync2/sema_internal.odin b/core/sync/sync2/sema_internal.odin index 89992fbed..64fc4ed96 100644 --- a/core/sync/sync2/sema_internal.odin +++ b/core/sync/sync2/sema_internal.odin @@ -55,62 +55,18 @@ when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { } } else { _Sema :: struct { - mutex: Mutex, - cond: Cond, - count: i32, + wg: Wait_Group, } _sema_post :: proc(s: ^Sema, count := 1) { - mutex_lock(&s.impl.mutex) - defer mutex_unlock(&s.impl.mutex) - - s.impl.count += i32(count) - if count == 1 { - cond_signal(&s.impl.cond) - } else { - cond_broadcast(&s.impl.cond) - } + wait_group_add(&s.impl.wg, count) } _sema_wait :: proc(s: ^Sema) { - mutex_lock(&s.impl.mutex) - defer mutex_unlock(&s.impl.mutex) - - for s.impl.count == 0 { - cond_wait(&s.impl.cond, &s.impl.mutex) - } - - s.impl.count -= 1 - if s.impl.count > 0 { - cond_signal(&s.impl.cond) - } + wait_group_wait(&s.impl.wg) } _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { - if duration <= 0 { - return false - } - - mutex_lock(&s.impl.mutex) - defer mutex_unlock(&s.impl.mutex) - - start := time.tick_now() - for s.impl.count == 0 { - remaining := duration - time.tick_since(start) - if remaining < 0 { - return false - } - - if !cond_wait_with_timeout(&s.impl.cond, &s.impl.mutex, remaining) { - return false - } - } - - s.impl.count -= 1 - if s.impl.count > 0 { - cond_signal(&s.impl.cond) - } - - return true + return wait_group_wait_with_timeout(&s.impl.wg, duration) } }
\ No newline at end of file |