about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeremy Soller <jackpot51@gmail.com>2017-11-06 22:05:20 -0700
committerJeremy Soller <jeremy@system76.com>2017-11-09 13:15:18 -0700
commit2f68b870b5111e45af24e80a5014ad21c657a02c (patch)
tree2db2c0ec6769364acc4ca146c4a2d5d2c27a82e1
parent12e6b53744a0101f28855f25e6e4551e2d664857 (diff)
downloadrust-2f68b870b5111e45af24e80a5014ad21c657a02c.tar.gz
rust-2f68b870b5111e45af24e80a5014ad21c657a02c.zip
Add futex timeout
-rw-r--r--src/libstd/sys/redox/condvar.rs57
-rw-r--r--src/libstd/sys/redox/fs.rs3
2 files changed, 38 insertions, 22 deletions
diff --git a/src/libstd/sys/redox/condvar.rs b/src/libstd/sys/redox/condvar.rs
index fe4a89c6f3e..2a611ed7dab 100644
--- a/src/libstd/sys/redox/condvar.rs
+++ b/src/libstd/sys/redox/condvar.rs
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 use cell::UnsafeCell;
-use intrinsics::{atomic_cxchg, atomic_xadd, atomic_xchg};
+use intrinsics::{atomic_cxchg, atomic_load, atomic_xadd, atomic_xchg};
 use ptr;
 use time::Duration;
 
 use sys::mutex::{mutex_unlock, Mutex};
-use sys::syscall::{futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE};
+use sys::syscall::{futex, TimeSpec, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE};
 
 pub struct Condvar {
     lock: UnsafeCell<*mut i32>,
@@ -63,33 +63,50 @@ impl Condvar {
     }
 
     #[inline]
-    pub fn wait(&self, mutex: &Mutex) {
-        unsafe {
-            let lock = self.lock.get();
-            let seq = self.seq.get();
-
-            if *lock != mutex.lock.get() {
-                if *lock != ptr::null_mut() {
-                    panic!("Condvar used with more than one Mutex");
-                }
+    unsafe fn wait_inner(&self, mutex: &Mutex, timeout_ptr: *const TimeSpec) -> bool {
+        let lock = self.lock.get();
+        let seq = self.seq.get();
 
-                atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize);
+        if *lock != mutex.lock.get() {
+            if *lock != ptr::null_mut() {
+                panic!("Condvar used with more than one Mutex");
             }
 
-            mutex_unlock(*lock);
+            atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize);
+        }
 
-            let _ = futex(seq, FUTEX_WAIT, *seq, 0, ptr::null_mut());
+        mutex_unlock(*lock);
 
-            while atomic_xchg(*lock, 2) != 0 {
-                let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut());
-            }
+        let seq_before = atomic_load(seq);
+
+        let _ = futex(seq, FUTEX_WAIT, seq_before, timeout_ptr as usize, ptr::null_mut());
+
+        let seq_after = atomic_load(seq);
+
+        while atomic_xchg(*lock, 2) != 0 {
+            let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut());
+        }
+
+        seq_before != seq_after
+    }
+
+    #[inline]
+    pub fn wait(&self, mutex: &Mutex) {
+        unsafe {
+            assert!(self.wait_inner(mutex, ptr::null()));
         }
     }
 
     #[inline]
-    pub fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
-        ::sys_common::util::dumb_print(format_args!("condvar wait_timeout\n"));
-        unimplemented!();
+    pub fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        unsafe {
+            let timeout = TimeSpec {
+                tv_sec: dur.as_secs() as i64,
+                tv_nsec: dur.subsec_nanos() as i32
+            };
+
+            self.wait_inner(mutex, &timeout as *const TimeSpec)
+        }
     }
 
     #[inline]
diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs
index 918893097f8..3483477d40c 100644
--- a/src/libstd/sys/redox/fs.rs
+++ b/src/libstd/sys/redox/fs.rs
@@ -437,8 +437,7 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
 }
 
 pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
-    ::sys_common::util::dumb_print(format_args!("Link\n"));
-    unimplemented!();
+    Err(Error::from_raw_os_error(syscall::ENOSYS))
 }
 
 pub fn stat(p: &Path) -> io::Result<FileAttr> {