diff --git a/framework/aster-frame/src/arch/x86/trap.rs b/framework/aster-frame/src/arch/x86/trap.rs
index 3c53de8f4..2036849b8 100644
--- a/framework/aster-frame/src/arch/x86/trap.rs
+++ b/framework/aster-frame/src/arch/x86/trap.rs
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: MPL-2.0
+use core::sync::atomic::{AtomicBool, Ordering};
+
use align_ext::AlignExt;
use log::debug;
#[cfg(feature = "intel_tdx")]
@@ -14,6 +16,7 @@ use crate::arch::{
};
use crate::{
cpu::{CpuException, PageFaultErrorCode, PAGE_FAULT},
+ cpu_local,
trap::call_irq_callback_functions,
vm::{
kspace::{KERNEL_PAGE_TABLE, LINEAR_MAPPING_BASE_VADDR, LINEAR_MAPPING_VADDR_RANGE},
@@ -22,6 +25,17 @@ use crate::{
},
};
+cpu_local! {
+ static IS_KERNEL_INTERRUPTED: AtomicBool = AtomicBool::new(false);
+}
+
+/// Returns true if this function is called within the context of an IRQ handler
+/// and the IRQ occurs while the CPU is executing in the kernel mode.
+/// Otherwise, it returns false.
+pub fn is_kernel_interrupted() -> bool {
+ IS_KERNEL_INTERRUPTED.load(Ordering::Acquire)
+}
+
/// Only from kernel
#[no_mangle]
extern "sysv64" fn trap_handler(f: &mut TrapFrame) {
@@ -43,7 +57,9 @@ extern "sysv64" fn trap_handler(f: &mut TrapFrame) {
}
}
} else {
+ IS_KERNEL_INTERRUPTED.store(true, Ordering::Release);
call_irq_callback_functions(f);
+ IS_KERNEL_INTERRUPTED.store(false, Ordering::Release);
}
}
diff --git a/kernel/aster-nix/src/lib.rs b/kernel/aster-nix/src/lib.rs
index 5281c6c8b..69321dccb 100644
--- a/kernel/aster-nix/src/lib.rs
+++ b/kernel/aster-nix/src/lib.rs
@@ -80,6 +80,7 @@ pub fn init() {
device::init().unwrap();
vdso::init();
taskless::init();
+ process::init();
}
fn init_thread() {
diff --git a/kernel/aster-nix/src/process/mod.rs b/kernel/aster-nix/src/process/mod.rs
index be309e032..82115bacb 100644
--- a/kernel/aster-nix/src/process/mod.rs
+++ b/kernel/aster-nix/src/process/mod.rs
@@ -32,3 +32,7 @@ pub use program_loader::{check_executable_file, load_program_to_vm};
pub use rlimit::ResourceType;
pub use term_status::TermStatus;
pub use wait::{wait_child_exit, WaitOptions};
+
+pub(super) fn init() {
+ process::init();
+}
diff --git a/kernel/aster-nix/src/process/posix_thread/builder.rs b/kernel/aster-nix/src/process/posix_thread/builder.rs
index 5ed3db918..190b4d013 100644
--- a/kernel/aster-nix/src/process/posix_thread/builder.rs
+++ b/kernel/aster-nix/src/process/posix_thread/builder.rs
@@ -11,6 +11,7 @@ use crate::{
Credentials, Process,
},
thread::{status::ThreadStatus, task, thread_table, Thread, Tid},
+ time::{clocks::ProfClock, TimerManager},
};
/// The builder to build a posix thread
@@ -94,6 +95,11 @@ impl PosixThreadBuilder {
let thread = Arc::new_cyclic(|thread_ref| {
let task = task::create_new_user_task(user_space, thread_ref.clone());
let status = ThreadStatus::Init;
+
+ let prof_clock = ProfClock::new();
+ let virtual_timer_manager = TimerManager::new(prof_clock.user_clock().clone());
+ let prof_timer_manager = TimerManager::new(prof_clock.clone());
+
let posix_thread = PosixThread {
process,
is_main_thread,
@@ -106,6 +112,9 @@ impl PosixThreadBuilder {
sig_context: Mutex::new(None),
sig_stack: Mutex::new(None),
robust_list: Mutex::new(None),
+ prof_clock,
+ virtual_timer_manager,
+ prof_timer_manager,
};
Thread::new(tid, task, posix_thread, status)
diff --git a/kernel/aster-nix/src/process/posix_thread/mod.rs b/kernel/aster-nix/src/process/posix_thread/mod.rs
index d49fe0ee0..c7f2ffd53 100644
--- a/kernel/aster-nix/src/process/posix_thread/mod.rs
+++ b/kernel/aster-nix/src/process/posix_thread/mod.rs
@@ -21,6 +21,7 @@ use crate::{
prelude::*,
process::signal::constants::SIGCONT,
thread::{thread_table, Tid},
+ time::{clocks::ProfClock, Timer, TimerManager},
util::write_val_to_user,
};
@@ -62,6 +63,15 @@ pub struct PosixThread {
/// FIXME: This field may be removed. For glibc applications with RESTORER flag set, the sig_context is always equals with rsp.
sig_context: Mutex