Add condvars and events via parking lot
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
// 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);
|
||||
}
|
||||
Reference in New Issue
Block a user