From 98ad9125095fac3550e25983b31fbd1813923506 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 27 Dec 2020 16:16:04 +0000 Subject: [PATCH] Fix typo --- core/sync/sync.odin | 63 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/core/sync/sync.odin b/core/sync/sync.odin index d74f88a09..b7c832213 100644 --- a/core/sync/sync.odin +++ b/core/sync/sync.odin @@ -1,6 +1,7 @@ package sync -import "core:intrinsics" +import "intrinsics" +import "core:runtime" cpu_relax :: inline proc "contextless" () { intrinsics.cpu_relax(); @@ -61,3 +62,63 @@ benaphore_unlock :: proc(b: ^Benaphore) { semaphore_post(&b.sema); } } + +Recursive_Benaphore :: struct { + counter: int, + owner: int, + recursion: int, + sema: Semaphore, +} + +recursive_benaphore_init :: proc(b: ^Recursive_Benaphore) { + intrinsics.atomic_store(&b.counter, 0); + semaphore_init(&b.sema); +} + +recursive_benaphore_destroy :: proc(b: ^Recursive_Benaphore) { + semaphore_destroy(&b.sema); +} + +recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) { + tid := runtime.current_thread_id(); + if intrinsics.atomic_add_acq(&b.counter, 1) > 1 { + if tid != b.owner { + semaphore_wait_for(&b.sema); + } + } + // inside the lock + b.owner = tid; + b.recursion += 1; +} + +recursive_benaphore_try_lock :: proc(b: ^Recursive_Benaphore) -> bool { + tid := runtime.current_thread_id(); + if b.owner == tid { + intrinsics.atomic_add_acq(&b.counter, 1); + } else { + v, _ := intrinsics.atomic_cxchg_acq(&b.counter, 1, 0); + if v != 0 { + return false; + } + // inside the lock + b.owner = tid; + } + b.recursion += 1; + return true; +} + +recursive_benaphore_unlock :: proc(b: ^Recursive_Benaphore) { + tid := runtime.current_thread_id(); + assert(tid == b.owner); + b.recursion -= 1; + recursion := b.recursion; + if recursion == 0 { + b.owner = 0; + } + if intrinsics.atomic_sub_rel(&b.counter, 1) > 0 { + if recursion == 0 { + semaphore_post(&b.sema); + } + } + // outside the lock +}