Add timeout to futex_wait calls

This commit is contained in:
Jeremy Soller
2022-04-04 20:23:29 -06:00
parent 6d394ba4f4
commit 8576b99759
6 changed files with 25 additions and 13 deletions
+7 -3
View File
@@ -8,6 +8,7 @@ pub use self::{
semaphore::Semaphore,
};
use crate::header::time::timespec;
use crate::platform::{types::*, Pal, Sys};
use core::{
cell::UnsafeCell,
@@ -37,22 +38,25 @@ impl AtomicLock {
}
}
pub fn notify_one(&self) {
Sys::futex(unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAKE, 1);
Sys::futex(unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAKE, 1, 0);
}
pub fn notify_all(&self) {
Sys::futex(
unsafe { &mut *self.atomic.get() }.get_mut(),
FUTEX_WAKE,
c_int::max_value(),
0
);
}
pub fn wait_if(&self, value: c_int) {
pub fn wait_if(&self, value: c_int, timeout_opt: Option<&timespec>) {
Sys::futex(
unsafe { &mut *self.atomic.get() }.get_mut(),
FUTEX_WAIT,
value,
timeout_opt.map_or(0, |timeout| timeout as *const timespec as usize)
);
}
/// A general way to efficiently wait for what might be a long time, using two closures:
///
/// - `attempt` = Attempt to modify the atomic value to any
@@ -103,7 +107,7 @@ impl AtomicLock {
// wait informed us that we might be done waiting
mark_long(self) != AttemptStatus::Desired
{
self.wait_if(long);
self.wait_if(long, None);
}
previous = attempt(self);
+3 -2
View File
@@ -2,6 +2,7 @@
//TODO: improve implementation
use super::AtomicLock;
use crate::header::time::timespec;
use crate::platform::{types::*, Pal, Sys};
use core::sync::atomic::Ordering;
@@ -21,7 +22,7 @@ impl Semaphore {
self.lock.notify_one();
}
pub fn wait(&self) {
pub fn wait(&self, timeout_opt: Option<&timespec>) {
let mut value = 1;
loop {
@@ -38,7 +39,7 @@ impl Semaphore {
}
if value == 0 {
self.lock.wait_if(0);
self.lock.wait_if(0, timeout_opt);
value = 1;
}
}