From c8f4ef07c8ad76d934b720142f52e0a70e1ed273 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 17 Oct 2021 16:21:10 -0500 Subject: [PATCH] added a (maybe function) semaphore implementation --- core/sync/mutex.onyx | 14 +++++++++++++- core/sync/semaphore.onyx | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 core/sync/semaphore.onyx diff --git a/core/sync/mutex.onyx b/core/sync/mutex.onyx index 4b8292b0..ecaf5518 100644 --- a/core/sync/mutex.onyx +++ b/core/sync/mutex.onyx @@ -2,6 +2,18 @@ package core.sync use package core.intrinsics.atomics +// `lock` has two states: 0, and 1. +// 0 means unlocked +// 1 means locked +// +// To lock it: +// Try to store 1 if the value was already 0 +// Otherwise, if it was already 1, wait until it goes to 0. +// +// To unlock it: +// Atomically set it to 0. +// Notify at most 1 other thread about this change. + Mutex :: struct { lock : i32; // owner : Thread_Id; @@ -17,7 +29,7 @@ mutex_destroy :: (m: ^Mutex) { mutex_lock :: (m: ^Mutex) { while __atomic_cmpxchg(^m.lock, 0, 1) == 1 { - __atomic_wait(^m.lock, 0); + __atomic_wait(^m.lock, 1); } } diff --git a/core/sync/semaphore.onyx b/core/sync/semaphore.onyx new file mode 100644 index 00000000..7ecf5f40 --- /dev/null +++ b/core/sync/semaphore.onyx @@ -0,0 +1,37 @@ +package core.sync + +use package core.intrinsics.atomics + +Semaphore :: struct { + mutex : Mutex; + counter : i32; +} + +semaphore_init :: (s: ^Semaphore, value: i32) { + s.counter = value; + + mutex_init(^s.mutex); +} + +semaphore_post :: (s: ^Semaphore) { + scoped_mutex(^s.mutex); + s.counter += 1; + __atomic_notify(^s.counter, maximum = 1); +} + +semaphore_wait :: (s: ^Semaphore) { + while true { + mutex_lock(^s.mutex); + if s.counter > 0 { + s.counter -= 1; + + mutex_unlock(^s.mutex); + return; + + } else { + mutex_unlock(^s.mutex); + + __atomic_wait(^s.counter, 0); + } + } +} \ No newline at end of file -- 2.25.1