Fix data races in sync.Recursive_Benaphore

This commit is contained in:
Feoramund
2024-09-11 08:39:23 -04:00
parent b2c2235e58
commit fec1ccd7a3
+16 -15
View File
@@ -449,13 +449,15 @@ recursive benaphore, until the lock is released.
*/ */
recursive_benaphore_lock :: proc "contextless" (b: ^Recursive_Benaphore) { recursive_benaphore_lock :: proc "contextless" (b: ^Recursive_Benaphore) {
tid := current_thread_id() tid := current_thread_id()
if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 { check_owner: if tid != atomic_load_explicit(&b.owner, .Acquire) {
if tid != b.owner { atomic_add_explicit(&b.counter, 1, .Relaxed)
sema_wait(&b.sema) if _, ok := atomic_compare_exchange_strong_explicit(&b.owner, 0, tid, .Release, .Relaxed); ok {
break check_owner
} }
sema_wait(&b.sema)
atomic_store_explicit(&b.owner, tid, .Release)
} }
// inside the lock // inside the lock
b.owner = tid
b.recursion += 1 b.recursion += 1
} }
@@ -472,15 +474,14 @@ benaphore, until the lock is released.
*/ */
recursive_benaphore_try_lock :: proc "contextless" (b: ^Recursive_Benaphore) -> bool { recursive_benaphore_try_lock :: proc "contextless" (b: ^Recursive_Benaphore) -> bool {
tid := current_thread_id() tid := current_thread_id()
if b.owner == tid { check_owner: if tid != atomic_load_explicit(&b.owner, .Acquire) {
atomic_add_explicit(&b.counter, 1, .Acquire) if _, ok := atomic_compare_exchange_strong_explicit(&b.owner, 0, tid, .Release, .Relaxed); ok {
} else { atomic_add_explicit(&b.counter, 1, .Relaxed)
if v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 0, 1, .Acquire, .Acquire); v != 0 { break check_owner
return false
} }
return false
} }
// inside the lock // inside the lock
b.owner = tid
b.recursion += 1 b.recursion += 1
return true return true
} }
@@ -494,14 +495,14 @@ for other threads for entering.
*/ */
recursive_benaphore_unlock :: proc "contextless" (b: ^Recursive_Benaphore) { recursive_benaphore_unlock :: proc "contextless" (b: ^Recursive_Benaphore) {
tid := current_thread_id() tid := current_thread_id()
assert_contextless(tid == b.owner, "tid != b.owner") assert_contextless(tid == atomic_load_explicit(&b.owner, .Relaxed), "tid != b.owner")
b.recursion -= 1 b.recursion -= 1
recursion := b.recursion recursion := b.recursion
if recursion == 0 { if recursion == 0 {
b.owner = 0 if atomic_sub_explicit(&b.counter, 1, .Relaxed) == 1 {
} atomic_store_explicit(&b.owner, 0, .Release)
if atomic_sub_explicit(&b.counter, 1, .Release) > 0 { } else {
if recursion == 0 {
sema_post(&b.sema) sema_post(&b.sema)
} }
} }