lab 03
This commit is contained in:
parent
5ab1ca507c
commit
8b2f8bf2a3
9 changed files with 140 additions and 23 deletions
|
@ -5,6 +5,7 @@ pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
|
||||||
pub const MAX_APP_NUM: usize = 4;
|
pub const MAX_APP_NUM: usize = 4;
|
||||||
pub const APP_BASE_ADDRESS: usize = 0x80400000;
|
pub const APP_BASE_ADDRESS: usize = 0x80400000;
|
||||||
pub const APP_SIZE_LIMIT: usize = 0x20000;
|
pub const APP_SIZE_LIMIT: usize = 0x20000;
|
||||||
|
pub const MAX_SYSCALL_NUM: usize = 500;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#[cfg(feature = "board_k210")]
|
#[cfg(feature = "board_k210")]
|
||||||
|
|
|
@ -14,6 +14,7 @@ const SYSCALL_WRITE: usize = 64;
|
||||||
const SYSCALL_EXIT: usize = 93;
|
const SYSCALL_EXIT: usize = 93;
|
||||||
const SYSCALL_YIELD: usize = 124;
|
const SYSCALL_YIELD: usize = 124;
|
||||||
const SYSCALL_GET_TIME: usize = 169;
|
const SYSCALL_GET_TIME: usize = 169;
|
||||||
|
const SYSCALL_TASK_INFO: usize = 410;
|
||||||
|
|
||||||
mod fs;
|
mod fs;
|
||||||
mod process;
|
mod process;
|
||||||
|
@ -21,13 +22,17 @@ mod process;
|
||||||
use fs::*;
|
use fs::*;
|
||||||
use process::*;
|
use process::*;
|
||||||
|
|
||||||
|
use crate::task::TASK_MANAGER;
|
||||||
|
|
||||||
/// handle syscall exception with `syscall_id` and other arguments
|
/// handle syscall exception with `syscall_id` and other arguments
|
||||||
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
||||||
|
TASK_MANAGER.mark_syscall(syscall_id);
|
||||||
match syscall_id {
|
match syscall_id {
|
||||||
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
|
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
|
||||||
SYSCALL_EXIT => sys_exit(args[0] as i32),
|
SYSCALL_EXIT => sys_exit(args[0] as i32),
|
||||||
SYSCALL_YIELD => sys_yield(),
|
SYSCALL_YIELD => sys_yield(),
|
||||||
SYSCALL_GET_TIME => sys_get_time(),
|
SYSCALL_GET_TIME => sys_get_time(),
|
||||||
|
SYSCALL_TASK_INFO => sys_task_info(args[0] as *mut TaskInfo),
|
||||||
_ => panic!("Unsupported syscall_id: {}", syscall_id),
|
_ => panic!("Unsupported syscall_id: {}", syscall_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
//! Process management syscalls
|
//! Process management syscalls
|
||||||
use crate::task::{exit_current_and_run_next, suspend_current_and_run_next};
|
use log::trace;
|
||||||
use crate::timer::get_time_ms;
|
|
||||||
|
use crate::task::{exit_current_and_run_next, suspend_current_and_run_next, TaskStatus, TASK_MANAGER};
|
||||||
|
use crate::timer::{get_time, get_time_ms};
|
||||||
|
use crate::config::MAX_SYSCALL_NUM;
|
||||||
|
|
||||||
|
/// Task information
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct TaskInfo {
|
||||||
|
/// Task status in it's life cycle
|
||||||
|
status: TaskStatus,
|
||||||
|
/// The numbers of syscall called by task
|
||||||
|
syscall_times: [u32; MAX_SYSCALL_NUM],
|
||||||
|
/// Total running time of task
|
||||||
|
time: usize,
|
||||||
|
}
|
||||||
|
|
||||||
/// task exits and submit an exit code
|
/// task exits and submit an exit code
|
||||||
pub fn sys_exit(exit_code: i32) -> ! {
|
pub fn sys_exit(exit_code: i32) -> ! {
|
||||||
|
@ -19,3 +33,14 @@ pub fn sys_yield() -> isize {
|
||||||
pub fn sys_get_time() -> isize {
|
pub fn sys_get_time() -> isize {
|
||||||
get_time_ms() as isize
|
get_time_ms() as isize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// YOUR JOB: Finish sys_task_info to pass testcases
|
||||||
|
pub fn sys_task_info(ti: *mut TaskInfo) -> isize {
|
||||||
|
unsafe {
|
||||||
|
(*ti).status = TASK_MANAGER.get_current_status();
|
||||||
|
(*ti).time = get_time();
|
||||||
|
(*ti).syscall_times = TASK_MANAGER.get_current_syscall_times()
|
||||||
|
}
|
||||||
|
trace!("kernel: sys_task_info");
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
|
@ -15,13 +15,13 @@ mod switch;
|
||||||
#[allow(clippy::module_inception)]
|
#[allow(clippy::module_inception)]
|
||||||
mod task;
|
mod task;
|
||||||
|
|
||||||
use crate::config::MAX_APP_NUM;
|
use crate::config::{MAX_APP_NUM, MAX_SYSCALL_NUM};
|
||||||
use crate::loader::{get_num_app, init_app_cx};
|
use crate::loader::{get_num_app, init_app_cx};
|
||||||
use crate::sbi::shutdown;
|
use crate::sbi::shutdown;
|
||||||
use crate::sync::UPSafeCell;
|
use crate::sync::UPSafeCell;
|
||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
use switch::__switch;
|
use switch::__switch;
|
||||||
use task::{TaskControlBlock, TaskStatus};
|
pub use task::{TaskControlBlock, TaskStatus};
|
||||||
|
|
||||||
pub use context::TaskContext;
|
pub use context::TaskContext;
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ lazy_static! {
|
||||||
let mut tasks = [TaskControlBlock {
|
let mut tasks = [TaskControlBlock {
|
||||||
task_cx: TaskContext::zero_init(),
|
task_cx: TaskContext::zero_init(),
|
||||||
task_status: TaskStatus::UnInit,
|
task_status: TaskStatus::UnInit,
|
||||||
|
syscall_times: [0; MAX_SYSCALL_NUM]
|
||||||
}; MAX_APP_NUM];
|
}; MAX_APP_NUM];
|
||||||
for (i, task) in tasks.iter_mut().enumerate() {
|
for (i, task) in tasks.iter_mut().enumerate() {
|
||||||
task.task_cx = TaskContext::goto_restore(init_app_cx(i));
|
task.task_cx = TaskContext::goto_restore(init_app_cx(i));
|
||||||
|
@ -138,6 +139,36 @@ impl TaskManager {
|
||||||
shutdown(false);
|
shutdown(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get current task id
|
||||||
|
pub fn get_current_id(&self) -> usize {
|
||||||
|
let inner = self.inner.exclusive_access();
|
||||||
|
inner.current_task
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get current task status
|
||||||
|
pub fn get_current_status(&self) -> TaskStatus {
|
||||||
|
let inner = self.inner.exclusive_access();
|
||||||
|
let current = inner.current_task;
|
||||||
|
inner.tasks[current].task_status
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get current task syscall times
|
||||||
|
pub fn get_current_syscall_times(&self) -> [u32; MAX_SYSCALL_NUM] {
|
||||||
|
let inner = self.inner.exclusive_access();
|
||||||
|
let current = inner.current_task;
|
||||||
|
return inner.tasks[current].syscall_times.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// record syscall
|
||||||
|
pub fn mark_syscall(&self, syscall_id: usize) {
|
||||||
|
if syscall_id >= MAX_SYSCALL_NUM {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut inner = self.inner.exclusive_access();
|
||||||
|
let current = inner.current_task;
|
||||||
|
inner.tasks[current].syscall_times[syscall_id] += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// run first task
|
/// run first task
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
//! Types related to task management
|
//! Types related to task management
|
||||||
|
|
||||||
|
use crate::config::MAX_SYSCALL_NUM;
|
||||||
|
|
||||||
use super::TaskContext;
|
use super::TaskContext;
|
||||||
|
|
||||||
|
/// The task control block (TCB) of a task.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct TaskControlBlock {
|
pub struct TaskControlBlock {
|
||||||
|
/// The task status in it's lifecycle
|
||||||
pub task_status: TaskStatus,
|
pub task_status: TaskStatus,
|
||||||
|
/// The task context
|
||||||
pub task_cx: TaskContext,
|
pub task_cx: TaskContext,
|
||||||
|
/// The numbers of syscall called by task
|
||||||
|
pub syscall_times: [u32; MAX_SYSCALL_NUM],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The status of a task
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum TaskStatus {
|
pub enum TaskStatus {
|
||||||
|
/// uninitialized
|
||||||
UnInit,
|
UnInit,
|
||||||
|
/// ready to run
|
||||||
Ready,
|
Ready,
|
||||||
|
/// running
|
||||||
Running,
|
Running,
|
||||||
|
/// exited
|
||||||
Exited,
|
Exited,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,16 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate user_lib;
|
extern crate user_lib;
|
||||||
|
|
||||||
const LEN: usize = 100;
|
use user_lib::{
|
||||||
|
println, task_info, TaskInfo,
|
||||||
|
};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn main() -> i32 {
|
pub fn main() -> usize {
|
||||||
let p = 3u64;
|
let info = TaskInfo::new();
|
||||||
let m = 998244353u64;
|
assert_eq!(0, task_info(&info));
|
||||||
let iter: usize = 200000;
|
println!("task_info {:?}", info);
|
||||||
let mut s = [0u64; LEN];
|
|
||||||
let mut cur = 0usize;
|
|
||||||
s[cur] = 1;
|
|
||||||
for i in 1..=iter {
|
|
||||||
let next = if cur + 1 == LEN { 0 } else { cur + 1 };
|
|
||||||
s[next] = s[cur] * p % m;
|
|
||||||
cur = next;
|
|
||||||
if i % 10000 == 0 {
|
|
||||||
println!("power_3 [{}/{}]", i, iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("{}^{} = {}(MOD {})", p, iter, s[cur], m);
|
|
||||||
println!("Test power_3 OK!");
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
16
user/src/bin/04taskinfo.rs
Normal file
16
user/src/bin/04taskinfo.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
use user_lib::{
|
||||||
|
println, task_info, TaskInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn main() -> usize {
|
||||||
|
let info = TaskInfo::new();
|
||||||
|
assert_eq!(0, task_info(&info));
|
||||||
|
println!("task_info {:?}", info);
|
||||||
|
0
|
||||||
|
}
|
|
@ -45,3 +45,35 @@ pub fn yield_() -> isize {
|
||||||
pub fn get_time() -> isize {
|
pub fn get_time() -> isize {
|
||||||
sys_get_time()
|
sys_get_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
pub enum TaskStatus {
|
||||||
|
UnInit,
|
||||||
|
Ready,
|
||||||
|
Running,
|
||||||
|
Exited,
|
||||||
|
}
|
||||||
|
|
||||||
|
const MAX_SYSCALL_NUM: usize = 500;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TaskInfo {
|
||||||
|
pub status: TaskStatus,
|
||||||
|
pub syscall_times: [u32; MAX_SYSCALL_NUM],
|
||||||
|
pub time: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaskInfo {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
TaskInfo {
|
||||||
|
status: TaskStatus::UnInit,
|
||||||
|
syscall_times: [0; MAX_SYSCALL_NUM],
|
||||||
|
time: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn task_info(info: &TaskInfo) -> isize {
|
||||||
|
sys_task_info(info)
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
|
use crate::TaskInfo;
|
||||||
|
|
||||||
const SYSCALL_WRITE: usize = 64;
|
const SYSCALL_WRITE: usize = 64;
|
||||||
const SYSCALL_EXIT: usize = 93;
|
const SYSCALL_EXIT: usize = 93;
|
||||||
const SYSCALL_YIELD: usize = 124;
|
const SYSCALL_YIELD: usize = 124;
|
||||||
const SYSCALL_GET_TIME: usize = 169;
|
const SYSCALL_GET_TIME: usize = 169;
|
||||||
|
pub const SYSCALL_TASK_INFO: usize = 410;
|
||||||
|
|
||||||
fn syscall(id: usize, args: [usize; 3]) -> isize {
|
fn syscall(id: usize, args: [usize; 3]) -> isize {
|
||||||
let mut ret: isize;
|
let mut ret: isize;
|
||||||
|
@ -34,3 +37,7 @@ pub fn sys_yield() -> isize {
|
||||||
pub fn sys_get_time() -> isize {
|
pub fn sys_get_time() -> isize {
|
||||||
syscall(SYSCALL_GET_TIME, [0, 0, 0])
|
syscall(SYSCALL_GET_TIME, [0, 0, 0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_task_info(info: &TaskInfo) -> isize {
|
||||||
|
syscall(SYSCALL_TASK_INFO, [info as *const _ as usize, 0, 0])
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue