mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 09:53:24 +00:00
Reduce some redundant usage of current!
and current_thread!
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
98a2e623e2
commit
8f3b1f8ddf
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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, ¤t_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, ¤t_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)
|
||||
|
Reference in New Issue
Block a user