// Copyright 2018 plutoo
#include "kernel/mutex.h"
#include "kernel/rwlock.h"
void rwlockInit(RwLock* r) {
mutexInit(&r->mutex);
condvarInit(&r->condvar_readers);
condvarInit(&r->condvar_writer);
r->readers = 0;
r->writer = false;
}
void rwlockReadLock(RwLock* r) {
mutexLock(&r->mutex);
while (r->writer) {
condvarWait(&r->condvar_writer, &r->mutex);
}
r->readers++;
mutexUnlock(&r->mutex);
}
void rwlockReadUnlock(RwLock* r) {
mutexLock(&r->mutex);
if (--r->readers == 0) {
condvarWakeAll(&r->condvar_readers);
}
mutexUnlock(&r->mutex);
}
void rwlockWriteLock(RwLock* r) {
mutexLock(&r->mutex);
while (r->writer) {
condvarWait(&r->condvar_writer, &r->mutex);
}
r->writer = true;
while (r->readers > 0) {
condvarWait(&r->condvar_readers, &r->mutex);
}
mutexUnlock(&r->mutex);
}
void rwlockWriteUnlock(RwLock* r) {
mutexLock(&r->mutex);
r->writer = false;
condvarWakeAll(&r->condvar_writer);
mutexUnlock(&r->mutex);
}