Add futex timeout
This commit is contained in:
26
Cargo.lock
generated
26
Cargo.lock
generated
@@ -1,16 +1,3 @@
|
||||
[root]
|
||||
name = "kernel"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"alloc_kernel 0.1.0",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"raw-cpuid 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.31",
|
||||
"spin 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloc_kernel"
|
||||
version = "0.1.0"
|
||||
@@ -43,6 +30,19 @@ dependencies = [
|
||||
"scroll 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"alloc_kernel 0.1.0",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"raw-cpuid 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.31",
|
||||
"spin 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked_list_allocator"
|
||||
version = "0.4.1"
|
||||
|
||||
@@ -4,9 +4,11 @@ use core::intrinsics;
|
||||
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use context::{self, Context};
|
||||
use time;
|
||||
use syscall::data::TimeSpec;
|
||||
use syscall::error::{Error, Result, ESRCH, EAGAIN, EINVAL};
|
||||
use syscall::flag::{FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE};
|
||||
use syscall::validate::validate_slice_mut;
|
||||
use syscall::validate::{validate_slice, validate_slice_mut};
|
||||
|
||||
type FutexList = VecDeque<(usize, Arc<RwLock<Context>>)>;
|
||||
|
||||
@@ -31,6 +33,12 @@ pub fn futexes_mut() -> RwLockWriteGuard<'static, FutexList> {
|
||||
pub fn futex(addr: &mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32) -> Result<usize> {
|
||||
match op {
|
||||
FUTEX_WAIT => {
|
||||
let timeout_opt = if val2 != 0 {
|
||||
Some(validate_slice(val2 as *const TimeSpec, 1).map(|req| &req[0])?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
{
|
||||
let mut futexes = futexes_mut();
|
||||
|
||||
@@ -44,13 +52,37 @@ pub fn futex(addr: &mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32)
|
||||
return Err(Error::new(EAGAIN));
|
||||
}
|
||||
|
||||
context_lock.write().block();
|
||||
{
|
||||
let mut context = context_lock.write();
|
||||
|
||||
if let Some(timeout) = timeout_opt {
|
||||
let start = time::monotonic();
|
||||
let sum = start.1 + timeout.tv_nsec as u64;
|
||||
let end = (start.0 + timeout.tv_sec as u64 + sum / 1000000000, sum % 1000000000);
|
||||
context.wake = Some(end);
|
||||
}
|
||||
|
||||
context.block();
|
||||
}
|
||||
|
||||
futexes.push_back((addr as *mut i32 as usize, context_lock));
|
||||
}
|
||||
|
||||
unsafe { context::switch(); }
|
||||
|
||||
if timeout_opt.is_some() {
|
||||
let context_lock = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
context_lock.clone()
|
||||
};
|
||||
|
||||
{
|
||||
let mut context = context_lock.write();
|
||||
context.wake = None;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
},
|
||||
FUTEX_WAKE => {
|
||||
|
||||
Reference in New Issue
Block a user