os: barrier

This commit is contained in:
Ryan Fleury
2025-08-12 10:12:05 -07:00
parent a8f6142e63
commit 788df5f556
5 changed files with 87 additions and 16 deletions
+51 -15
View File
@@ -1091,14 +1091,18 @@ internal OS_Handle
os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name) os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name)
{ {
OS_Handle result = {0}; OS_Handle result = {0};
if (name.size > 0) { if (name.size > 0)
{
// TODO: we need to allocate shared memory to store sem_t // TODO: we need to allocate shared memory to store sem_t
// NotImplemented; // NotImplemented;
} else { }
else
{
sem_t *s = mmap(0, sizeof(*s), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); sem_t *s = mmap(0, sizeof(*s), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
AssertAlways(s != MAP_FAILED); AssertAlways(s != MAP_FAILED);
int err = sem_init(s, 0, initial_count); int err = sem_init(s, 0, initial_count);
if (err == 0) { if(err == 0)
{
result.u64[0] = (U64)s; result.u64[0] = (U64)s;
} }
} }
@@ -1127,17 +1131,19 @@ os_semaphore_close(OS_Handle semaphore)
internal B32 internal B32
os_semaphore_take(OS_Handle semaphore, U64 endt_us) os_semaphore_take(OS_Handle semaphore, U64 endt_us)
{ {
// TODO(rjf): we need to use `sem_timedwait` here.
AssertAlways(endt_us == max_U64); AssertAlways(endt_us == max_U64);
for (;;) { for(;;)
{
int err = sem_wait((sem_t*)semaphore.u64[0]); int err = sem_wait((sem_t*)semaphore.u64[0]);
if (err == 0) { if(err == 0)
{
break; break;
} else {
if (errno == EAGAIN) {
continue;
}
} }
InvalidPath; else if(errno == EAGAIN)
{
continue;
}
break; break;
} }
return 1; return 1;
@@ -1146,20 +1152,50 @@ os_semaphore_take(OS_Handle semaphore, U64 endt_us)
internal void internal void
os_semaphore_drop(OS_Handle semaphore) os_semaphore_drop(OS_Handle semaphore)
{ {
for (;;) { for(;;)
{
int err = sem_post((sem_t*)semaphore.u64[0]); int err = sem_post((sem_t*)semaphore.u64[0]);
if (err == 0) { if(err == 0)
{
break; break;
} else { }
if (errno == EAGAIN) { else
{
if(errno == EAGAIN)
{
continue; continue;
} }
} }
InvalidPath;
break; 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) //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
+2
View File
@@ -67,6 +67,7 @@ typedef enum OS_LNX_EntityKind
OS_LNX_EntityKind_Mutex, OS_LNX_EntityKind_Mutex,
OS_LNX_EntityKind_RWMutex, OS_LNX_EntityKind_RWMutex,
OS_LNX_EntityKind_ConditionVariable, OS_LNX_EntityKind_ConditionVariable,
OS_LNX_EntityKind_Barrier,
} }
OS_LNX_EntityKind; OS_LNX_EntityKind;
@@ -90,6 +91,7 @@ struct OS_LNX_Entity
pthread_cond_t cond_handle; pthread_cond_t cond_handle;
pthread_mutex_t rwlock_mutex_handle; pthread_mutex_t rwlock_mutex_handle;
} cv; } cv;
pthread_barrier_t barrier;
}; };
}; };
+5
View File
@@ -301,6 +301,11 @@ internal void os_semaphore_close(OS_Handle semaphore);
internal B32 os_semaphore_take(OS_Handle semaphore, U64 endt_us); 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 //- rjf: scope macros
#define OS_MutexScope(mutex) DeferLoop(os_mutex_take(mutex), os_mutex_drop(mutex)) #define OS_MutexScope(mutex) DeferLoop(os_mutex_take(mutex), os_mutex_drop(mutex))
#define OS_MutexScopeR(mutex) DeferLoop(os_rw_mutex_take_r(mutex), os_rw_mutex_drop_r(mutex)) #define OS_MutexScopeR(mutex) DeferLoop(os_rw_mutex_take_r(mutex), os_rw_mutex_drop_r(mutex))
+26
View File
@@ -1352,6 +1352,32 @@ os_semaphore_drop(OS_Handle semaphore)
ReleaseSemaphore(handle, 1, 0); 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) //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
+2
View File
@@ -46,6 +46,7 @@ typedef enum OS_W32_EntityKind
OS_W32_EntityKind_Mutex, OS_W32_EntityKind_Mutex,
OS_W32_EntityKind_RWMutex, OS_W32_EntityKind_RWMutex,
OS_W32_EntityKind_ConditionVariable, OS_W32_EntityKind_ConditionVariable,
OS_W32_EntityKind_Barrier,
} }
OS_W32_EntityKind; OS_W32_EntityKind;
@@ -66,6 +67,7 @@ struct OS_W32_Entity
CRITICAL_SECTION mutex; CRITICAL_SECTION mutex;
SRWLOCK rw_mutex; SRWLOCK rw_mutex;
CONDITION_VARIABLE cv; CONDITION_VARIABLE cv;
SYNCHRONIZATION_BARRIER sb;
}; };
}; };