aboutsummaryrefslogtreecommitdiff
path: root/core/sync
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-10-11 20:14:26 +0100
committergingerBill <bill@gingerbill.org>2021-10-11 20:14:26 +0100
commit753acc6971588aed8b90ffec81f63e5a560f84ff (patch)
treeb592f5cee2e935d33a942bda47b39af4af17b1ac /core/sync
parent0d258e8b55f95b7e0d47911be9b5b0ab2094cb17 (diff)
Add `wait_group_wait_with_timeout`; Allow `Sema` to be implemented as a `Wait_Group`
Diffstat (limited to 'core/sync')
-rw-r--r--core/sync/sync2/extended.odin20
-rw-r--r--core/sync/sync2/sema_internal.odin52
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