Files

35 lines
912 B
C

// SPDX-License-Identifier: ISC
#include <zinnia/atomic.h>
#include <zinnia/condvar.h>
#include <zinnia/park.h>
#include <stdint.h>
void condvar_init(struct condvar* cv) {
atomic_store(&cv->seq, 0, ATOMIC_RELAXED);
atomic_store(&cv->waiters, 0, ATOMIC_RELAXED);
}
void condvar_wait(struct condvar* cv, mutex_t* mutex) {
atomic_fetch_add(&cv->waiters, 1, ATOMIC_SEQ_CST);
uint32_t seq = atomic_load(&cv->seq, ATOMIC_SEQ_CST);
mutex_unlock(mutex);
park_wait(&cv->seq, seq);
atomic_fetch_sub(&cv->waiters, 1, ATOMIC_RELAXED);
mutex_lock(mutex);
}
static void wake(struct condvar* cv, size_t count) {
atomic_fetch_add(&cv->seq, 1, ATOMIC_SEQ_CST);
if (atomic_load(&cv->waiters, ATOMIC_SEQ_CST) != 0)
park_wake(&cv->seq, count);
}
void condvar_signal(struct condvar* cv) {
wake(cv, 1);
}
void condvar_broadcast(struct condvar* cv) {
wake(cv, SIZE_MAX);
}