rwlock: Move over to condvar implementation.

This one is superior to the previous because it is write-preferring.
This commit is contained in:
plutooo 2019-03-24 00:21:18 +01:00
parent b897c3a650
commit e48496ccf4
2 changed files with 43 additions and 16 deletions

View File

@ -6,12 +6,15 @@
*/ */
#pragma once #pragma once
#include "../kernel/mutex.h" #include "../kernel/mutex.h"
#include "../kernel/condvar.h"
/// Read/write lock structure. /// Read/write lock structure.
typedef struct { typedef struct {
RMutex r; Mutex mutex;
RMutex g; CondVar condvar_readers;
u64 b; CondVar condvar_writer;
u64 readers;
bool writer;
} RwLock; } RwLock;
/** /**

View File

@ -3,33 +3,57 @@
#include "kernel/rwlock.h" #include "kernel/rwlock.h"
void rwlockInit(RwLock* r) { void rwlockInit(RwLock* r) {
rmutexInit(&r->r); mutexInit(&r->mutex);
rmutexInit(&r->g); condvarInit(&r->condvar_readers);
r->b = 0; condvarInit(&r->condvar_writer);
r->readers = 0;
r->writer = false;
} }
void rwlockReadLock(RwLock* r) { void rwlockReadLock(RwLock* r) {
rmutexLock(&r->r); mutexLock(&r->mutex);
if (r->b++ == 0) while (r->writer) {
rmutexLock(&r->g); condvarWait(&r->condvar_writer, &r->mutex);
}
rmutexUnlock(&r->r); r->readers++;
mutexUnlock(&r->mutex);
} }
void rwlockReadUnlock(RwLock* r) { void rwlockReadUnlock(RwLock* r) {
rmutexLock(&r->r); mutexLock(&r->mutex);
if (r->b-- == 1) if (r->readers-- == 1) {
rmutexUnlock(&r->g); condvarWakeAll(&r->condvar_readers);
}
rmutexUnlock(&r->r); mutexUnlock(&r->mutex);
} }
void rwlockWriteLock(RwLock* r) { void rwlockWriteLock(RwLock* r) {
rmutexLock(&r->g); 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) { void rwlockWriteUnlock(RwLock* r) {
rmutexUnlock(&r->g); mutexLock(&r->mutex);
r->writer = false;
condvarWakeAll(&r->condvar_writer);
mutexUnlock(&r->mutex);
} }