diff options
| author | kennytm <kennytm@gmail.com> | 2017-11-13 17:09:42 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-13 17:09:42 +0800 |
| commit | 331862ef1169734ed33469b662c48b050c7d65d6 (patch) | |
| tree | a9aeed5ea1b7196eabc1c155e16ccaf6cc6b2086 /src/libstd | |
| parent | 563af5d2607d8e7e4205de5a04c9c7e7c4582677 (diff) | |
| parent | 2f68b870b5111e45af24e80a5014ad21c657a02c (diff) | |
| download | rust-331862ef1169734ed33469b662c48b050c7d65d6.tar.gz rust-331862ef1169734ed33469b662c48b050c7d65d6.zip | |
Rollup merge of #45893 - redox-os:futex_timeout, r=alexcrichton
Redox: Use futex timeout to implement CondVar::wait_timeout `CondVar::wait_timeout` is implemented by supplying a `TimeSpec` pointer to `futex`. In addition, all calls to `unimplemented!()` have been removed from the Redox `sys` module. Related to https://github.com/rust-lang/rust/pull/45892
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/sys/redox/condvar.rs | 57 | ||||
| -rw-r--r-- | src/libstd/sys/redox/fs.rs | 3 |
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> { |
