Replace the Pausers' usage with Waiter/WaitQueue

This commit is contained in:
Chen Chengjun
2024-09-14 10:12:31 +08:00
committed by Tate, Hongliang Tian
parent 822caf34f4
commit 42e28763c5
12 changed files with 110 additions and 91 deletions

View File

@ -14,6 +14,8 @@
//! refer to the man 2 eventfd documentation.
//!
use ostd::sync::WaitQueue;
use super::SyscallReturn;
use crate::{
events::{IoEvents, Observer},
@ -24,7 +26,7 @@ use crate::{
},
prelude::*,
process::{
signal::{Pauser, Pollable, Pollee, Poller},
signal::{Pollable, Pollee, Poller},
Gid, Uid,
},
time::clocks::RealTimeClock,
@ -75,7 +77,7 @@ struct EventFile {
counter: Mutex<u64>,
pollee: Pollee,
flags: Mutex<Flags>,
write_pauser: Arc<Pauser>,
write_wait_queue: WaitQueue,
}
impl EventFile {
@ -84,12 +86,12 @@ impl EventFile {
fn new(init_val: u64, flags: Flags) -> Self {
let counter = Mutex::new(init_val);
let pollee = Pollee::new(IoEvents::OUT);
let write_pauser = Pauser::new();
let write_wait_queue = WaitQueue::new();
Self {
counter,
pollee,
flags: Mutex::new(flags),
write_pauser,
write_wait_queue,
}
}
@ -112,7 +114,7 @@ impl EventFile {
self.pollee.del_events(IoEvents::IN);
}
self.write_pauser.resume_all();
self.write_wait_queue.wake_all();
return;
}
@ -215,7 +217,7 @@ impl FileLike for EventFile {
}
// Wait until counter can be added val to
self.write_pauser
self.write_wait_queue
.pause_until(|| self.add_counter_val(supplied_value).ok())?;
Ok(write_len)

View File

@ -2,10 +2,11 @@
use core::time::Duration;
use ostd::sync::Waiter;
use super::{clock_gettime::read_clock, ClockId, SyscallReturn};
use crate::{
prelude::*,
process::signal::Pauser,
time::{clockid_t, timespec_t, TIMER_ABSTIME},
};
@ -81,9 +82,9 @@ fn do_clock_nanosleep(
// FIXME: sleeping thread can only be interrupted by signals that will call signal handler or terminate
// current process. i.e., the signals that should be ignored will not interrupt sleeping thread.
let pauser = Pauser::new();
let waiter = Waiter::new_pair().0;
let res = pauser.pause_until_or_timeout(|| None, &timeout);
let res = waiter.pause_until_or_timeout(|| None, &timeout);
match res {
Err(e) if e.error() == Errno::ETIME => Ok(SyscallReturn::Return(0)),
Err(e) if e.error() == Errno::EINTR => {

View File

@ -1,14 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
use ostd::sync::Waiter;
use super::SyscallReturn;
use crate::{prelude::*, process::signal::Pauser};
use crate::prelude::*;
pub fn sys_pause(_ctx: &Context) -> Result<SyscallReturn> {
// FIXME: like sleep, paused thread can only be interrupted by signals that will call signal
// handler or terminate current process
let pauser = Pauser::new();
let waiter = Waiter::new_pair().0;
pauser.pause_until(|| None)?;
waiter.pause_until(|| None)?;
unreachable!("[Internal Error] pause should always return EINTR");
}

View File

@ -1,12 +1,14 @@
// SPDX-License-Identifier: MPL-2.0
use ostd::sync::Waiter;
use super::SyscallReturn;
use crate::{
prelude::*,
process::signal::{
constants::{SIGKILL, SIGSTOP},
sig_mask::SigMask,
Pauser,
with_signal_blocked,
},
};
@ -34,9 +36,9 @@ pub fn sys_rt_sigsuspend(
mask
};
// Pause until receiving any signal
let pauser = Pauser::new_with_mask(sigmask);
pauser.pause_until(|| None::<()>)?;
// Wait until receiving any signal
let waiter = Waiter::new_pair().0;
with_signal_blocked(ctx, sigmask, || waiter.pause_until(|| None::<()>))?;
// This syscall should always return `Err(EINTR)`. This path should never be reached.
unreachable!("rt_sigsuspend always return EINTR");

View File

@ -22,7 +22,7 @@ pub fn sys_wait4(
debug!("wait4 current pid = {}", ctx.process.pid());
let process_filter = ProcessFilter::from_id(wait_pid as _);
let waited_process = wait_child_exit(process_filter, wait_options)?;
let waited_process = wait_child_exit(process_filter, wait_options, ctx)?;
let Some(process) = waited_process else {
return Ok(SyscallReturn::Return(0 as _));
};

View File

@ -12,13 +12,13 @@ pub fn sys_waitid(
_infoq_addr: u64,
options: u64,
_rusage_addr: u64,
_ctx: &Context,
ctx: &Context,
) -> Result<SyscallReturn> {
// FIXME: what does infoq and rusage use for?
let process_filter = ProcessFilter::from_which_and_id(which, upid)?;
let wait_options = WaitOptions::from_bits(options as u32)
.ok_or(Error::with_message(Errno::EINVAL, "invalid options"))?;
let waited_process = wait_child_exit(process_filter, wait_options)?;
let waited_process = wait_child_exit(process_filter, wait_options, ctx)?;
let pid = waited_process.map_or(0, |process| process.pid());
Ok(SyscallReturn::Return(pid as _))
}