Reduce some redundant usage of current! and current_thread!

This commit is contained in:
LI Qing
2024-05-09 10:12:18 +08:00
committed by Tate, Hongliang Tian
parent 98a2e623e2
commit 8f3b1f8ddf
4 changed files with 30 additions and 18 deletions

View File

@ -61,14 +61,15 @@ pub fn schedule() {
} }
} }
pub fn preempt() { // TODO: This interface of this method is error prone.
// The method takes an argument for the current task to optimize its efficiency,
// but the argument provided by the caller may not be the current task, really.
// Thus, this method should be removed or reworked in the future.
pub fn preempt(task: &Arc<Task>) {
// TODO: Refactor `preempt` and `schedule` // TODO: Refactor `preempt` and `schedule`
// after the Atomic mode and `might_break` is enabled. // after the Atomic mode and `might_break` is enabled.
let Some(curr_task) = current_task() else {
return;
};
let mut scheduler = GLOBAL_SCHEDULER.lock_irq_disabled(); let mut scheduler = GLOBAL_SCHEDULER.lock_irq_disabled();
if !scheduler.should_preempt(&curr_task) { if !scheduler.should_preempt(task) {
return; return;
} }
let Some(next_task) = scheduler.dequeue() else { let Some(next_task) = scheduler.dequeue() else {

View File

@ -30,17 +30,20 @@ use super::posix_thread::{PosixThread, PosixThreadExt};
use crate::{ use crate::{
prelude::*, prelude::*,
process::{do_exit_group, TermStatus}, process::{do_exit_group, TermStatus},
thread::Thread,
util::{write_bytes_to_user, write_val_to_user}, util::{write_bytes_to_user, write_val_to_user},
}; };
/// Handle pending signal for current process // TODO: This interface of this method is error prone.
pub fn handle_pending_signal(context: &mut UserContext) -> Result<()> { // The method takes an argument for the current thread to optimize its efficiency.
let current = current!(); /// Handle pending signal for current process.
let current_thread = current_thread!(); pub fn handle_pending_signal(
context: &mut UserContext,
current_thread: &Arc<Thread>,
) -> Result<()> {
// We first deal with signal in current thread, then signal in current process. // We first deal with signal in current thread, then signal in current process.
let posix_thread = current_thread.as_posix_thread().unwrap();
let signal = { let signal = {
let posix_thread = current_thread.as_posix_thread().unwrap();
let sig_mask = *posix_thread.sig_mask().lock(); let sig_mask = *posix_thread.sig_mask().lock();
if let Some(signal) = posix_thread.dequeue_signal(&sig_mask) { if let Some(signal) = posix_thread.dequeue_signal(&sig_mask) {
signal signal
@ -51,6 +54,7 @@ pub fn handle_pending_signal(context: &mut UserContext) -> Result<()> {
let sig_num = signal.num(); let sig_num = signal.num();
trace!("sig_num = {:?}, sig_name = {}", sig_num, sig_num.sig_name()); trace!("sig_num = {:?}, sig_name = {}", sig_num, sig_num.sig_name());
let current = posix_thread.process();
let sig_action = current.sig_dispositions().lock().get(sig_num); let sig_action = current.sig_dispositions().lock().get(sig_num);
trace!("sig action: {:x?}", sig_action); trace!("sig action: {:x?}", sig_action);
match sig_action { match sig_action {

View File

@ -61,6 +61,10 @@ impl Thread {
.expect("[Internal Error] current thread cannot be None") .expect("[Internal Error] current thread cannot be None")
} }
pub(in crate::thread) fn task(&self) -> &Arc<Task> {
&self.task
}
/// Run this thread at once. /// Run this thread at once.
pub fn run(&self) { pub fn run(&self) {
self.status.lock().set_running(); self.status.lock().set_running();

View File

@ -15,8 +15,11 @@ use crate::{
/// create new task with userspace and parent process /// create new task with userspace and parent process
pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>) -> Arc<Task> { pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>) -> Arc<Task> {
fn user_task_entry() { fn user_task_entry() {
let cur = Task::current(); let current_thread = current_thread!();
let user_space = cur.user_space().expect("user task should have user space"); let current_task = current_thread.task();
let user_space = current_task
.user_space()
.expect("user task should have user space");
let mut user_mode = UserMode::new(user_space); let mut user_mode = UserMode::new(user_space);
debug!( debug!(
"[Task entry] rip = 0x{:x}", "[Task entry] rip = 0x{:x}",
@ -30,17 +33,17 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>
"[Task entry] rax = 0x{:x}", "[Task entry] rax = 0x{:x}",
user_mode.context().syscall_ret() user_mode.context().syscall_ret()
); );
loop { loop {
let user_event = user_mode.execute(); let user_event = user_mode.execute();
let context = user_mode.context_mut(); let context = user_mode.context_mut();
// handle user event: // handle user event:
handle_user_event(user_event, context); handle_user_event(user_event, context);
let current_thread = current_thread!();
// should be do this comparison before handle signal? // should be do this comparison before handle signal?
if current_thread.status().lock().is_exited() { if current_thread.status().lock().is_exited() {
break; break;
} }
handle_pending_signal(context).unwrap(); handle_pending_signal(context, &current_thread).unwrap();
if current_thread.status().lock().is_exited() { if current_thread.status().lock().is_exited() {
debug!("exit due to signal"); debug!("exit due to signal");
break; break;
@ -49,14 +52,14 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>
while current_thread.status().lock().is_stopped() { while current_thread.status().lock().is_stopped() {
Thread::yield_now(); Thread::yield_now();
debug!("{} is suspended.", current_thread.tid()); debug!("{} is suspended.", current_thread.tid());
handle_pending_signal(context).unwrap(); handle_pending_signal(context, &current_thread).unwrap();
} }
// a preemption point after handling user event. // a preemption point after handling user event.
preempt(); preempt(current_task);
} }
debug!("exit user loop"); debug!("exit user loop");
// FIXME: This is a work around: exit in kernel task entry may be not called. Why this will happen? // FIXME: This is a work around: exit in kernel task entry may be not called. Why this will happen?
Task::current().exit(); current_task.exit();
} }
TaskOptions::new(user_task_entry) TaskOptions::new(user_task_entry)