mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 09:53:24 +00:00
Make Pauser
work in raw tasks
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
8f64a1cb90
commit
ceb0ef67e1
@ -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_export]
|
||||||
macro_rules! current_thread {
|
macro_rules! current_thread {
|
||||||
() => {
|
() => {
|
||||||
$crate::thread::Thread::current()
|
$crate::thread::Thread::current().expect("the current task is not associated with a thread")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +641,7 @@ impl Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn current() -> Arc<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() {
|
if let Some(posix_thread) = current_thread.as_posix_thread() {
|
||||||
posix_thread.process()
|
posix_thread.process()
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,14 +18,12 @@ use ostd::{
|
|||||||
|
|
||||||
use super::Process;
|
use super::Process;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
prelude::*,
|
||||||
process::{
|
process::{
|
||||||
posix_thread::PosixThreadExt,
|
posix_thread::PosixThreadExt,
|
||||||
signal::{constants::SIGALRM, signals::kernel::KernelSignal},
|
signal::{constants::SIGALRM, signals::kernel::KernelSignal},
|
||||||
},
|
},
|
||||||
thread::{
|
thread::work_queue::{submit_work_item, work_item::WorkItem},
|
||||||
work_queue::{submit_work_item, work_item::WorkItem},
|
|
||||||
Thread,
|
|
||||||
},
|
|
||||||
time::{
|
time::{
|
||||||
clocks::{ProfClock, RealTimeClock},
|
clocks::{ProfClock, RealTimeClock},
|
||||||
Timer, TimerManager,
|
Timer, TimerManager,
|
||||||
@ -38,7 +36,7 @@ use crate::{
|
|||||||
/// invoke the callbacks of expired timers which are based on the updated
|
/// invoke the callbacks of expired timers which are based on the updated
|
||||||
/// CPU clock.
|
/// CPU clock.
|
||||||
fn update_cpu_time() {
|
fn update_cpu_time() {
|
||||||
let current_thread = Thread::current();
|
let current_thread = current_thread!();
|
||||||
if let Some(posix_thread) = current_thread.as_posix_thread() {
|
if let Some(posix_thread) = current_thread.as_posix_thread() {
|
||||||
let process = posix_thread.process();
|
let process = posix_thread.process();
|
||||||
let timer_manager = process.timer_manager();
|
let timer_manager = process.timer_manager();
|
||||||
|
@ -123,9 +123,9 @@ impl Pauser {
|
|||||||
where
|
where
|
||||||
F: FnMut() -> Option<R>,
|
F: FnMut() -> Option<R>,
|
||||||
{
|
{
|
||||||
let current_thread = current_thread!();
|
let current_thread = Thread::current();
|
||||||
let sig_queue_waiter =
|
let sig_queue_waiter =
|
||||||
SigObserverRegistrar::new(¤t_thread, self.sig_mask, self.clone());
|
SigObserverRegistrar::new(current_thread.as_ref(), self.sig_mask, self.clone());
|
||||||
|
|
||||||
let cond = || {
|
let cond = || {
|
||||||
if let Some(res) = cond() {
|
if let Some(res) = cond() {
|
||||||
@ -174,8 +174,12 @@ enum SigObserverRegistrar<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SigObserverRegistrar<'a> {
|
impl<'a> SigObserverRegistrar<'a> {
|
||||||
fn new(current_thread: &'a Arc<Thread>, sig_mask: SigMask, pauser: Arc<Pauser>) -> Self {
|
fn new(
|
||||||
let Some(thread) = current_thread.as_posix_thread() else {
|
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;
|
return Self::KernelThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -281,19 +285,17 @@ mod test {
|
|||||||
let boolean = Arc::new(AtomicBool::new(false));
|
let boolean = Arc::new(AtomicBool::new(false));
|
||||||
let boolean_cloned = boolean.clone();
|
let boolean_cloned = boolean.clone();
|
||||||
|
|
||||||
let thread1 = Thread::spawn_kernel_thread(ThreadOptions::new(move || {
|
let thread = 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 || {
|
|
||||||
Thread::yield_now();
|
Thread::yield_now();
|
||||||
|
|
||||||
boolean_cloned.store(true, Ordering::Relaxed);
|
boolean_cloned.store(true, Ordering::Relaxed);
|
||||||
pauser_cloned.resume_all();
|
pauser_cloned.resume_all();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
thread1.join();
|
pauser
|
||||||
thread2.join();
|
.pause_until(|| boolean.load(Ordering::Relaxed).then_some(()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
thread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{posix_thread::PosixThreadExt, process_table},
|
process::{posix_thread::PosixThreadExt, process_table},
|
||||||
thread::{thread_table, Thread},
|
thread::thread_table,
|
||||||
time::{
|
time::{
|
||||||
clockid_t,
|
clockid_t,
|
||||||
clocks::{
|
clocks::{
|
||||||
@ -121,7 +121,7 @@ pub fn read_clock(clockid: clockid_t) -> Result<Duration> {
|
|||||||
Ok(process.prof_clock().read_time())
|
Ok(process.prof_clock().read_time())
|
||||||
}
|
}
|
||||||
ClockId::CLOCK_THREAD_CPUTIME_ID => {
|
ClockId::CLOCK_THREAD_CPUTIME_ID => {
|
||||||
let thread = Thread::current();
|
let thread = current_thread!();
|
||||||
Ok(thread.as_posix_thread().unwrap().prof_clock().read_time())
|
Ok(thread.as_posix_thread().unwrap().prof_clock().read_time())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ use crate::{
|
|||||||
thread::{
|
thread::{
|
||||||
thread_table,
|
thread_table,
|
||||||
work_queue::{submit_work_item, work_item::WorkItem},
|
work_queue::{submit_work_item, work_item::WorkItem},
|
||||||
Thread,
|
|
||||||
},
|
},
|
||||||
time::{
|
time::{
|
||||||
clockid_t,
|
clockid_t,
|
||||||
@ -113,7 +112,7 @@ pub fn sys_timer_create(
|
|||||||
match clock_id {
|
match clock_id {
|
||||||
ClockId::CLOCK_PROCESS_CPUTIME_ID => process_timer_manager.create_prof_timer(func),
|
ClockId::CLOCK_PROCESS_CPUTIME_ID => process_timer_manager.create_prof_timer(func),
|
||||||
ClockId::CLOCK_THREAD_CPUTIME_ID => {
|
ClockId::CLOCK_THREAD_CPUTIME_ID => {
|
||||||
let current_thread = Thread::current();
|
let current_thread = current_thread!();
|
||||||
current_thread
|
current_thread
|
||||||
.as_posix_thread()
|
.as_posix_thread()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -50,15 +50,16 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current() -> Arc<Self> {
|
/// Returns the current thread, or `None` if the current task is not associated with a thread.
|
||||||
let task = Task::current();
|
///
|
||||||
let thread = task
|
/// 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()
|
.data()
|
||||||
.downcast_ref::<Weak<Thread>>()
|
.downcast_ref::<Weak<Thread>>()?
|
||||||
.expect("[Internal Error] task data should points to weak<thread>");
|
|
||||||
thread
|
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.expect("[Internal Error] current thread cannot be None")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::thread) fn task(&self) -> &Arc<Task> {
|
pub(in crate::thread) fn task(&self) -> &Arc<Task> {
|
||||||
|
Reference in New Issue
Block a user