Merge pull request #81 from arihant2math/mutex-timeouts

This commit is contained in:
Matthew Leach
2025-12-24 08:08:20 +00:00
committed by GitHub
9 changed files with 74 additions and 7 deletions

View File

@@ -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 _,
)

View File

@@ -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()
}
}

View File

@@ -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)),