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`
// 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();
if !scheduler.should_preempt(&curr_task) {
if !scheduler.should_preempt(task) {
return;
}
let Some(next_task) = scheduler.dequeue() else {

View File

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

View File

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

View File

@ -15,8 +15,11 @@ use crate::{
/// create new task with userspace and parent process
pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>) -> Arc<Task> {
fn user_task_entry() {
let cur = Task::current();
let user_space = cur.user_space().expect("user task should have user space");
let current_thread = current_thread!();
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);
debug!(
"[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}",
user_mode.context().syscall_ret()
);
loop {
let user_event = user_mode.execute();
let context = user_mode.context_mut();
// handle user event:
handle_user_event(user_event, context);
let current_thread = current_thread!();
// should be do this comparison before handle signal?
if current_thread.status().lock().is_exited() {
break;
}
handle_pending_signal(context).unwrap();
handle_pending_signal(context, &current_thread).unwrap();
if current_thread.status().lock().is_exited() {
debug!("exit due to signal");
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() {
Thread::yield_now();
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.
preempt();
preempt(current_task);
}
debug!("exit user loop");
// 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)