Files
zinnia/lib/semaphore.c
T
2026-10-28 21:46:25 +01:00

41 lines
1.0 KiB
C

// SPDX-License-Identifier: ISC
#include <zinnia/atomic.h>
#include <zinnia/park.h>
#include <zinnia/semaphore.h>
void sem_init(sem_t* sem, uint32_t count) {
atomic_store(&sem->count, count, ATOMIC_RELAXED);
}
bool sem_trywait(sem_t* sem) {
uint32_t count = atomic_load(&sem->count, ATOMIC_RELAXED);
while (count) {
if (atomic_compare_exchange_weak(&sem->count, &count, count - 1, ATOMIC_ACQUIRE, ATOMIC_RELAXED))
return true;
}
return false;
}
static bool sem_empty(void* ctx) {
sem_t* sem = ctx;
return atomic_load(&sem->count, ATOMIC_RELAXED) == 0;
}
bool sem_timedwait(sem_t* sem, const uint64_t* deadline_ns) {
while (!sem_trywait(sem)) {
if (park_timeout(sem, sem_empty, nullptr, sem, 0, deadline_ns).status == PARK_TIMED_OUT)
return sem_trywait(sem);
}
return true;
}
void sem_wait(sem_t* sem) {
sem_timedwait(sem, nullptr);
}
void sem_post(sem_t* sem) {
atomic_fetch_add(&sem->count, 1, ATOMIC_RELEASE);
unpark_one(sem, nullptr, nullptr);
}