mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-01-30 09:01:44 -05:00
Merge pull request #81 from arihant2math/mutex-timeouts
This commit is contained in:
13
Cargo.lock
generated
13
Cargo.lock
generated
@@ -106,6 +106,17 @@ version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.31"
|
||||
@@ -125,6 +136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
@@ -530,6 +542,7 @@ name = "usertest"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -20,7 +20,7 @@ async-trait = "0.1.88"
|
||||
getargs = { version = "0.5.0", default-features = false }
|
||||
ringbuf = { version = "0.4.8", default-features = false, features = ["alloc"] }
|
||||
bitflags = "2.9.1"
|
||||
futures = { version = "0.3.31", default-features = false, features = ["alloc"] }
|
||||
futures = { version = "0.3.31", default-features = false, features = ["alloc", "async-await"] }
|
||||
rand = { version = "0.9.2", default-features = false, features = ["small_rng"] }
|
||||
|
||||
[profile.release]
|
||||
|
||||
@@ -168,6 +168,9 @@ pub enum KernelError {
|
||||
#[error("No such process")]
|
||||
NoProcess,
|
||||
|
||||
#[error("Operation timed out")]
|
||||
TimedOut,
|
||||
|
||||
#[error("{0}")]
|
||||
Other(&'static str),
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ pub const EDOM: isize = -33;
|
||||
pub const ERANGE: isize = -34;
|
||||
pub const EWOULDBLOCK: isize = -EAGAIN;
|
||||
pub const ENOSYS: isize = -38;
|
||||
pub const ETIMEDOUT: isize = -110;
|
||||
|
||||
pub fn kern_err_to_syscall(err: KernelError) -> isize {
|
||||
match err {
|
||||
@@ -51,6 +52,7 @@ pub fn kern_err_to_syscall(err: KernelError) -> isize {
|
||||
KernelError::SeekPipe => ESPIPE,
|
||||
KernelError::NotSupported => ENOSYS,
|
||||
KernelError::NoMemory => ENOMEM,
|
||||
KernelError::TimedOut => ETIMEDOUT,
|
||||
e => todo!("{e}"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ pub async fn handle_syscall() {
|
||||
TUA::from_value(arg1 as _),
|
||||
arg2 as _,
|
||||
arg3 as _,
|
||||
VA::from_value(arg4 as _),
|
||||
TUA::from_value(arg4 as _),
|
||||
TUA::from_value(arg5 as _),
|
||||
arg6 as _,
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
drivers::timer::{Instant, now},
|
||||
drivers::timer::{Instant, now, uptime},
|
||||
sync::SpinLock,
|
||||
};
|
||||
use core::time::Duration;
|
||||
@@ -14,7 +14,7 @@ pub fn date() -> Duration {
|
||||
let duraton_since_ep_info = now - ep_info.1;
|
||||
ep_info.0 + duraton_since_ep_info
|
||||
} else {
|
||||
Duration::new(0, 0)
|
||||
uptime()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
use crate::clock::realtime::date;
|
||||
use crate::clock::timespec::TimeSpec;
|
||||
use crate::drivers::timer::sleep;
|
||||
use crate::sync::{OnceLock, SpinLock};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::{collections::btree_map::BTreeMap, sync::Arc};
|
||||
use core::time::Duration;
|
||||
use futures::FutureExt;
|
||||
use key::FutexKey;
|
||||
use libkernel::{
|
||||
error::{KernelError, Result},
|
||||
memory::address::{TUA, VA},
|
||||
memory::address::TUA,
|
||||
sync::waker_set::WakerSet,
|
||||
};
|
||||
use wait::FutexWait;
|
||||
@@ -60,7 +66,7 @@ pub async fn sys_futex(
|
||||
uaddr: TUA<u32>,
|
||||
op: i32,
|
||||
val: u32,
|
||||
_timeout: VA,
|
||||
timeout: TUA<TimeSpec>,
|
||||
_uaddr2: TUA<u32>,
|
||||
_val3: u32,
|
||||
) -> Result<usize> {
|
||||
@@ -74,13 +80,36 @@ pub async fn sys_futex(
|
||||
};
|
||||
|
||||
// TODO: support bitset variants properly
|
||||
let timeout = if timeout.is_null() {
|
||||
None
|
||||
} else {
|
||||
let timeout = TimeSpec::copy_from_user(timeout).await?;
|
||||
if matches!(cmd, FUTEX_WAIT_BITSET) {
|
||||
Some(Duration::from(timeout) - date())
|
||||
} else {
|
||||
Some(Duration::from(timeout))
|
||||
}
|
||||
};
|
||||
match cmd {
|
||||
FUTEX_WAIT | FUTEX_WAIT_BITSET => {
|
||||
// Obtain (or create) the wait-queue for this futex word.
|
||||
let slot = get_or_create_queue(key);
|
||||
|
||||
// Return 0 on success.
|
||||
FutexWait::new(uaddr, val, slot).await.map(|_| 0)
|
||||
if let Some(dur) = timeout {
|
||||
let mut wait = FutexWait::new(uaddr, val, slot).fuse();
|
||||
let mut sleep = Box::pin(sleep(dur).fuse());
|
||||
futures::select_biased! {
|
||||
res = wait => {
|
||||
res.map(|_| 0)
|
||||
},
|
||||
_ = sleep => {
|
||||
Err(KernelError::TimedOut)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FutexWait::new(uaddr, val, slot).await.map(|_| 0)
|
||||
}
|
||||
}
|
||||
|
||||
FUTEX_WAKE | FUTEX_WAKE_BITSET => Ok(wake_key(val as _, key)),
|
||||
|
||||
@@ -5,3 +5,4 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
parking_lot = "0.12"
|
||||
|
||||
@@ -451,6 +451,24 @@ fn test_rust_mutex() {
|
||||
println!(" OK");
|
||||
}
|
||||
|
||||
fn test_parking_lot_mutex_timeout() {
|
||||
print!("Testing parking_lot mutex with timeout ...");
|
||||
use parking_lot::Mutex;
|
||||
use std::time::Duration;
|
||||
let mtx = Arc::new(Mutex::new(()));
|
||||
let mtx_clone = Arc::clone(&mtx);
|
||||
let guard = mtx.lock();
|
||||
// Now try to acquire the lock with a timeout in another thread
|
||||
let handle = thread::spawn(move || {
|
||||
let timeout = Duration::from_millis(100);
|
||||
let result = mtx_clone.try_lock_for(timeout);
|
||||
assert!(result.is_none(), "Expected to not acquire the lock");
|
||||
});
|
||||
handle.join().unwrap();
|
||||
drop(guard);
|
||||
println!(" OK");
|
||||
}
|
||||
|
||||
fn run_test(test_fn: fn()) {
|
||||
// Fork a new process to run the test
|
||||
unsafe {
|
||||
@@ -495,6 +513,7 @@ fn main() {
|
||||
run_test(test_rust_dir);
|
||||
run_test(test_rust_thread);
|
||||
run_test(test_rust_mutex);
|
||||
run_test(test_parking_lot_mutex_timeout);
|
||||
let end = std::time::Instant::now();
|
||||
println!("All tests passed in {} ms", (end - start).as_millis());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user