Make Pauser work in raw tasks

This commit is contained in:
Ruihan Li
2024-07-11 01:41:24 +08:00
committed by Tate, Hongliang Tian
parent 8f64a1cb90
commit ceb0ef67e1
7 changed files with 41 additions and 32 deletions

View File

@ -30,11 +30,20 @@ macro_rules! current {
};
}
/// return current thread
/// Returns the current thread.
///
/// # Panics
///
/// This macro will panic if the current task is not associated with a thread.
///
/// Except for unit tests, all tasks should be associated with threads. To write code that can be
/// called directly in unit tests, consider using [`Thread::current`] instead.
///
/// [`Thread::current`]: crate::thread::Thread::current
#[macro_export]
macro_rules! current_thread {
() => {
$crate::thread::Thread::current()
$crate::thread::Thread::current().expect("the current task is not associated with a thread")
};
}

View File

@ -641,7 +641,7 @@ impl Process {
}
pub fn current() -> Arc<Process> {
let current_thread = Thread::current();
let current_thread = current_thread!();
if let Some(posix_thread) = current_thread.as_posix_thread() {
posix_thread.process()
} else {

View File

@ -18,14 +18,12 @@ use ostd::{
use super::Process;
use crate::{
prelude::*,
process::{
posix_thread::PosixThreadExt,
signal::{constants::SIGALRM, signals::kernel::KernelSignal},
},
thread::{
work_queue::{submit_work_item, work_item::WorkItem},
Thread,
},
thread::work_queue::{submit_work_item, work_item::WorkItem},
time::{
clocks::{ProfClock, RealTimeClock},
Timer, TimerManager,
@ -38,7 +36,7 @@ use crate::{
/// invoke the callbacks of expired timers which are based on the updated
/// CPU clock.
fn update_cpu_time() {
let current_thread = Thread::current();
let current_thread = current_thread!();
if let Some(posix_thread) = current_thread.as_posix_thread() {
let process = posix_thread.process();
let timer_manager = process.timer_manager();

View File

@ -123,9 +123,9 @@ impl Pauser {
where
F: FnMut() -> Option<R>,
{
let current_thread = current_thread!();
let current_thread = Thread::current();
let sig_queue_waiter =
SigObserverRegistrar::new(&current_thread, self.sig_mask, self.clone());
SigObserverRegistrar::new(current_thread.as_ref(), self.sig_mask, self.clone());
let cond = || {
if let Some(res) = cond() {
@ -174,8 +174,12 @@ enum SigObserverRegistrar<'a> {
}
impl<'a> SigObserverRegistrar<'a> {
fn new(current_thread: &'a Arc<Thread>, sig_mask: SigMask, pauser: Arc<Pauser>) -> Self {
let Some(thread) = current_thread.as_posix_thread() else {
fn new(
current_thread: Option<&'a Arc<Thread>>,
sig_mask: SigMask,
pauser: Arc<Pauser>,
) -> Self {
let Some(thread) = current_thread.and_then(|thread| thread.as_posix_thread()) else {
return Self::KernelThread;
};
@ -281,19 +285,17 @@ mod test {
let boolean = Arc::new(AtomicBool::new(false));
let boolean_cloned = boolean.clone();
let thread1 = Thread::spawn_kernel_thread(ThreadOptions::new(move || {
pauser
.pause_until(|| boolean.load(Ordering::Relaxed).then_some(()))
.unwrap();
}));
let thread2 = Thread::spawn_kernel_thread(ThreadOptions::new(move || {
let thread = Thread::spawn_kernel_thread(ThreadOptions::new(move || {
Thread::yield_now();
boolean_cloned.store(true, Ordering::Relaxed);
pauser_cloned.resume_all();
}));
thread1.join();
thread2.join();
pauser
.pause_until(|| boolean.load(Ordering::Relaxed).then_some(()))
.unwrap();
thread.join();
}
}

View File

@ -9,7 +9,7 @@ use super::SyscallReturn;
use crate::{
prelude::*,
process::{posix_thread::PosixThreadExt, process_table},
thread::{thread_table, Thread},
thread::thread_table,
time::{
clockid_t,
clocks::{
@ -121,7 +121,7 @@ pub fn read_clock(clockid: clockid_t) -> Result<Duration> {
Ok(process.prof_clock().read_time())
}
ClockId::CLOCK_THREAD_CPUTIME_ID => {
let thread = Thread::current();
let thread = current_thread!();
Ok(thread.as_posix_thread().unwrap().prof_clock().read_time())
}
}

View File

@ -20,7 +20,6 @@ use crate::{
thread::{
thread_table,
work_queue::{submit_work_item, work_item::WorkItem},
Thread,
},
time::{
clockid_t,
@ -113,7 +112,7 @@ pub fn sys_timer_create(
match clock_id {
ClockId::CLOCK_PROCESS_CPUTIME_ID => process_timer_manager.create_prof_timer(func),
ClockId::CLOCK_THREAD_CPUTIME_ID => {
let current_thread = Thread::current();
let current_thread = current_thread!();
current_thread
.as_posix_thread()
.unwrap()

View File

@ -50,15 +50,16 @@ impl Thread {
}
}
pub fn current() -> Arc<Self> {
let task = Task::current();
let thread = task
/// Returns the current thread, or `None` if the current task is not associated with a thread.
///
/// Except for unit tests, all tasks should be associated with threads. This method is useful
/// when writing code that can be called directly by unit tests. If this isn't the case,
/// consider using [`current_thread!`] instead.
pub fn current() -> Option<Arc<Self>> {
Task::current()
.data()
.downcast_ref::<Weak<Thread>>()
.expect("[Internal Error] task data should points to weak<thread>");
thread
.downcast_ref::<Weak<Thread>>()?
.upgrade()
.expect("[Internal Error] current thread cannot be None")
}
pub(in crate::thread) fn task(&self) -> &Arc<Task> {