summary refs log tree commit diff
path: root/src/libstd/sys/redox/mutex.rs
diff options
context:
space:
mode:
authorJeremy Soller <jackpot51@gmail.com>2016-10-27 20:57:49 -0600
committerJeremy Soller <jackpot51@gmail.com>2016-10-27 20:57:49 -0600
commit8b09e01fef9912e7c3eef997c40f9f4f91d09e4c (patch)
treeab28c5cd1bb526809e12e316ea2b3c2135f72f28 /src/libstd/sys/redox/mutex.rs
parent07436946b6ee6345509b73c6e4dafb38b6a243f1 (diff)
downloadrust-8b09e01fef9912e7c3eef997c40f9f4f91d09e4c.tar.gz
rust-8b09e01fef9912e7c3eef997c40f9f4f91d09e4c.zip
Add redox system
Diffstat (limited to 'src/libstd/sys/redox/mutex.rs')
-rw-r--r--src/libstd/sys/redox/mutex.rs125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/libstd/sys/redox/mutex.rs b/src/libstd/sys/redox/mutex.rs
new file mode 100644
index 00000000000..5723443785a
--- /dev/null
+++ b/src/libstd/sys/redox/mutex.rs
@@ -0,0 +1,125 @@
+use cell::UnsafeCell;
+use intrinsics::{atomic_cxchg, atomic_xchg};
+use ptr;
+
+use libc::{futex, FUTEX_WAIT, FUTEX_WAKE};
+
+pub unsafe fn mutex_try_lock(m: *mut i32) -> bool {
+    atomic_cxchg(m, 0, 1).0 == 0
+}
+
+pub unsafe fn mutex_lock(m: *mut i32) {
+    let mut c = 0;
+    //Set to larger value for longer spin test
+    for _i in 0..100 {
+        c = atomic_cxchg(m, 0, 1).0;
+        if c == 0 {
+            break;
+        }
+        //cpu_relax()
+    }
+    if c == 1 {
+        c = atomic_xchg(m, 2);
+    }
+    while c != 0 {
+        let _ = futex(m, FUTEX_WAIT, 2, 0, ptr::null_mut());
+        c = atomic_xchg(m, 2);
+    }
+}
+
+pub unsafe fn mutex_unlock(m: *mut i32) {
+    if *m == 2 {
+        *m = 0;
+    } else if atomic_xchg(m, 0) == 1 {
+        return;
+    }
+    //Set to larger value for longer spin test
+    for _i in 0..100 {
+        if *m != 0 {
+            if atomic_cxchg(m, 1, 2).0 != 0 {
+                return;
+            }
+        }
+        //cpu_relax()
+    }
+    let _ = futex(m, FUTEX_WAKE, 1, 0, ptr::null_mut());
+}
+
+pub struct Mutex {
+    pub lock: UnsafeCell<i32>,
+}
+
+impl Mutex {
+    /// Create a new mutex.
+    pub const fn new() -> Self {
+        Mutex {
+            lock: UnsafeCell::new(0),
+        }
+    }
+
+    pub unsafe fn init(&self) {
+
+    }
+
+    /// Try to lock the mutex
+    pub unsafe fn try_lock(&self) -> bool {
+        mutex_try_lock(self.lock.get())
+    }
+
+    /// Lock the mutex
+    pub unsafe fn lock(&self) {
+        mutex_lock(self.lock.get());
+    }
+
+    /// Unlock the mutex
+    pub unsafe fn unlock(&self) {
+        mutex_unlock(self.lock.get());
+    }
+
+    pub unsafe fn destroy(&self) {
+
+    }
+}
+
+unsafe impl Send for Mutex {}
+
+unsafe impl Sync for Mutex {}
+
+pub struct ReentrantMutex {
+    pub lock: UnsafeCell<i32>,
+}
+
+impl ReentrantMutex {
+    pub const fn uninitialized() -> Self {
+        ReentrantMutex {
+            lock: UnsafeCell::new(0),
+        }
+    }
+
+    pub unsafe fn init(&mut self) {
+
+    }
+
+    /// Try to lock the mutex
+    pub unsafe fn try_lock(&self) -> bool {
+        mutex_try_lock(self.lock.get())
+    }
+
+    /// Lock the mutex
+    pub unsafe fn lock(&self) {
+        mutex_lock(self.lock.get());
+    }
+
+    /// Unlock the mutex
+    pub unsafe fn unlock(&self) {
+        mutex_unlock(self.lock.get());
+    }
+
+    pub unsafe fn destroy(&self) {
+
+    }
+}
+
+unsafe impl Send for ReentrantMutex {}
+
+unsafe impl Sync for ReentrantMutex {}