Skip to content

Commit 2f68b87

Browse files
committed
Add futex timeout
1 parent 12e6b53 commit 2f68b87

File tree

2 files changed

+38
-22
lines changed

2 files changed

+38
-22
lines changed

src/libstd/sys/redox/condvar.rs

+37-20
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
// except according to those terms.
1010

1111
use cell::UnsafeCell;
12-
use intrinsics::{atomic_cxchg, atomic_xadd, atomic_xchg};
12+
use intrinsics::{atomic_cxchg, atomic_load, atomic_xadd, atomic_xchg};
1313
use ptr;
1414
use time::Duration;
1515

1616
use sys::mutex::{mutex_unlock, Mutex};
17-
use sys::syscall::{futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE};
17+
use sys::syscall::{futex, TimeSpec, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE};
1818

1919
pub struct Condvar {
2020
lock: UnsafeCell<*mut i32>,
@@ -63,33 +63,50 @@ impl Condvar {
6363
}
6464

6565
#[inline]
66-
pub fn wait(&self, mutex: &Mutex) {
67-
unsafe {
68-
let lock = self.lock.get();
69-
let seq = self.seq.get();
70-
71-
if *lock != mutex.lock.get() {
72-
if *lock != ptr::null_mut() {
73-
panic!("Condvar used with more than one Mutex");
74-
}
66+
unsafe fn wait_inner(&self, mutex: &Mutex, timeout_ptr: *const TimeSpec) -> bool {
67+
let lock = self.lock.get();
68+
let seq = self.seq.get();
7569

76-
atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize);
70+
if *lock != mutex.lock.get() {
71+
if *lock != ptr::null_mut() {
72+
panic!("Condvar used with more than one Mutex");
7773
}
7874

79-
mutex_unlock(*lock);
75+
atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize);
76+
}
8077

81-
let _ = futex(seq, FUTEX_WAIT, *seq, 0, ptr::null_mut());
78+
mutex_unlock(*lock);
8279

83-
while atomic_xchg(*lock, 2) != 0 {
84-
let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut());
85-
}
80+
let seq_before = atomic_load(seq);
81+
82+
let _ = futex(seq, FUTEX_WAIT, seq_before, timeout_ptr as usize, ptr::null_mut());
83+
84+
let seq_after = atomic_load(seq);
85+
86+
while atomic_xchg(*lock, 2) != 0 {
87+
let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut());
88+
}
89+
90+
seq_before != seq_after
91+
}
92+
93+
#[inline]
94+
pub fn wait(&self, mutex: &Mutex) {
95+
unsafe {
96+
assert!(self.wait_inner(mutex, ptr::null()));
8697
}
8798
}
8899

89100
#[inline]
90-
pub fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
91-
::sys_common::util::dumb_print(format_args!("condvar wait_timeout\n"));
92-
unimplemented!();
101+
pub fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
102+
unsafe {
103+
let timeout = TimeSpec {
104+
tv_sec: dur.as_secs() as i64,
105+
tv_nsec: dur.subsec_nanos() as i32
106+
};
107+
108+
self.wait_inner(mutex, &timeout as *const TimeSpec)
109+
}
93110
}
94111

95112
#[inline]

src/libstd/sys/redox/fs.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,7 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
437437
}
438438

439439
pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
440-
::sys_common::util::dumb_print(format_args!("Link\n"));
441-
unimplemented!();
440+
Err(Error::from_raw_os_error(syscall::ENOSYS))
442441
}
443442

444443
pub fn stat(p: &Path) -> io::Result<FileAttr> {

0 commit comments

Comments
 (0)