Add ThreadExt and clean up PosixThreadExt

This commit is contained in:
Ruihan Li
2024-11-10 17:15:08 +08:00
committed by Tate, Hongliang Tian
parent a4a8807a20
commit 9233d1cdbb
13 changed files with 46 additions and 57 deletions

View File

@ -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)?;

View File

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

View File

@ -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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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={}][{}]",

View File

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

View File

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

View File

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

View File

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