rwlock: Move over to condvar implementation. (#255)

This one is superior to the previous because it is write-preferring.
This commit is contained in:
plutoo 2019-03-28 23:53:04 +01:00 committed by fincs
parent a4c23a0314
commit b7fe92f3a2
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;
u32 readers : 31;
bool writer : 1;
} 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 == 0) {
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);
} }