diff options
| author | Fenrir <[email protected]> | 2018-01-25 00:02:17 -0700 |
|---|---|---|
| committer | FenrirWolf <[email protected]> | 2018-01-25 00:26:32 -0700 |
| commit | bf6ef666d17db6c7e72696e0de14d75880634209 (patch) | |
| tree | 28bbc97750e5a927ad6236cb8cbf4d4116b6da59 /ctr-std/src/sys | |
| parent | Notify all threads when the write-lock goes out of scope (diff) | |
| download | ctru-rs-bf6ef666d17db6c7e72696e0de14d75880634209.tar.xz ctru-rs-bf6ef666d17db6c7e72696e0de14d75880634209.zip | |
Increase reader count + style fixes
Diffstat (limited to 'ctr-std/src/sys')
| -rw-r--r-- | ctr-std/src/sys/unix/rwlock.rs | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/ctr-std/src/sys/unix/rwlock.rs b/ctr-std/src/sys/unix/rwlock.rs index 76d2271..4a802e9 100644 --- a/ctr-std/src/sys/unix/rwlock.rs +++ b/ctr-std/src/sys/unix/rwlock.rs @@ -16,7 +16,7 @@ use super::condvar::Condvar; pub struct RWLock { mutex: Mutex, cvar: Condvar, - reader_count: UnsafeCell<u8>, // Is 255 potential readers enough? I would hope so, but idk + reader_count: UnsafeCell<u32>, writer_active: UnsafeCell<bool>, } @@ -36,10 +36,14 @@ impl RWLock { #[inline] pub unsafe fn read(&self) { self.mutex.lock(); + while *self.writer_active.get() { self.cvar.wait(&self.mutex); } + + assert!(*self.reader_count.get() != u32::max_value()); *self.reader_count.get() += 1; + self.mutex.unlock(); } @@ -52,19 +56,24 @@ impl RWLock { while *self.writer_active.get() { self.cvar.wait(&self.mutex); } + + assert!(*self.reader_count.get() != u32::max_value()); *self.reader_count.get() += 1; - self.mutex.unlock(); + self.mutex.unlock(); true } #[inline] pub unsafe fn write(&self) { self.mutex.lock(); + while *self.writer_active.get() || *self.reader_count.get() > 0 { self.cvar.wait(&self.mutex); } + *self.writer_active.get() = true; + self.mutex.unlock(); } @@ -77,27 +86,34 @@ impl RWLock { while *self.writer_active.get() || *self.reader_count.get() > 0 { self.cvar.wait(&self.mutex); } + *self.writer_active.get() = true; - self.mutex.unlock(); + self.mutex.unlock(); true } #[inline] pub unsafe fn read_unlock(&self) { self.mutex.lock(); + *self.reader_count.get() -= 1; + if *self.reader_count.get() == 0 { self.cvar.notify_one() } + self.mutex.unlock(); } #[inline] pub unsafe fn write_unlock(&self) { self.mutex.lock(); + *self.writer_active.get() = false; + self.cvar.notify_all(); + self.mutex.unlock(); } |