From 367ff671321a21876cc347074a17fcaa7e28d5d5 Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Wed, 24 Sep 2025 19:49:35 +0800 Subject: [PATCH 1/8] ch3 --- os/Cargo.toml | 1 + os/src/syscall/mod.rs | 8 ++++++++ os/src/syscall/process.rs | 24 +++++++++++++++++++++++- os/src/syscall/trace.rs | 18 ++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 os/src/syscall/trace.rs diff --git a/os/Cargo.toml b/os/Cargo.toml index d610c69d..906bc240 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -11,3 +11,4 @@ buddy_system_allocator = "0.6" lazy_static = { version = "1.4.0", features = ["spin_no_std"] } log = "0.4" riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } +spin = "0.9" \ No newline at end of file diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 3b579ba6..555c4ff0 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -21,14 +21,22 @@ const SYSCALL_GET_TIME: usize = 169; /// trace syscall const SYSCALL_TRACE: usize = 410; +use spin::Mutex; + +const MAX_SYSCALLS: usize = 410; +static SYSCALL_COUNTS: Mutex<[usize; MAX_SYSCALLS]> = Mutex::new([0; MAX_SYSCALLS]); + mod fs; mod process; +mod trace; use fs::*; use process::*; +use trace::increment_syscall; /// handle syscall exception with `syscall_id` and other arguments pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { + increment_syscall(syscall_id); match syscall_id { SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index ab43bbe7..2eac3f14 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -3,6 +3,7 @@ use crate::{ task::{exit_current_and_run_next, suspend_current_and_run_next}, timer::get_time_us, }; +use super::trace::get_count; #[repr(C)] #[derive(Debug)] @@ -39,7 +40,28 @@ pub fn sys_get_time(ts: *mut TimeVal, _tz: usize) -> isize { } // TODO: implement the syscall +// 这个系统调用有三种功能,根据 trace_request 的值不同,执行不同的操作: +// 如果 trace_request 为 0,则 id 应被视作 *const u8 ,表示读取当前任务 id 地址处一个字节的无符号整数值。此时应忽略 data 参数。返回值为 id 地址处的值。 +// 如果 trace_request 为 1,则 id 应被视作 *mut u8 ,表示写入 data (作为 u8,即只考虑最低位的一个字节)到该用户程序 id 地址处。返回值应为0。 +// 如果 trace_request 为 2,表示查询当前任务调用编号为 id 的系统调用的次数,返回值为这个调用次数。本次调用也计入统计 。 +// 否则,忽略其他参数,返回值为 -1。 pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { trace!("kernel: sys_trace"); - -1 + match _trace_request { + 0 => { + let id = _id as *const u8; + unsafe { *id as isize } + }, + 1 => { + let id = _id as *mut u8; + unsafe { *id = _data as u8 }; + 0 + }, + 2 => { + get_count(_id) as isize + }, + _ => { + -1 + } + } } diff --git a/os/src/syscall/trace.rs b/os/src/syscall/trace.rs new file mode 100644 index 00000000..6b1b2c71 --- /dev/null +++ b/os/src/syscall/trace.rs @@ -0,0 +1,18 @@ +use super::MAX_SYSCALLS; +use super::SYSCALL_COUNTS; + +pub fn increment_syscall(syscall_num: usize) { + let mut counts = SYSCALL_COUNTS.lock(); + if syscall_num < MAX_SYSCALLS { + counts[syscall_num] += 1; + } +} + +pub fn get_count(syscall_num: usize) -> usize { + let counts = SYSCALL_COUNTS.lock(); + if syscall_num < MAX_SYSCALLS { + counts[syscall_num] + } else { + 0 + } +} From 487f8eef552086ee0f43add8230ea6290fb92313 Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Wed, 24 Sep 2025 20:21:40 +0800 Subject: [PATCH 2/8] small change --- os/src/syscall/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 555c4ff0..ce49922e 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -23,7 +23,7 @@ const SYSCALL_TRACE: usize = 410; use spin::Mutex; -const MAX_SYSCALLS: usize = 410; +const MAX_SYSCALLS: usize = 1000; static SYSCALL_COUNTS: Mutex<[usize; MAX_SYSCALLS]> = Mutex::new([0; MAX_SYSCALLS]); mod fs; From 70060bdafdbe3d842b52bfa14160bb411b08e683 Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Wed, 24 Sep 2025 22:23:04 +0800 Subject: [PATCH 3/8] add syscall count clear --- os/src/syscall/mod.rs | 5 +++++ os/src/syscall/trace.rs | 7 +++++++ os/src/task/mod.rs | 3 +++ 3 files changed, 15 insertions(+) diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index ce49922e..f349b47a 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -46,3 +46,8 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { _ => panic!("Unsupported syscall_id: {}", syscall_id), } } + +/// clear syscall count +pub fn clear_counts() { + trace::clear_counts(); +} \ No newline at end of file diff --git a/os/src/syscall/trace.rs b/os/src/syscall/trace.rs index 6b1b2c71..27b5e30b 100644 --- a/os/src/syscall/trace.rs +++ b/os/src/syscall/trace.rs @@ -16,3 +16,10 @@ pub fn get_count(syscall_num: usize) -> usize { 0 } } + +pub fn clear_counts() { + let mut counts = SYSCALL_COUNTS.lock(); + for i in 0..MAX_SYSCALLS { + counts[i] = 0; + } +} \ No newline at end of file diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index c1636ef4..4577f25d 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -23,6 +23,8 @@ pub use task::{TaskControlBlock, TaskStatus}; pub use context::TaskContext; +pub use crate::syscall; + /// The task manager, where all the tasks are managed. /// /// Functions implemented on `TaskManager` deals with all task state transitions @@ -146,6 +148,7 @@ pub fn run_first_task() { /// or there is no `Ready` task and we can exit with all applications completed fn run_next_task() { TASK_MANAGER.run_next_task(); + syscall::clear_counts(); } /// Change the status of current `Running` task into `Ready`. From 63a2347efa5a819c7db4ee6c25832ed6dcfa98c4 Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Thu, 25 Sep 2025 16:30:32 +0800 Subject: [PATCH 4/8] add to TaskManager --- os/src/syscall/mod.rs | 17 ++++------------- os/src/syscall/process.rs | 5 +++-- os/src/syscall/trace.rs | 25 ------------------------- os/src/task/mod.rs | 33 ++++++++++++++++++++++++++++++++- os/src/task/task.rs | 5 ++++- 5 files changed, 43 insertions(+), 42 deletions(-) delete mode 100644 os/src/syscall/trace.rs diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index f349b47a..a797063f 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -20,23 +20,19 @@ const SYSCALL_YIELD: usize = 124; const SYSCALL_GET_TIME: usize = 169; /// trace syscall const SYSCALL_TRACE: usize = 410; - -use spin::Mutex; - -const MAX_SYSCALLS: usize = 1000; -static SYSCALL_COUNTS: Mutex<[usize; MAX_SYSCALLS]> = Mutex::new([0; MAX_SYSCALLS]); +/// max syscall id +pub const MAX_SYSCALLS: usize = 1000; mod fs; mod process; -mod trace; use fs::*; use process::*; -use trace::increment_syscall; +use crate::task::add_syscall_count; /// handle syscall exception with `syscall_id` and other arguments pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { - increment_syscall(syscall_id); + add_syscall_count(syscall_id); match syscall_id { SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), @@ -46,8 +42,3 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { _ => panic!("Unsupported syscall_id: {}", syscall_id), } } - -/// clear syscall count -pub fn clear_counts() { - trace::clear_counts(); -} \ No newline at end of file diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index 2eac3f14..1b4e7404 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -3,7 +3,8 @@ use crate::{ task::{exit_current_and_run_next, suspend_current_and_run_next}, timer::get_time_us, }; -use super::trace::get_count; + +use crate::task::get_syscall_count; #[repr(C)] #[derive(Debug)] @@ -58,7 +59,7 @@ pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { 0 }, 2 => { - get_count(_id) as isize + get_syscall_count(_id) as isize }, _ => { -1 diff --git a/os/src/syscall/trace.rs b/os/src/syscall/trace.rs deleted file mode 100644 index 27b5e30b..00000000 --- a/os/src/syscall/trace.rs +++ /dev/null @@ -1,25 +0,0 @@ -use super::MAX_SYSCALLS; -use super::SYSCALL_COUNTS; - -pub fn increment_syscall(syscall_num: usize) { - let mut counts = SYSCALL_COUNTS.lock(); - if syscall_num < MAX_SYSCALLS { - counts[syscall_num] += 1; - } -} - -pub fn get_count(syscall_num: usize) -> usize { - let counts = SYSCALL_COUNTS.lock(); - if syscall_num < MAX_SYSCALLS { - counts[syscall_num] - } else { - 0 - } -} - -pub fn clear_counts() { - let mut counts = SYSCALL_COUNTS.lock(); - for i in 0..MAX_SYSCALLS { - counts[i] = 0; - } -} \ No newline at end of file diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 4577f25d..e571b7f3 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -24,6 +24,7 @@ pub use task::{TaskControlBlock, TaskStatus}; pub use context::TaskContext; pub use crate::syscall; +use crate::syscall::MAX_SYSCALLS; /// The task manager, where all the tasks are managed. /// @@ -56,6 +57,7 @@ lazy_static! { let mut tasks = [TaskControlBlock { task_cx: TaskContext::zero_init(), task_status: TaskStatus::UnInit, + syscall_counts: [0; MAX_SYSCALLS], }; MAX_APP_NUM]; for (i, task) in tasks.iter_mut().enumerate() { task.task_cx = TaskContext::goto_restore(init_app_cx(i)); @@ -137,6 +139,26 @@ impl TaskManager { panic!("All applications completed!"); } } + + /// Get syscall count of current task + fn get_syscall_count(&self, syscall_id: usize) -> usize { + let inner = self.inner.exclusive_access(); + let current = inner.current_task; + let tcb = &inner.tasks[current]; + let count = tcb.syscall_counts[syscall_id]; + drop(inner); + count + } + + /// Add syscall count of current task + fn add_syscall_count(&self, syscall_id: usize) { + // println!("add syscall count, syscall_id = {}", syscall_id); + let mut inner = self.inner.exclusive_access(); + let current = inner.current_task; + let tcb = &mut inner.tasks[current]; + tcb.syscall_counts[syscall_id] += 1; + drop(inner); + } } /// Run the first task in task list. @@ -148,7 +170,6 @@ pub fn run_first_task() { /// or there is no `Ready` task and we can exit with all applications completed fn run_next_task() { TASK_MANAGER.run_next_task(); - syscall::clear_counts(); } /// Change the status of current `Running` task into `Ready`. @@ -172,3 +193,13 @@ pub fn exit_current_and_run_next() { mark_current_exited(); run_next_task(); } + +/// Add syscall count of current task +pub fn add_syscall_count(syscall_id: usize) { + TASK_MANAGER.add_syscall_count(syscall_id); +} + +/// Get syscall count of current task +pub fn get_syscall_count(syscall_id: usize) -> usize { + TASK_MANAGER.get_syscall_count(syscall_id) +} \ No newline at end of file diff --git a/os/src/task/task.rs b/os/src/task/task.rs index e6580c9a..50967b5d 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -1,6 +1,7 @@ //! Types related to task management use super::TaskContext; +use crate::syscall::MAX_SYSCALLS; /// The task control block (TCB) of a task. #[derive(Copy, Clone)] @@ -9,6 +10,8 @@ pub struct TaskControlBlock { pub task_status: TaskStatus, /// The task context pub task_cx: TaskContext, + /// syscall count + pub syscall_counts: [usize; MAX_SYSCALLS], } /// The status of a task @@ -22,4 +25,4 @@ pub enum TaskStatus { Running, /// exited Exited, -} +} \ No newline at end of file From 6343fd036444dda21d9a03e2b8cc738fe9fcee57 Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Thu, 25 Sep 2025 17:10:21 +0800 Subject: [PATCH 5/8] Revert "ch3" This reverts commit 367ff671321a21876cc347074a17fcaa7e28d5d5. --- os/Cargo.toml | 1 - os/src/syscall/mod.rs | 11 +++++++---- os/src/syscall/process.rs | 10 ++-------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/os/Cargo.toml b/os/Cargo.toml index 906bc240..d610c69d 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -11,4 +11,3 @@ buddy_system_allocator = "0.6" lazy_static = { version = "1.4.0", features = ["spin_no_std"] } log = "0.4" riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } -spin = "0.9" \ No newline at end of file diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index a797063f..a427e2a6 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -20,19 +20,22 @@ const SYSCALL_YIELD: usize = 124; const SYSCALL_GET_TIME: usize = 169; /// trace syscall const SYSCALL_TRACE: usize = 410; -/// max syscall id -pub const MAX_SYSCALLS: usize = 1000; + +use spin::Mutex; + +const MAX_SYSCALLS: usize = 410; +static SYSCALL_COUNTS: Mutex<[usize; MAX_SYSCALLS]> = Mutex::new([0; MAX_SYSCALLS]); mod fs; mod process; use fs::*; use process::*; -use crate::task::add_syscall_count; +use trace::increment_syscall; /// handle syscall exception with `syscall_id` and other arguments pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { - add_syscall_count(syscall_id); + increment_syscall(syscall_id); match syscall_id { SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index 1b4e7404..5e02aed4 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -3,8 +3,7 @@ use crate::{ task::{exit_current_and_run_next, suspend_current_and_run_next}, timer::get_time_us, }; - -use crate::task::get_syscall_count; +use super::trace::get_count; #[repr(C)] #[derive(Debug)] @@ -41,11 +40,6 @@ pub fn sys_get_time(ts: *mut TimeVal, _tz: usize) -> isize { } // TODO: implement the syscall -// 这个系统调用有三种功能,根据 trace_request 的值不同,执行不同的操作: -// 如果 trace_request 为 0,则 id 应被视作 *const u8 ,表示读取当前任务 id 地址处一个字节的无符号整数值。此时应忽略 data 参数。返回值为 id 地址处的值。 -// 如果 trace_request 为 1,则 id 应被视作 *mut u8 ,表示写入 data (作为 u8,即只考虑最低位的一个字节)到该用户程序 id 地址处。返回值应为0。 -// 如果 trace_request 为 2,表示查询当前任务调用编号为 id 的系统调用的次数,返回值为这个调用次数。本次调用也计入统计 。 -// 否则,忽略其他参数,返回值为 -1。 pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { trace!("kernel: sys_trace"); match _trace_request { @@ -59,7 +53,7 @@ pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { 0 }, 2 => { - get_syscall_count(_id) as isize + get_count(_id) as isize }, _ => { -1 From 4c0e2268dcee8b1264f7a1a757826b8113345b36 Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Thu, 25 Sep 2025 17:16:29 +0800 Subject: [PATCH 6/8] normal --- os/src/syscall/mod.rs | 7 ------- os/src/syscall/process.rs | 4 ++-- os/src/task/mod.rs | 32 -------------------------------- os/src/task/task.rs | 3 --- 4 files changed, 2 insertions(+), 44 deletions(-) diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index a427e2a6..3b579ba6 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -21,21 +21,14 @@ const SYSCALL_GET_TIME: usize = 169; /// trace syscall const SYSCALL_TRACE: usize = 410; -use spin::Mutex; - -const MAX_SYSCALLS: usize = 410; -static SYSCALL_COUNTS: Mutex<[usize; MAX_SYSCALLS]> = Mutex::new([0; MAX_SYSCALLS]); - mod fs; mod process; use fs::*; use process::*; -use trace::increment_syscall; /// handle syscall exception with `syscall_id` and other arguments pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { - increment_syscall(syscall_id); match syscall_id { SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index 5e02aed4..65885302 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -3,7 +3,6 @@ use crate::{ task::{exit_current_and_run_next, suspend_current_and_run_next}, timer::get_time_us, }; -use super::trace::get_count; #[repr(C)] #[derive(Debug)] @@ -30,6 +29,7 @@ pub fn sys_yield() -> isize { pub fn sys_get_time(ts: *mut TimeVal, _tz: usize) -> isize { trace!("kernel: sys_get_time"); let us = get_time_us(); + trace!("kernel: sys_get_time, us = {}", us); unsafe { *ts = TimeVal { sec: us / 1_000_000, @@ -53,7 +53,7 @@ pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { 0 }, 2 => { - get_count(_id) as isize + 0 }, _ => { -1 diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index e571b7f3..7a60e2c3 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -24,7 +24,6 @@ pub use task::{TaskControlBlock, TaskStatus}; pub use context::TaskContext; pub use crate::syscall; -use crate::syscall::MAX_SYSCALLS; /// The task manager, where all the tasks are managed. /// @@ -57,7 +56,6 @@ lazy_static! { let mut tasks = [TaskControlBlock { task_cx: TaskContext::zero_init(), task_status: TaskStatus::UnInit, - syscall_counts: [0; MAX_SYSCALLS], }; MAX_APP_NUM]; for (i, task) in tasks.iter_mut().enumerate() { task.task_cx = TaskContext::goto_restore(init_app_cx(i)); @@ -139,26 +137,6 @@ impl TaskManager { panic!("All applications completed!"); } } - - /// Get syscall count of current task - fn get_syscall_count(&self, syscall_id: usize) -> usize { - let inner = self.inner.exclusive_access(); - let current = inner.current_task; - let tcb = &inner.tasks[current]; - let count = tcb.syscall_counts[syscall_id]; - drop(inner); - count - } - - /// Add syscall count of current task - fn add_syscall_count(&self, syscall_id: usize) { - // println!("add syscall count, syscall_id = {}", syscall_id); - let mut inner = self.inner.exclusive_access(); - let current = inner.current_task; - let tcb = &mut inner.tasks[current]; - tcb.syscall_counts[syscall_id] += 1; - drop(inner); - } } /// Run the first task in task list. @@ -192,14 +170,4 @@ pub fn suspend_current_and_run_next() { pub fn exit_current_and_run_next() { mark_current_exited(); run_next_task(); -} - -/// Add syscall count of current task -pub fn add_syscall_count(syscall_id: usize) { - TASK_MANAGER.add_syscall_count(syscall_id); -} - -/// Get syscall count of current task -pub fn get_syscall_count(syscall_id: usize) -> usize { - TASK_MANAGER.get_syscall_count(syscall_id) } \ No newline at end of file diff --git a/os/src/task/task.rs b/os/src/task/task.rs index 50967b5d..376a60c8 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -1,7 +1,6 @@ //! Types related to task management use super::TaskContext; -use crate::syscall::MAX_SYSCALLS; /// The task control block (TCB) of a task. #[derive(Copy, Clone)] @@ -10,8 +9,6 @@ pub struct TaskControlBlock { pub task_status: TaskStatus, /// The task context pub task_cx: TaskContext, - /// syscall count - pub syscall_counts: [usize; MAX_SYSCALLS], } /// The status of a task From b8eba0be0f5146a35c3d8a1e839a42026ad932c4 Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Thu, 25 Sep 2025 17:22:11 +0800 Subject: [PATCH 7/8] repair --- os/src/syscall/mod.rs | 6 ++++++ os/src/syscall/process.rs | 4 ++-- os/src/task/mod.rs | 34 +++++++++++++++++++++++++++++++++- os/src/task/task.rs | 4 ++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 3b579ba6..8824075d 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -27,8 +27,14 @@ mod process; use fs::*; use process::*; +use crate::task::{add_syscall_count}; + +/// max syscall id +pub const MAX_SYSCALL_ID: usize = 474; + /// handle syscall exception with `syscall_id` and other arguments pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { + add_syscall_count(syscall_id); match syscall_id { SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index 65885302..cb448682 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,6 +1,6 @@ //! Process management syscalls use crate::{ - task::{exit_current_and_run_next, suspend_current_and_run_next}, + task::{exit_current_and_run_next, suspend_current_and_run_next, get_syscall_count}, timer::get_time_us, }; @@ -53,7 +53,7 @@ pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { 0 }, 2 => { - 0 + get_syscall_count(_id) as isize }, _ => { -1 diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 7a60e2c3..07a11c03 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -24,6 +24,7 @@ pub use task::{TaskControlBlock, TaskStatus}; pub use context::TaskContext; pub use crate::syscall; +use crate::syscall::MAX_SYSCALL_ID; /// The task manager, where all the tasks are managed. /// @@ -56,6 +57,7 @@ lazy_static! { let mut tasks = [TaskControlBlock { task_cx: TaskContext::zero_init(), task_status: TaskStatus::UnInit, + syscall_counts: [0; MAX_SYSCALL_ID], }; MAX_APP_NUM]; for (i, task) in tasks.iter_mut().enumerate() { task.task_cx = TaskContext::goto_restore(init_app_cx(i)); @@ -137,6 +139,26 @@ impl TaskManager { panic!("All applications completed!"); } } + + /// Get syscall count of current task + fn get_syscall_count(&self, syscall_id: usize) -> usize { + let inner = self.inner.exclusive_access(); + let current = inner.current_task; + let tcb = &inner.tasks[current]; + let count = tcb.syscall_counts[syscall_id]; + drop(inner); + count + } + + /// Add syscall count of current task + fn add_syscall_count(&self, syscall_id: usize) { + // println!("add syscall count, syscall_id = {}", syscall_id); + let mut inner = self.inner.exclusive_access(); + let current = inner.current_task; + let tcb = &mut inner.tasks[current]; + tcb.syscall_counts[syscall_id] += 1; + drop(inner); + } } /// Run the first task in task list. @@ -170,4 +192,14 @@ pub fn suspend_current_and_run_next() { pub fn exit_current_and_run_next() { mark_current_exited(); run_next_task(); -} \ No newline at end of file +} + +/// Get syscall count of current task +pub fn get_syscall_count(syscall_id: usize) -> usize { + TASK_MANAGER.get_syscall_count(syscall_id) +} + +/// Add syscall count of current task +pub fn add_syscall_count(syscall_id: usize) { + TASK_MANAGER.add_syscall_count(syscall_id); +} diff --git a/os/src/task/task.rs b/os/src/task/task.rs index 376a60c8..50b974ea 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -2,6 +2,8 @@ use super::TaskContext; +use crate::syscall::MAX_SYSCALL_ID; + /// The task control block (TCB) of a task. #[derive(Copy, Clone)] pub struct TaskControlBlock { @@ -9,6 +11,8 @@ pub struct TaskControlBlock { pub task_status: TaskStatus, /// The task context pub task_cx: TaskContext, + /// The syscall count + pub syscall_counts: [usize; MAX_SYSCALL_ID], } /// The status of a task From 71a54d74fb9e468f270347855d552451e092fb8b Mon Sep 17 00:00:00 2001 From: diandianjunA <1730523754@qq.com> Date: Thu, 25 Sep 2025 17:45:19 +0800 Subject: [PATCH 8/8] add report --- os/src/task/mod.rs | 2 +- reports/lab1.md | 140 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 reports/lab1.md diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 07a11c03..37533a1f 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -140,7 +140,7 @@ impl TaskManager { } } - /// Get syscall count of current task + /// Get syscall count of current task fn get_syscall_count(&self, syscall_id: usize) -> usize { let inner = self.inner.exclusive_access(); let current = inner.current_task; diff --git a/reports/lab1.md b/reports/lab1.md new file mode 100644 index 00000000..245870b0 --- /dev/null +++ b/reports/lab1.md @@ -0,0 +1,140 @@ +# Lab1 + +## 实验题目 + +在 ch3 中,我们的系统已经能够支持多个任务分时轮流运行,我们希望引入一个新的系统调用 ``sys_trace``(ID 为 410)用来追踪当前任务系统调用的历史信息,并做对应的修改。定义如下。 + +```rust +fn sys_trace(trace_request: usize, id: usize, data: usize) -> isize +``` + +- 调用规范: + - 这个系统调用有三种功能,根据 trace_request 的值不同,执行不同的操作: + + - 如果 trace_request 为 0,则 id 应被视作 *const u8 ,表示读取当前任务 id 地址处一个字节的无符号整数值。此时应忽略 data 参数。返回值为 id 地址处的值。 + + 如果 trace_request 为 1,则 id 应被视作 *mut u8 ,表示写入 data (作为 u8,即只考虑最低位的一个字节)到该用户程序 id 地址处。返回值应为0。 + + 如果 trace_request 为 2,表示查询当前任务调用编号为 id 的系统调用的次数,返回值为这个调用次数。本次调用也计入统计 。 + + 否则,忽略其他参数,返回值为 -1。 + +- 说明: + - 你可能会注意到,这个调用的读写并不安全,使用不当可能导致崩溃。这是因为在下一章节实现地址空间之前,系统中缺乏隔离机制。所以我们 不要求你实现安全检查机制,只需通过测试用例即可 。 + + - 你还可能注意到,这个系统调用读写本任务内存的功能并不是很有用。这是因为作业的灵感来源 syscall 主要依靠 trace 功能追踪其他任务的信息,但在本章节我们还没有进程、线程等概念,所以简化了操作,只要求追踪自身的信息。 + +## 解决方案 + +首先,我们需要在 `syscall` 中添加 `sys_trace` 系统调用的处理函数。 + +```rust +// TODO: implement the syscall +pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { + trace!("kernel: sys_trace"); + match _trace_request { + 0 => { + let id = _id as *const u8; + unsafe { *id as isize } + }, + 1 => { + let id = _id as *mut u8; + unsafe { *id = _data as u8 }; + 0 + }, + 2 => { + get_syscall_count(_id) as isize + }, + _ => { + -1 + } + } +} +``` + +- 0和1的情况比较简单,直接根据参数进行读写即可。 + +- 2的情况比较复杂,我们需要根据参数 id 来查询当前任务调用编号为 id 的系统调用的次数。 + +根据测试用例的要求,每个app的系统调用次数需要单独存储,因此不能直接使用一个内核中的数组来存储系统调用的次数 + +应当在每个TaskControlBlock中添加对系统调用次数的记录 + +```rust +/// The task control block (TCB) of a task. +#[derive(Copy, Clone)] +pub struct TaskControlBlock { + /// The task status in it's lifecycle + pub task_status: TaskStatus, + /// The task context + pub task_cx: TaskContext, + /// The syscall count + pub syscall_counts: [usize; MAX_SYSCALL_ID], +} +``` + +然后由 `TaskManager` 来对外暴露获取与增加系统调用计数的接口 + +```rust +/// Get syscall count of current task +fn get_syscall_count(&self, syscall_id: usize) -> usize { + let inner = self.inner.exclusive_access(); + let current = inner.current_task; + let tcb = &inner.tasks[current]; + let count = tcb.syscall_counts[syscall_id]; + drop(inner); + count +} + +/// Add syscall count of current task +fn add_syscall_count(&self, syscall_id: usize) { + // println!("add syscall count, syscall_id = {}", syscall_id); + let mut inner = self.inner.exclusive_access(); + let current = inner.current_task; + let tcb = &mut inner.tasks[current]; + tcb.syscall_counts[syscall_id] += 1; + drop(inner); +} +``` + +最后,在 `syscall` 中调用 `TaskManager` 提供的接口来增加系统调用计数 + +```rust +/// handle syscall exception with `syscall_id` and other arguments +pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { + add_syscall_count(syscall_id); + match syscall_id { + SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), + SYSCALL_EXIT => sys_exit(args[0] as i32), + SYSCALL_YIELD => sys_yield(), + SYSCALL_GET_TIME => sys_get_time(args[0] as *mut TimeVal, args[1]), + SYSCALL_TRACE => sys_trace(args[0], args[1], args[2]), + _ => panic!("Unsupported syscall_id: {}", syscall_id), + } +} +``` + +```rust +// TODO: implement the syscall +pub fn sys_trace(trace_request: usize, id: usize, data: usize) -> isize { + trace!("kernel: sys_trace"); + match trace_request { + 0 => { + let id = id as *const u8; + unsafe { *id as isize } + }, + 1 => { + let id = id as *mut u8; + unsafe { *id = data as u8 }; + 0 + }, + 2 => { + let count = get_syscall_count(id); + count as isize + }, + _ => { + -1 + } + } +} +```