From 788df5f556dc950c63599db1fb9416193991e93a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 12 Aug 2025 10:12:05 -0700 Subject: [PATCH] os: barrier --- src/os/core/linux/os_core_linux.c | 66 ++++++++++++++++++++++++------- src/os/core/linux/os_core_linux.h | 2 + src/os/core/os_core.h | 7 +++- src/os/core/win32/os_core_win32.c | 26 ++++++++++++ src/os/core/win32/os_core_win32.h | 2 + 5 files changed, 87 insertions(+), 16 deletions(-) diff --git a/src/os/core/linux/os_core_linux.c b/src/os/core/linux/os_core_linux.c index d8ded967..c61fa270 100644 --- a/src/os/core/linux/os_core_linux.c +++ b/src/os/core/linux/os_core_linux.c @@ -1091,14 +1091,18 @@ internal OS_Handle os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name) { OS_Handle result = {0}; - if (name.size > 0) { + if (name.size > 0) + { // TODO: we need to allocate shared memory to store sem_t // NotImplemented; - } else { + } + else + { sem_t *s = mmap(0, sizeof(*s), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); AssertAlways(s != MAP_FAILED); int err = sem_init(s, 0, initial_count); - if (err == 0) { + if(err == 0) + { result.u64[0] = (U64)s; } } @@ -1127,17 +1131,19 @@ os_semaphore_close(OS_Handle semaphore) internal B32 os_semaphore_take(OS_Handle semaphore, U64 endt_us) { + // TODO(rjf): we need to use `sem_timedwait` here. AssertAlways(endt_us == max_U64); - for (;;) { + for(;;) + { int err = sem_wait((sem_t*)semaphore.u64[0]); - if (err == 0) { + if(err == 0) + { break; - } else { - if (errno == EAGAIN) { - continue; - } } - InvalidPath; + else if(errno == EAGAIN) + { + continue; + } break; } return 1; @@ -1146,20 +1152,50 @@ os_semaphore_take(OS_Handle semaphore, U64 endt_us) internal void os_semaphore_drop(OS_Handle semaphore) { - for (;;) { + for(;;) + { int err = sem_post((sem_t*)semaphore.u64[0]); - if (err == 0) { + if(err == 0) + { break; - } else { - if (errno == EAGAIN) { + } + else + { + if(errno == EAGAIN) + { continue; } } - InvalidPath; break; } } +//- rjf: barriers + +internal OS_Handle +os_barrier_alloc(U64 count) +{ + OS_LNX_Entity *entity = os_w32_entity_alloc(OS_LNX_EntityKind_Barrier); + pthread_barrier_init(&entity->barrier, count); + OS_Handle result = {IntFromPtr(entity)}; + return result; +} + +internal void +os_barrier_release(OS_Handle barrier) +{ + OS_LNX_Entity *entity = (OS_LNX_Entity*)PtrFromInt(barrier.u64[0]); + pthread_barrier_destroy(&entity->barrier); + os_lnx_entity_release(entity); +} + +internal void +os_barrier_wait(OS_Handle barrier) +{ + OS_LNX_Entity *entity = (OS_LNX_Entity*)PtrFromInt(barrier.u64[0]); + pthread_barrier_wait(&entity->barrier); +} + //////////////////////////////// //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS) diff --git a/src/os/core/linux/os_core_linux.h b/src/os/core/linux/os_core_linux.h index 1770d239..4b345a4b 100644 --- a/src/os/core/linux/os_core_linux.h +++ b/src/os/core/linux/os_core_linux.h @@ -67,6 +67,7 @@ typedef enum OS_LNX_EntityKind OS_LNX_EntityKind_Mutex, OS_LNX_EntityKind_RWMutex, OS_LNX_EntityKind_ConditionVariable, + OS_LNX_EntityKind_Barrier, } OS_LNX_EntityKind; @@ -90,6 +91,7 @@ struct OS_LNX_Entity pthread_cond_t cond_handle; pthread_mutex_t rwlock_mutex_handle; } cv; + pthread_barrier_t barrier; }; }; diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 415bb662..158c5185 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -299,7 +299,12 @@ internal void os_semaphore_release(OS_Handle semaphore); internal OS_Handle os_semaphore_open(String8 name); internal void os_semaphore_close(OS_Handle semaphore); internal B32 os_semaphore_take(OS_Handle semaphore, U64 endt_us); -internal void os_semaphore_drop(OS_Handle semaphore); +internal void os_semaphore_drop(OS_Handle semaphore); + +//- rjf: barriers +internal OS_Handle os_barrier_alloc(U64 count); +internal void os_barrier_release(OS_Handle barrier); +internal void os_barrier_wait(OS_Handle barrier); //- rjf: scope macros #define OS_MutexScope(mutex) DeferLoop(os_mutex_take(mutex), os_mutex_drop(mutex)) diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 65d7926d..175ad4f5 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -1352,6 +1352,32 @@ os_semaphore_drop(OS_Handle semaphore) ReleaseSemaphore(handle, 1, 0); } +//- rjf: barriers + +internal OS_Handle +os_barrier_alloc(U64 count) +{ + OS_W32_Entity *entity = os_w32_entity_alloc(OS_W32_EntityKind_Barrier); + InitializeSynchronizationBarrier(&entity->sb, count, -1); + OS_Handle result = {IntFromPtr(entity)}; + return result; +} + +internal void +os_barrier_release(OS_Handle barrier) +{ + OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(barrier.u64[0]); + DeleteSynchronizationBarrier(&entity->sb); + os_w32_entity_release(entity); +} + +internal void +os_barrier_wait(OS_Handle barrier) +{ + OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(barrier.u64[0]); + EnterSynchronizationBarrier(&entity->sb, 0); +} + //////////////////////////////// //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS) diff --git a/src/os/core/win32/os_core_win32.h b/src/os/core/win32/os_core_win32.h index 22a21f80..4938a828 100644 --- a/src/os/core/win32/os_core_win32.h +++ b/src/os/core/win32/os_core_win32.h @@ -46,6 +46,7 @@ typedef enum OS_W32_EntityKind OS_W32_EntityKind_Mutex, OS_W32_EntityKind_RWMutex, OS_W32_EntityKind_ConditionVariable, + OS_W32_EntityKind_Barrier, } OS_W32_EntityKind; @@ -66,6 +67,7 @@ struct OS_W32_Entity CRITICAL_SECTION mutex; SRWLOCK rw_mutex; CONDITION_VARIABLE cv; + SYNCHRONIZATION_BARRIER sb; }; };