Browse Source

Remove the wait group based semaphore implementation

It was a misuse of the data structure
gingerBill 3 years ago
parent
commit
d5886c1572
3 changed files with 24 additions and 49 deletions
  1. 5 10
      core/sync/extended.odin
  2. 19 0
      core/sync/primitives_internal.odin
  3. 0 39
      core/sync/sema_internal.odin

+ 5 - 10
core/sync/extended.odin

@@ -16,8 +16,7 @@ wait_group_add :: proc(wg: ^Wait_Group, delta: int) {
 		return
 		return
 	}
 	}
 
 
-	mutex_lock(&wg.mutex)
-	defer mutex_unlock(&wg.mutex)
+	guard(&wg.mutex)
 
 
 	atomic_add(&wg.counter, delta)
 	atomic_add(&wg.counter, delta)
 	if wg.counter < 0 {
 	if wg.counter < 0 {
@@ -36,8 +35,7 @@ wait_group_done :: proc(wg: ^Wait_Group) {
 }
 }
 
 
 wait_group_wait :: proc(wg: ^Wait_Group) {
 wait_group_wait :: proc(wg: ^Wait_Group) {
-	mutex_lock(&wg.mutex)
-	defer mutex_unlock(&wg.mutex)
+	guard(&wg.mutex)
 
 
 	if wg.counter != 0 {
 	if wg.counter != 0 {
 		cond_wait(&wg.cond, &wg.mutex)
 		cond_wait(&wg.cond, &wg.mutex)
@@ -51,8 +49,7 @@ wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) -
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}
-	mutex_lock(&wg.mutex)
-	defer mutex_unlock(&wg.mutex)
+	guard(&wg.mutex)
 
 
 	if wg.counter != 0 {
 	if wg.counter != 0 {
 		if !cond_wait_with_timeout(&wg.cond, &wg.mutex, duration) {
 		if !cond_wait_with_timeout(&wg.cond, &wg.mutex, duration) {
@@ -119,8 +116,7 @@ barrier_init :: proc(b: ^Barrier, thread_count: int) {
 // Block the current thread until all threads have rendezvoused
 // Block the current thread until all threads have rendezvoused
 // Barrier can be reused after all threads rendezvoused once, and can be used continuously
 // Barrier can be reused after all threads rendezvoused once, and can be used continuously
 barrier_wait :: proc(b: ^Barrier) -> (is_leader: bool) {
 barrier_wait :: proc(b: ^Barrier) -> (is_leader: bool) {
-	mutex_lock(&b.mutex)
-	defer mutex_unlock(&b.mutex)
+	guard(&b.mutex)
 	local_gen := b.generation_id
 	local_gen := b.generation_id
 	b.index += 1
 	b.index += 1
 	if b.index < b.thread_count {
 	if b.index < b.thread_count {
@@ -289,8 +285,7 @@ Once :: struct {
 once_do :: proc(o: ^Once, fn: proc()) {
 once_do :: proc(o: ^Once, fn: proc()) {
 	@(cold)
 	@(cold)
 	do_slow :: proc(o: ^Once, fn: proc()) {
 	do_slow :: proc(o: ^Once, fn: proc()) {
-		mutex_lock(&o.m)
-		defer mutex_unlock(&o.m)
+		guard(&o.m)
 		if !o.done {
 		if !o.done {
 			fn()
 			fn()
 			atomic_store_explicit(&o.done, true, .Release)
 			atomic_store_explicit(&o.done, true, .Release)

+ 19 - 0
core/sync/primitives_internal.odin

@@ -1,6 +1,25 @@
 //+private
 //+private
 package sync
 package sync
 
 
+import "core:time"
+
+_Sema :: struct {
+	atomic: Atomic_Sema,
+}
+
+_sema_post :: proc(s: ^Sema, count := 1) {
+	atomic_sema_post(&s.impl.atomic, count)
+}
+
+_sema_wait :: proc(s: ^Sema) {
+	atomic_sema_wait(&s.impl.atomic)
+}
+
+_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
+	return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
+}
+
+
 when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) {
 when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) {
 	_Recursive_Mutex :: struct {
 	_Recursive_Mutex :: struct {
 		owner:     Futex,
 		owner:     Futex,

+ 0 - 39
core/sync/sema_internal.odin

@@ -1,39 +0,0 @@
-//+private
-package sync
-
-import "core:time"
-
-
-when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) {
-	_Sema :: struct {
-		atomic: Atomic_Sema,
-	}
-
-	_sema_post :: proc(s: ^Sema, count := 1) {
-		atomic_sema_post(&s.impl.atomic, count)
-	}
-
-	_sema_wait :: proc(s: ^Sema) {
-		atomic_sema_wait(&s.impl.atomic)
-	}
-
-	_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
-		return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
-	}
-} else {
-	_Sema :: struct {
-		wg: Wait_Group,
-	}
-
-	_sema_post :: proc(s: ^Sema, count := 1) {
-		wait_group_add(&s.impl.wg, count)
-	}
-
-	_sema_wait :: proc(s: ^Sema) {
-		wait_group_wait(&s.impl.wg)
-	}
-
-	_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
-		return wait_group_wait_with_timeout(&s.impl.wg, duration)
-	}
-}