From 9233d1cdbbdd3b1dcc93a62a70bc515671504972 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Sun, 10 Nov 2024 17:15:08 +0800 Subject: [PATCH] Add `ThreadExt` and clean up `PosixThreadExt` --- kernel/src/process/clone.rs | 6 ++--- kernel/src/process/exit.rs | 4 +-- kernel/src/process/posix_thread/mod.rs | 4 +-- .../process/posix_thread/posix_thread_ext.rs | 17 +++++------- .../src/process/posix_thread/thread_table.rs | 2 +- kernel/src/process/process/mod.rs | 18 +++++-------- kernel/src/process/signal/pause.rs | 6 ++--- kernel/src/process/wait.rs | 2 +- kernel/src/syscall/mod.rs | 2 +- kernel/src/thread/kernel_thread.rs | 4 +-- kernel/src/thread/mod.rs | 26 +++++++++---------- kernel/src/thread/work_queue/worker.rs | 5 ++-- kernel/src/thread/work_queue/worker_pool.rs | 7 +++-- 13 files changed, 46 insertions(+), 57 deletions(-) diff --git a/kernel/src/process/clone.rs b/kernel/src/process/clone.rs index 24f2c4eef..9ea3f5740 100644 --- a/kernel/src/process/clone.rs +++ b/kernel/src/process/clone.rs @@ -21,7 +21,7 @@ use crate::{ get_current_userspace, prelude::*, process::posix_thread::allocate_posix_tid, - thread::{Thread, Tid}, + thread::{ThreadExt, Tid}, }; bitflags! { @@ -183,10 +183,10 @@ pub fn clone_child( clone_args.flags.check_unsupported_flags()?; if clone_args.flags.contains(CloneFlags::CLONE_THREAD) { 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(); - let child_tid = child_thread.tid(); + let child_tid = child_thread.as_posix_thread().unwrap().tid(); Ok(child_tid) } else { let child_process = clone_child_process(ctx, parent_context, clone_args)?; diff --git a/kernel/src/process/exit.rs b/kernel/src/process/exit.rs index 8e6330f71..47d7ad95a 100644 --- a/kernel/src/process/exit.rs +++ b/kernel/src/process/exit.rs @@ -7,7 +7,7 @@ use crate::{ posix_thread::{do_exit, PosixThreadExt}, signal::signals::kernel::KernelSignal, }, - thread::Thread, + thread::ThreadExt, }; pub fn do_exit_group(term_status: TermStatus) { @@ -21,7 +21,7 @@ pub fn do_exit_group(term_status: TermStatus) { // Exit all threads let tasks = current.tasks().lock().clone(); 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(); if let Err(e) = do_exit(thread, posix_thread, term_status) { debug!("Ignore error when call exit: {:?}", e); diff --git a/kernel/src/process/posix_thread/mod.rs b/kernel/src/process/posix_thread/mod.rs index cc5096e5f..e3976fd5e 100644 --- a/kernel/src/process/posix_thread/mod.rs +++ b/kernel/src/process/posix_thread/mod.rs @@ -22,7 +22,7 @@ use crate::{ events::Observer, prelude::*, process::signal::constants::SIGCONT, - thread::{Thread, Tid}, + thread::{Thread, ThreadExt, Tid}, time::{clocks::ProfClock, Timer, TimerManager}, }; @@ -277,7 +277,7 @@ impl PosixThread { let tasks = process.tasks().lock(); tasks .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. diff --git a/kernel/src/process/posix_thread/posix_thread_ext.rs b/kernel/src/process/posix_thread/posix_thread_ext.rs index eac3cbb68..847f077d0 100644 --- a/kernel/src/process/posix_thread/posix_thread_ext.rs +++ b/kernel/src/process/posix_thread/posix_thread_ext.rs @@ -11,17 +11,12 @@ use crate::{ fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD}, prelude::*, 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 { - /// Returns the thread id. - /// - /// # Panics - /// - /// If the thread is not posix thread, this method will panic. - fn tid(&self) -> Tid { - self.as_posix_thread().unwrap().tid() - } + /// Returns the associated [`PosixThread`]. fn as_posix_thread(&self) -> Option<&PosixThread>; } @@ -31,9 +26,9 @@ impl PosixThreadExt for Thread { } } -impl PosixThreadExt for Arc { +impl PosixThreadExt for Task { fn as_posix_thread(&self) -> Option<&PosixThread> { - Thread::borrow_from_task(self).as_posix_thread() + self.as_thread()?.as_posix_thread() } } diff --git a/kernel/src/process/posix_thread/thread_table.rs b/kernel/src/process/posix_thread/thread_table.rs index fc8f1e88d..f333198b2 100644 --- a/kernel/src/process/posix_thread/thread_table.rs +++ b/kernel/src/process/posix_thread/thread_table.rs @@ -7,7 +7,7 @@ static THREAD_TABLE: SpinLock>> = SpinLock::new(BTreeM /// Adds a posix thread to global thread table pub fn add_thread(tid: Tid, thread: Arc) { - debug_assert_eq!(tid, thread.tid()); + debug_assert_eq!(tid, thread.as_posix_thread().unwrap().tid()); THREAD_TABLE.lock().insert(tid, thread); } diff --git a/kernel/src/process/process/mod.rs b/kernel/src/process/process/mod.rs index adefda3c3..82daba645 100644 --- a/kernel/src/process/process/mod.rs +++ b/kernel/src/process/process/mod.rs @@ -21,7 +21,7 @@ use crate::{ fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask}, prelude::*, sched::priority::{AtomicNice, Nice}, - thread::Thread, + thread::{Thread, ThreadExt}, time::clocks::ProfClock, vm::vmar::Vmar, }; @@ -174,13 +174,7 @@ impl Process { /// - the function is called in the bootstrap context; /// - or if the current task is not associated with a process. pub fn current() -> Option> { - Some( - Task::current()? - .data() - .downcast_ref::>()? - .as_posix_thread()? - .process(), - ) + Some(Task::current()?.as_posix_thread()?.process()) } #[allow(clippy::too_many_arguments)] @@ -292,7 +286,7 @@ impl Process { let task = tasks[0].clone(); // should not hold the lock when run thread drop(tasks); - let thread = Thread::borrow_from_task(&task); + let thread = task.as_thread().unwrap(); thread.run(); } @@ -336,8 +330,10 @@ impl Process { self.tasks .lock() .iter() - .find(|task| task.tid() == self.pid) - .map(|task| Thread::borrow_from_task(task.as_ref())) + .find_map(|task| { + let thread = task.as_thread().unwrap(); + (thread.as_posix_thread().unwrap().tid() == self.pid).then_some(thread) + }) .cloned() } diff --git a/kernel/src/process/signal/pause.rs b/kernel/src/process/signal/pause.rs index 40f0150c4..0cc7bc3c9 100644 --- a/kernel/src/process/signal/pause.rs +++ b/kernel/src/process/signal/pause.rs @@ -8,7 +8,7 @@ use super::sig_mask::SigMask; use crate::{ prelude::*, process::posix_thread::PosixThreadExt, - thread::Thread, + thread::ThreadExt, 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_ // the waiter is created. - let current_thread = self.task().data().downcast_ref::>(); + let current_thread = self.task().as_thread(); let Some(posix_thread) = current_thread .as_ref() @@ -143,7 +143,7 @@ impl Pause for Waiter { }) }); - let current_thread = self.task().data().downcast_ref::>(); + let current_thread = self.task().as_thread(); if let Some(posix_thread) = current_thread .as_ref() diff --git a/kernel/src/process/wait.rs b/kernel/src/process/wait.rs index 8b5b827d3..aaaa04735 100644 --- a/kernel/src/process/wait.rs +++ b/kernel/src/process/wait.rs @@ -92,7 +92,7 @@ fn reap_zombie_child(process: &Process, pid: Pid) -> ExitCode { let child_process = process.children().lock().remove(&pid).unwrap(); assert!(child_process.is_zombie()); 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 diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 2f851fbec..802e51c95 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -348,7 +348,7 @@ macro_rules! log_syscall_entry { let pid = $crate::current!().pid(); let tid = { use $crate::process::posix_thread::PosixThreadExt; - $crate::current_thread!().tid() + $crate::current_thread!().as_posix_thread().unwrap().tid() }; log::info!( "[pid={}][tid={}][id={}][{}]", diff --git a/kernel/src/thread/kernel_thread.rs b/kernel/src/thread/kernel_thread.rs index 1f0336b38..a2b0bf7e1 100644 --- a/kernel/src/thread/kernel_thread.rs +++ b/kernel/src/thread/kernel_thread.rs @@ -5,7 +5,7 @@ use ostd::{ task::{Task, TaskOptions}, }; -use super::{oops, status::ThreadStatus, Thread}; +use super::{oops, status::ThreadStatus, Thread, ThreadExt}; use crate::{prelude::*, sched::priority::Priority}; /// The inner data of a kernel thread. @@ -77,7 +77,7 @@ impl ThreadOptions { /// Builds a new kernel thread and runs it immediately. pub fn spawn(self) -> Arc { let task = self.build(); - let thread = Thread::borrow_from_task(&task).clone(); + let thread = task.as_thread().unwrap().clone(); thread.run(); thread } diff --git a/kernel/src/thread/mod.rs b/kernel/src/thread/mod.rs index 64dc40e8e..6c54124da 100644 --- a/kernel/src/thread/mod.rs +++ b/kernel/src/thread/mod.rs @@ -65,10 +65,7 @@ impl Thread { /// This function returns `None` if the current task is not associated with /// a thread, or if called within the bootstrap context. pub fn current() -> Option> { - Task::current()? - .data() - .downcast_ref::>() - .cloned() + Task::current()?.as_thread().cloned() } /// Returns the task associated with this thread. @@ -76,15 +73,6 @@ impl Thread { 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 { - task.data().downcast_ref::>().unwrap() - } - /// Runs this thread at once. pub fn run(&self) { self.status.store(ThreadStatus::Running, Ordering::Release); @@ -173,3 +161,15 @@ impl Thread { &*self.data } } + +/// An extension trait for [`Thread`]-like types. +pub trait ThreadExt { + /// Returns the associated [`Thread`]. + fn as_thread(&self) -> Option<&Arc>; +} + +impl ThreadExt for Task { + fn as_thread(&self) -> Option<&Arc> { + self.data().downcast_ref::>() + } +} diff --git a/kernel/src/thread/work_queue/worker.rs b/kernel/src/thread/work_queue/worker.rs index a74af943f..8783402ed 100644 --- a/kernel/src/thread/work_queue/worker.rs +++ b/kernel/src/thread/work_queue/worker.rs @@ -11,8 +11,7 @@ use super::worker_pool::WorkerPool; use crate::{ prelude::*, sched::priority::{Priority, PriorityRange}, - thread::kernel_thread::ThreadOptions, - Thread, + thread::{kernel_thread::ThreadOptions, ThreadExt}, }; /// A worker thread. A `Worker` will attempt to retrieve unfinished @@ -72,7 +71,7 @@ impl Worker { } pub(super) fn run(&self) { - let thread = Thread::borrow_from_task(&self.bound_task); + let thread = self.bound_task.as_thread().unwrap(); thread.run(); } diff --git a/kernel/src/thread/work_queue/worker_pool.rs b/kernel/src/thread/work_queue/worker_pool.rs index 26c583c94..5cdeb03ab 100644 --- a/kernel/src/thread/work_queue/worker_pool.rs +++ b/kernel/src/thread/work_queue/worker_pool.rs @@ -17,8 +17,7 @@ use super::{simple_scheduler::SimpleScheduler, worker::Worker, WorkItem, WorkPri use crate::{ prelude::*, sched::priority::{Priority, PriorityRange}, - thread::kernel_thread::ThreadOptions, - Thread, + thread::{kernel_thread::ThreadOptions, ThreadExt}, }; /// A pool of workers. @@ -83,7 +82,7 @@ impl LocalWorkerPool { fn add_worker(&self) { let worker = Worker::new(self.parent.clone(), self.cpu_id); 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) { @@ -258,7 +257,7 @@ impl Monitor { } 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) {