aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sys
diff options
context:
space:
mode:
authorFenrir <[email protected]>2018-01-25 00:02:17 -0700
committerFenrirWolf <[email protected]>2018-01-25 00:26:32 -0700
commitbf6ef666d17db6c7e72696e0de14d75880634209 (patch)
tree28bbc97750e5a927ad6236cb8cbf4d4116b6da59 /ctr-std/src/sys
parentNotify all threads when the write-lock goes out of scope (diff)
downloadctru-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.rs22
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();
}