mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 20:46:35 +00:00
Add ThreadExt
and clean up PosixThreadExt
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
a4a8807a20
commit
9233d1cdbb
@ -21,7 +21,7 @@ use crate::{
|
|||||||
get_current_userspace,
|
get_current_userspace,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::posix_thread::allocate_posix_tid,
|
process::posix_thread::allocate_posix_tid,
|
||||||
thread::{Thread, Tid},
|
thread::{ThreadExt, Tid},
|
||||||
};
|
};
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
@ -183,10 +183,10 @@ pub fn clone_child(
|
|||||||
clone_args.flags.check_unsupported_flags()?;
|
clone_args.flags.check_unsupported_flags()?;
|
||||||
if clone_args.flags.contains(CloneFlags::CLONE_THREAD) {
|
if clone_args.flags.contains(CloneFlags::CLONE_THREAD) {
|
||||||
let child_task = clone_child_task(ctx, parent_context, clone_args)?;
|
let child_task = clone_child_task(ctx, parent_context, clone_args)?;
|
||||||
let child_thread = Thread::borrow_from_task(&child_task);
|
let child_thread = child_task.as_thread().unwrap();
|
||||||
child_thread.run();
|
child_thread.run();
|
||||||
|
|
||||||
let child_tid = child_thread.tid();
|
let child_tid = child_thread.as_posix_thread().unwrap().tid();
|
||||||
Ok(child_tid)
|
Ok(child_tid)
|
||||||
} else {
|
} else {
|
||||||
let child_process = clone_child_process(ctx, parent_context, clone_args)?;
|
let child_process = clone_child_process(ctx, parent_context, clone_args)?;
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
posix_thread::{do_exit, PosixThreadExt},
|
posix_thread::{do_exit, PosixThreadExt},
|
||||||
signal::signals::kernel::KernelSignal,
|
signal::signals::kernel::KernelSignal,
|
||||||
},
|
},
|
||||||
thread::Thread,
|
thread::ThreadExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn do_exit_group(term_status: TermStatus) {
|
pub fn do_exit_group(term_status: TermStatus) {
|
||||||
@ -21,7 +21,7 @@ pub fn do_exit_group(term_status: TermStatus) {
|
|||||||
// Exit all threads
|
// Exit all threads
|
||||||
let tasks = current.tasks().lock().clone();
|
let tasks = current.tasks().lock().clone();
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
let thread = Thread::borrow_from_task(&task);
|
let thread = task.as_thread().unwrap();
|
||||||
let posix_thread = thread.as_posix_thread().unwrap();
|
let posix_thread = thread.as_posix_thread().unwrap();
|
||||||
if let Err(e) = do_exit(thread, posix_thread, term_status) {
|
if let Err(e) = do_exit(thread, posix_thread, term_status) {
|
||||||
debug!("Ignore error when call exit: {:?}", e);
|
debug!("Ignore error when call exit: {:?}", e);
|
||||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||||||
events::Observer,
|
events::Observer,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::signal::constants::SIGCONT,
|
process::signal::constants::SIGCONT,
|
||||||
thread::{Thread, Tid},
|
thread::{Thread, ThreadExt, Tid},
|
||||||
time::{clocks::ProfClock, Timer, TimerManager},
|
time::{clocks::ProfClock, Timer, TimerManager},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ impl PosixThread {
|
|||||||
let tasks = process.tasks().lock();
|
let tasks = process.tasks().lock();
|
||||||
tasks
|
tasks
|
||||||
.iter()
|
.iter()
|
||||||
.all(|task| Thread::borrow_from_task(task).is_exited())
|
.all(|task| task.as_thread().unwrap().is_exited())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the read-only credentials of the thread.
|
/// Gets the read-only credentials of the thread.
|
||||||
|
@ -11,17 +11,12 @@ use crate::{
|
|||||||
fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD},
|
fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{process_vm::ProcessVm, program_loader::load_program_to_vm, Credentials, Process},
|
process::{process_vm::ProcessVm, program_loader::load_program_to_vm, Credentials, Process},
|
||||||
thread::{Thread, Tid},
|
thread::{Thread, ThreadExt, Tid},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// An extension trait for some [`PosixThread`]-like types.
|
||||||
pub trait PosixThreadExt {
|
pub trait PosixThreadExt {
|
||||||
/// Returns the thread id.
|
/// Returns the associated [`PosixThread`].
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// If the thread is not posix thread, this method will panic.
|
|
||||||
fn tid(&self) -> Tid {
|
|
||||||
self.as_posix_thread().unwrap().tid()
|
|
||||||
}
|
|
||||||
fn as_posix_thread(&self) -> Option<&PosixThread>;
|
fn as_posix_thread(&self) -> Option<&PosixThread>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,9 +26,9 @@ impl PosixThreadExt for Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PosixThreadExt for Arc<Task> {
|
impl PosixThreadExt for Task {
|
||||||
fn as_posix_thread(&self) -> Option<&PosixThread> {
|
fn as_posix_thread(&self) -> Option<&PosixThread> {
|
||||||
Thread::borrow_from_task(self).as_posix_thread()
|
self.as_thread()?.as_posix_thread()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ static THREAD_TABLE: SpinLock<BTreeMap<Tid, Arc<Thread>>> = SpinLock::new(BTreeM
|
|||||||
|
|
||||||
/// Adds a posix thread to global thread table
|
/// Adds a posix thread to global thread table
|
||||||
pub fn add_thread(tid: Tid, thread: Arc<Thread>) {
|
pub fn add_thread(tid: Tid, thread: Arc<Thread>) {
|
||||||
debug_assert_eq!(tid, thread.tid());
|
debug_assert_eq!(tid, thread.as_posix_thread().unwrap().tid());
|
||||||
THREAD_TABLE.lock().insert(tid, thread);
|
THREAD_TABLE.lock().insert(tid, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ use crate::{
|
|||||||
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
sched::priority::{AtomicNice, Nice},
|
sched::priority::{AtomicNice, Nice},
|
||||||
thread::Thread,
|
thread::{Thread, ThreadExt},
|
||||||
time::clocks::ProfClock,
|
time::clocks::ProfClock,
|
||||||
vm::vmar::Vmar,
|
vm::vmar::Vmar,
|
||||||
};
|
};
|
||||||
@ -174,13 +174,7 @@ impl Process {
|
|||||||
/// - the function is called in the bootstrap context;
|
/// - the function is called in the bootstrap context;
|
||||||
/// - or if the current task is not associated with a process.
|
/// - or if the current task is not associated with a process.
|
||||||
pub fn current() -> Option<Arc<Process>> {
|
pub fn current() -> Option<Arc<Process>> {
|
||||||
Some(
|
Some(Task::current()?.as_posix_thread()?.process())
|
||||||
Task::current()?
|
|
||||||
.data()
|
|
||||||
.downcast_ref::<Arc<Thread>>()?
|
|
||||||
.as_posix_thread()?
|
|
||||||
.process(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@ -292,7 +286,7 @@ impl Process {
|
|||||||
let task = tasks[0].clone();
|
let task = tasks[0].clone();
|
||||||
// should not hold the lock when run thread
|
// should not hold the lock when run thread
|
||||||
drop(tasks);
|
drop(tasks);
|
||||||
let thread = Thread::borrow_from_task(&task);
|
let thread = task.as_thread().unwrap();
|
||||||
thread.run();
|
thread.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,8 +330,10 @@ impl Process {
|
|||||||
self.tasks
|
self.tasks
|
||||||
.lock()
|
.lock()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|task| task.tid() == self.pid)
|
.find_map(|task| {
|
||||||
.map(|task| Thread::borrow_from_task(task.as_ref()))
|
let thread = task.as_thread().unwrap();
|
||||||
|
(thread.as_posix_thread().unwrap().tid() == self.pid).then_some(thread)
|
||||||
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use super::sig_mask::SigMask;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::posix_thread::PosixThreadExt,
|
process::posix_thread::PosixThreadExt,
|
||||||
thread::Thread,
|
thread::ThreadExt,
|
||||||
time::wait::{ManagedTimeout, TimeoutExt},
|
time::wait::{ManagedTimeout, TimeoutExt},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ impl Pause for Waiter {
|
|||||||
// No fast paths for `Waiter`. If the caller wants a fast path, it should do so _before_
|
// No fast paths for `Waiter`. If the caller wants a fast path, it should do so _before_
|
||||||
// the waiter is created.
|
// the waiter is created.
|
||||||
|
|
||||||
let current_thread = self.task().data().downcast_ref::<Arc<Thread>>();
|
let current_thread = self.task().as_thread();
|
||||||
|
|
||||||
let Some(posix_thread) = current_thread
|
let Some(posix_thread) = current_thread
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -143,7 +143,7 @@ impl Pause for Waiter {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let current_thread = self.task().data().downcast_ref::<Arc<Thread>>();
|
let current_thread = self.task().as_thread();
|
||||||
|
|
||||||
if let Some(posix_thread) = current_thread
|
if let Some(posix_thread) = current_thread
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -92,7 +92,7 @@ fn reap_zombie_child(process: &Process, pid: Pid) -> ExitCode {
|
|||||||
let child_process = process.children().lock().remove(&pid).unwrap();
|
let child_process = process.children().lock().remove(&pid).unwrap();
|
||||||
assert!(child_process.is_zombie());
|
assert!(child_process.is_zombie());
|
||||||
for task in &*child_process.tasks().lock() {
|
for task in &*child_process.tasks().lock() {
|
||||||
thread_table::remove_thread(task.tid());
|
thread_table::remove_thread(task.as_posix_thread().unwrap().tid());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock order: session table -> group table -> process table -> group of process
|
// Lock order: session table -> group table -> process table -> group of process
|
||||||
|
@ -348,7 +348,7 @@ macro_rules! log_syscall_entry {
|
|||||||
let pid = $crate::current!().pid();
|
let pid = $crate::current!().pid();
|
||||||
let tid = {
|
let tid = {
|
||||||
use $crate::process::posix_thread::PosixThreadExt;
|
use $crate::process::posix_thread::PosixThreadExt;
|
||||||
$crate::current_thread!().tid()
|
$crate::current_thread!().as_posix_thread().unwrap().tid()
|
||||||
};
|
};
|
||||||
log::info!(
|
log::info!(
|
||||||
"[pid={}][tid={}][id={}][{}]",
|
"[pid={}][tid={}][id={}][{}]",
|
||||||
|
@ -5,7 +5,7 @@ use ostd::{
|
|||||||
task::{Task, TaskOptions},
|
task::{Task, TaskOptions},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{oops, status::ThreadStatus, Thread};
|
use super::{oops, status::ThreadStatus, Thread, ThreadExt};
|
||||||
use crate::{prelude::*, sched::priority::Priority};
|
use crate::{prelude::*, sched::priority::Priority};
|
||||||
|
|
||||||
/// The inner data of a kernel thread.
|
/// The inner data of a kernel thread.
|
||||||
@ -77,7 +77,7 @@ impl ThreadOptions {
|
|||||||
/// Builds a new kernel thread and runs it immediately.
|
/// Builds a new kernel thread and runs it immediately.
|
||||||
pub fn spawn(self) -> Arc<Thread> {
|
pub fn spawn(self) -> Arc<Thread> {
|
||||||
let task = self.build();
|
let task = self.build();
|
||||||
let thread = Thread::borrow_from_task(&task).clone();
|
let thread = task.as_thread().unwrap().clone();
|
||||||
thread.run();
|
thread.run();
|
||||||
thread
|
thread
|
||||||
}
|
}
|
||||||
|
@ -65,10 +65,7 @@ impl Thread {
|
|||||||
/// This function returns `None` if the current task is not associated with
|
/// This function returns `None` if the current task is not associated with
|
||||||
/// a thread, or if called within the bootstrap context.
|
/// a thread, or if called within the bootstrap context.
|
||||||
pub fn current() -> Option<Arc<Self>> {
|
pub fn current() -> Option<Arc<Self>> {
|
||||||
Task::current()?
|
Task::current()?.as_thread().cloned()
|
||||||
.data()
|
|
||||||
.downcast_ref::<Arc<Thread>>()
|
|
||||||
.cloned()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the task associated with this thread.
|
/// Returns the task associated with this thread.
|
||||||
@ -76,15 +73,6 @@ impl Thread {
|
|||||||
self.task.upgrade().unwrap()
|
self.task.upgrade().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the Thread from task's data.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// This method panics if the task is not a thread.
|
|
||||||
pub fn borrow_from_task(task: &Task) -> &Arc<Self> {
|
|
||||||
task.data().downcast_ref::<Arc<Thread>>().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs this thread at once.
|
/// Runs this thread at once.
|
||||||
pub fn run(&self) {
|
pub fn run(&self) {
|
||||||
self.status.store(ThreadStatus::Running, Ordering::Release);
|
self.status.store(ThreadStatus::Running, Ordering::Release);
|
||||||
@ -173,3 +161,15 @@ impl Thread {
|
|||||||
&*self.data
|
&*self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An extension trait for [`Thread`]-like types.
|
||||||
|
pub trait ThreadExt {
|
||||||
|
/// Returns the associated [`Thread`].
|
||||||
|
fn as_thread(&self) -> Option<&Arc<Thread>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ThreadExt for Task {
|
||||||
|
fn as_thread(&self) -> Option<&Arc<Thread>> {
|
||||||
|
self.data().downcast_ref::<Arc<Thread>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,8 +11,7 @@ use super::worker_pool::WorkerPool;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
sched::priority::{Priority, PriorityRange},
|
sched::priority::{Priority, PriorityRange},
|
||||||
thread::kernel_thread::ThreadOptions,
|
thread::{kernel_thread::ThreadOptions, ThreadExt},
|
||||||
Thread,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A worker thread. A `Worker` will attempt to retrieve unfinished
|
/// A worker thread. A `Worker` will attempt to retrieve unfinished
|
||||||
@ -72,7 +71,7 @@ impl Worker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn run(&self) {
|
pub(super) fn run(&self) {
|
||||||
let thread = Thread::borrow_from_task(&self.bound_task);
|
let thread = self.bound_task.as_thread().unwrap();
|
||||||
thread.run();
|
thread.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,7 @@ use super::{simple_scheduler::SimpleScheduler, worker::Worker, WorkItem, WorkPri
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
sched::priority::{Priority, PriorityRange},
|
sched::priority::{Priority, PriorityRange},
|
||||||
thread::kernel_thread::ThreadOptions,
|
thread::{kernel_thread::ThreadOptions, ThreadExt},
|
||||||
Thread,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A pool of workers.
|
/// A pool of workers.
|
||||||
@ -83,7 +82,7 @@ impl LocalWorkerPool {
|
|||||||
fn add_worker(&self) {
|
fn add_worker(&self) {
|
||||||
let worker = Worker::new(self.parent.clone(), self.cpu_id);
|
let worker = Worker::new(self.parent.clone(), self.cpu_id);
|
||||||
self.workers.disable_irq().lock().push_back(worker.clone());
|
self.workers.disable_irq().lock().push_back(worker.clone());
|
||||||
Thread::borrow_from_task(worker.bound_task()).run();
|
worker.bound_task().as_thread().unwrap().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_worker(&self) {
|
fn remove_worker(&self) {
|
||||||
@ -258,7 +257,7 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self) {
|
pub fn run(&self) {
|
||||||
Thread::borrow_from_task(&self.bound_task).run()
|
self.bound_task.as_thread().unwrap().run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_monitor_loop(self: &Arc<Self>) {
|
fn run_monitor_loop(self: &Arc<Self>) {
|
||||||
|
Reference in New Issue
Block a user