From 3d45b8f8a0c34eb9a8f272cfd57fd117d47944a1 Mon Sep 17 00:00:00 2001 From: sslime336 <sslime@yeah.net> Date: Sun, 30 Jul 2023 16:04:57 +0800 Subject: [PATCH] Feat: child res recycler --- kernel/src/task/manager.rs | 22 +++++++++++++++++++++ kernel/src/task/mod.rs | 10 +++++++++- kernel/src/task/processor/mod.rs | 13 ++++++++++++- kernel/src/task/processor/schedule.rs | 4 +++- kernel/src/task/task.rs | 28 +++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/kernel/src/task/manager.rs b/kernel/src/task/manager.rs index 3c816559..092913c8 100644 --- a/kernel/src/task/manager.rs +++ b/kernel/src/task/manager.rs @@ -1,4 +1,5 @@ use crate::timer::get_time_ms; +use alloc::vec::Vec; use sync_cell::SyncRefCell; use super::TaskControlBlock; @@ -6,6 +7,27 @@ use alloc::collections::{BTreeMap, BinaryHeap, VecDeque}; use alloc::sync::Arc; use spin::Mutex; +pub struct ChildrenThreadMonitor { + cancelled_child_threads: Vec<Arc<TaskControlBlock>>, +} + +impl ChildrenThreadMonitor { + pub const fn new() -> Self { + ChildrenThreadMonitor { + cancelled_child_threads: Vec::new(), + } + } + pub fn take(&mut self, child_thread: Arc<TaskControlBlock>) { + self.cancelled_child_threads.push(child_thread); + } + pub fn release_all(&mut self){ + self.cancelled_child_threads.clear(); + } +} + +pub static CHILDREN_THREAD_MONITOR: Mutex<ChildrenThreadMonitor> = + Mutex::new(ChildrenThreadMonitor::new()); + /// FIFO 任务管ç†å™¨ pub struct TaskManager { ready_queue: VecDeque<Arc<TaskControlBlock>>, // status: Ready diff --git a/kernel/src/task/mod.rs b/kernel/src/task/mod.rs index 1ca3c8bd..ecd1ace4 100644 --- a/kernel/src/task/mod.rs +++ b/kernel/src/task/mod.rs @@ -34,7 +34,7 @@ use crate::{ use self::{ initproc::INITPROC, manager::block_task, - processor::{acquire_processor, schedule}, + processor::{acquire_processor, schedule, take_cancelled_chiled_thread}, }; /// 将当å‰ä»»åŠ¡ç½®ä¸ºå°±ç»ªæ€ï¼Œæ”¾å›žåˆ°è¿›ç¨‹ç®¡ç†å™¨ä¸çš„就绪队列ä¸ï¼Œé‡æ–°é€‰æ‹©ä¸€ä¸ªè¿›ç¨‹è¿è¡Œ @@ -64,6 +64,14 @@ pub fn exit_current_and_run_next(exit_code: i32) { // 获å–访问æƒé™ï¼Œä¿®æ”¹è¿›ç¨‹çŠ¶æ€ let task = take_current_task().unwrap(); remove_from_pid2task(task.pid()); + + if task.is_child_thread() { + take_cancelled_chiled_thread(task); + let mut _unused = TaskContext::empty(); + schedule(&mut _unused as *mut _); + unreachable!() + } + let mut inner = task.inner_mut(); // memory_set mut borrow let mut ms_mut = task.memory_set.write(); diff --git a/kernel/src/task/processor/mod.rs b/kernel/src/task/processor/mod.rs index e9314648..ece49ef5 100644 --- a/kernel/src/task/processor/mod.rs +++ b/kernel/src/task/processor/mod.rs @@ -14,7 +14,9 @@ pub use schedule::*; use crate::{mm::memory_set, trap::TrapContext}; -use super::{switch::__switch, task::TaskControlBlock, TaskContext}; +use super::{ + manager::CHILDREN_THREAD_MONITOR, switch::__switch, task::TaskControlBlock, TaskContext, +}; /// 从全局å˜é‡ `PROCESSOR` ä¸å–å‡ºå½“å‰æ£åœ¨æ‰§è¡Œçš„任务 pub fn take_current_task() -> Option<Arc<TaskControlBlock>> { @@ -48,3 +50,12 @@ pub fn schedule(switched_task_cx_ptr: *mut TaskContext) { unsafe { __switch(switched_task_cx_ptr, idle_task_cx_ptr) } } + +/// 回收已 cancel çš„åçº¿ç¨‹èµ„æº +pub fn recycle_child_threads_res() { + CHILDREN_THREAD_MONITOR.lock().release_all(); +} + +pub fn take_cancelled_chiled_thread(child_thread: Arc<TaskControlBlock>) { + CHILDREN_THREAD_MONITOR.lock().take(child_thread); +} diff --git a/kernel/src/task/processor/schedule.rs b/kernel/src/task/processor/schedule.rs index 85af1195..0499da81 100644 --- a/kernel/src/task/processor/schedule.rs +++ b/kernel/src/task/processor/schedule.rs @@ -14,7 +14,7 @@ use crate::task::{ unblock_task, TaskContext, TaskControlBlock, }; -use super::{acquire_processor, Processor}; +use super::{acquire_processor, Processor, recycle_child_threads_res}; /// 进入 idle 控制æµï¼Œå®ƒè¿è¡Œåœ¨è¿™ä¸ª CPU æ ¸çš„å¯åŠ¨æ ˆä¸Šï¼Œ /// 功能是循环调用 fetch_task 直到顺利从任务管ç†å™¨ä¸å–出一个任务,éšåŽä¾¿å‡†å¤‡é€šè¿‡ä»»åŠ¡åˆ‡æ¢çš„æ–¹å¼æ¥æ‰§è¡Œ @@ -22,6 +22,8 @@ pub fn run_tasks() { loop { let processor = acquire_processor(); + recycle_child_threads_res(); + if let Some(hanging_task) = check_hanging() { run_task(hanging_task, processor); } else if let Some(interupt_task) = check_interupt() { diff --git a/kernel/src/task/task.rs b/kernel/src/task/task.rs index 2113026e..debf0d12 100644 --- a/kernel/src/task/task.rs +++ b/kernel/src/task/task.rs @@ -44,6 +44,13 @@ pub struct TaskControlBlock { inner: RwLock<TaskControlBlockInner>, } +impl TaskControlBlock { + #[inline] + pub fn is_child_thread(&self) -> bool { + self.pid.0 != self.tgid + } +} + impl Debug for TaskControlBlock { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("TaskControlBlock") @@ -324,7 +331,11 @@ impl TaskControlBlock { // padding 0 è¡¨ç¤ºç»“æŸ user_sp -= core::mem::size_of::<usize>(); - copyout(token, unsafe { (user_sp as *mut usize).as_mut().unwrap() }, &0); + copyout( + token, + unsafe { (user_sp as *mut usize).as_mut().unwrap() }, + &0, + ); // envs_ptr user_sp -= (envs.len()) * core::mem::size_of::<usize>(); @@ -343,7 +354,11 @@ impl TaskControlBlock { // padding 0 è¡¨ç¤ºç»“æŸ user_sp -= core::mem::size_of::<usize>(); - copyout(token, unsafe { (user_sp as *mut usize).as_mut().unwrap() }, &0); + copyout( + token, + unsafe { (user_sp as *mut usize).as_mut().unwrap() }, + &0, + ); // args_ptr user_sp -= (args.len()) * core::mem::size_of::<usize>(); @@ -351,8 +366,13 @@ impl TaskControlBlock { for i in 0..args.len() { copyout( token, - unsafe { ((args_ptr_base + i * core::mem::size_of::<usize>()) as *mut usize).as_mut().unwrap() }, - &args_ptrv[i]); + unsafe { + ((args_ptr_base + i * core::mem::size_of::<usize>()) as *mut usize) + .as_mut() + .unwrap() + }, + &args_ptrv[i], + ); } // argc -- GitLab