Skip to content

Commit

Permalink
impl stride
Browse files Browse the repository at this point in the history
  • Loading branch information
Etavioxy committed Jun 18, 2023
1 parent b5836e7 commit f106395
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ easy-fs-fuse/Cargo.lock
easy-fs-fuse/target/*
tools/
pushall.sh
*.bak
14 changes: 14 additions & 0 deletions files.bak/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
DOCKER_NAME ?= dinghao188/rcore-tutorial
.PHONY: docker build_docker

docker:
docker run --rm -it --mount type=bind,source=$(shell pwd),destination=/mnt ${DOCKER_NAME}

bash:
docker start rcore-tutorial
docker exec -it rcore-tutorial bash

build_docker:
docker build -t ${DOCKER_NAME} .
fmt:
cd os ; cargo fmt; cd ../user; cargo fmt; cd ..
2 changes: 1 addition & 1 deletion os/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
SYSCALL_YIELD => sys_yield(),
SYSCALL_GET_TIME => sys_get_time(),
SYSCALL_GETPID => sys_getpid(),
SYSCALL_FORK => sys_fork(),
SYSCALL_FORK => sys_fork(args[0] as u32),
SYSCALL_EXEC => sys_exec(args[0] as *const u8),
SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
_ => panic!("Unsupported syscall_id: {}", syscall_id),
Expand Down
9 changes: 7 additions & 2 deletions os/src/syscall/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ pub fn sys_getpid() -> isize {
current_task().unwrap().pid.0 as isize
}

pub fn sys_fork() -> isize {
pub fn sys_fork(priority: u32) -> isize {
let current_task = current_task().unwrap();
let new_task = current_task.fork();
let pr = if priority != 0 {
priority
} else {
current_task.inner_exclusive_access().pr.priority
};
let new_task = current_task.fork(pr);
let new_pid = new_task.pid.0;
// modify trap context of new_task, because it returns immediately after switching
let trap_cx = new_task.inner_exclusive_access().get_trap_cx();
Expand Down
10 changes: 5 additions & 5 deletions os/src/task/manager.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
//!Implementation of [`TaskManager`]
use super::TaskControlBlock;
use crate::sync::UPSafeCell;
use alloc::collections::VecDeque;
use alloc::collections::BinaryHeap;
use alloc::sync::Arc;
use lazy_static::*;
///A array of `TaskControlBlock` that is thread-safe
pub struct TaskManager {
ready_queue: VecDeque<Arc<TaskControlBlock>>,
ready_queue: BinaryHeap<Arc<TaskControlBlock>>,
}

/// A simple FIFO scheduler.
impl TaskManager {
///Creat an empty TaskManager
pub fn new() -> Self {
Self {
ready_queue: VecDeque::new(),
ready_queue: BinaryHeap::new(),
}
}
///Add a task to `TaskManager`
pub fn add(&mut self, task: Arc<TaskControlBlock>) {
self.ready_queue.push_back(task);
self.ready_queue.push(task);
}
///Remove the first task and return it,or `None` if `TaskManager` is empty
pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
self.ready_queue.pop_front()
self.ready_queue.pop()
}
}

Expand Down
2 changes: 2 additions & 0 deletions os/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub fn suspend_current_and_run_next() {
let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext;
// Change status to Ready
task_inner.task_status = TaskStatus::Ready;
task_inner.pr.stride += task_inner.pr.pass;
drop(task_inner);
// ---- release current PCB

Expand Down Expand Up @@ -81,6 +82,7 @@ pub fn exit_current_and_run_next(exit_code: i32) {

// **** access current TCB exclusively
let mut inner = task.inner_exclusive_access();
println!("[EXIT] task pid {} priority {} time {} index {}", task.getpid(), inner.pr.priority, inner.pr.stride / inner.pr.pass, (inner.pr.stride / inner.pr.pass) *1000 / inner.pr.priority);
// Change status to Zombie
inner.task_status = TaskStatus::Zombie;
// Record exit code
Expand Down
65 changes: 64 additions & 1 deletion os/src/task/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,48 @@ use crate::sync::UPSafeCell;
use crate::trap::{trap_handler, TrapContext};
use alloc::sync::{Arc, Weak};
use alloc::vec::Vec;
use core::cmp::Ordering;
use core::cell::RefMut;

const STRIDE_BASE: u32 = 100000000;

#[derive(Clone)]
pub struct Priority {
pub priority: u32,
pub stride: u32,
pub pass: u32,
}

impl Priority {
pub fn new(priority: u32) -> Self {
Self {
priority,
stride: 0,
pass: STRIDE_BASE / priority,
}
}
}

impl PartialEq for Priority {
fn eq(&self, other: &Self) -> bool {
self.stride == other.stride
}
}

impl Eq for Priority {}

impl PartialOrd for Priority {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Priority {
fn cmp(&self, other: &Self) -> Ordering {
other.stride.cmp(&self.stride)
}
}

pub struct TaskControlBlock {
// immutable
pub pid: PidHandle,
Expand All @@ -17,7 +57,28 @@ pub struct TaskControlBlock {
inner: UPSafeCell<TaskControlBlockInner>,
}

impl PartialEq for TaskControlBlock {
fn eq(&self, other: &Self) -> bool {
self.inner_exclusive_access().pr.eq(&other.inner_exclusive_access().pr)
}
}

impl Eq for TaskControlBlock {}

impl PartialOrd for TaskControlBlock {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.inner_exclusive_access().pr.cmp(&other.inner_exclusive_access().pr))
}
}

impl Ord for TaskControlBlock {
fn cmp(&self, other: &Self) -> Ordering {
self.inner_exclusive_access().pr.cmp(&other.inner_exclusive_access().pr)
}
}

pub struct TaskControlBlockInner {
pub pr: Priority,
pub trap_cx_ppn: PhysPageNum,
pub base_size: usize,
pub task_cx: TaskContext,
Expand Down Expand Up @@ -69,6 +130,7 @@ impl TaskControlBlock {
kernel_stack,
inner: unsafe {
UPSafeCell::new(TaskControlBlockInner {
pr: Priority::new(2),
trap_cx_ppn,
base_size: user_sp,
task_cx: TaskContext::goto_trap_return(kernel_stack_top),
Expand Down Expand Up @@ -118,7 +180,7 @@ impl TaskControlBlock {
);
// **** release inner automatically
}
pub fn fork(self: &Arc<Self>) -> Arc<Self> {
pub fn fork(self: &Arc<Self>, priority: u32) -> Arc<Self> {
// ---- access parent PCB exclusively
let mut parent_inner = self.inner_exclusive_access();
// copy user space(include trap context)
Expand All @@ -136,6 +198,7 @@ impl TaskControlBlock {
kernel_stack,
inner: unsafe {
UPSafeCell::new(TaskControlBlockInner {
pr: Priority::new(priority),
trap_cx_ppn,
base_size: parent_inner.base_size,
task_cx: TaskContext::goto_trap_return(kernel_stack_top),
Expand Down
28 changes: 28 additions & 0 deletions user/src/bin/initproc_origin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#![no_std]
#![no_main]

#[macro_use]
extern crate user_lib;

use user_lib::{exec, fork, wait, yield_};

#[no_mangle]
fn main() -> i32 {
if fork() == 0 {
exec("user_shell\0");
} else {
loop {
let mut exit_code: i32 = 0;
let pid = wait(&mut exit_code);
if pid == -1 {
yield_();
continue;
}
println!(
"[initproc] Released a zombie process, pid={}, exit_code={}",
pid, exit_code,
);
}
}
0
}
15 changes: 9 additions & 6 deletions user/src/bin/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#[macro_use]
extern crate user_lib;

use user_lib::{exit, fork, get_time, getpid, wait, yield_};
use user_lib::{exit, fork_with_priority, get_time, getpid, wait, yield_};

static NUM: usize = 30;
static NUM: usize = 20;
const N: usize = 10;
static P: i32 = 10007;
type Arr = [[i32; N]; N];
Expand All @@ -24,7 +24,7 @@ fn work(times: isize) {
}
yield_();
println!("pid {} is running ({} times)!.", getpid(), times);
for _ in 0..times {
for t in 0..times {
for i in 0..N {
for j in 0..N {
c[i][j] = 0;
Expand All @@ -40,6 +40,9 @@ fn work(times: isize) {
b[i][j] = c[i][j];
}
}
if t % 1000 == 0 {
println!("pid {} run {} times!.", getpid(), t);
}
}
println!("pid {} done!.", getpid());
exit(0);
Expand All @@ -48,10 +51,10 @@ fn work(times: isize) {
#[no_mangle]
pub fn main() -> i32 {
for _ in 0..NUM {
let pid = fork();
let current_time = get_time();
let times = (current_time as i32 as isize) * (current_time as i32 as isize) % 2000;
let pid = fork_with_priority((times/100+4) as u32);
if pid == 0 {
let current_time = get_time();
let times = (current_time as i32 as isize) * (current_time as i32 as isize) % 1000;
work(times * 10);
}
}
Expand Down
5 changes: 4 additions & 1 deletion user/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ pub fn getpid() -> isize {
sys_getpid()
}
pub fn fork() -> isize {
sys_fork()
sys_fork(0)
}
pub fn fork_with_priority(priority: u32) -> isize {
sys_fork(priority)
}
pub fn exec(path: &str) -> isize {
sys_exec(path)
Expand Down
4 changes: 2 additions & 2 deletions user/src/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub fn sys_getpid() -> isize {
syscall(SYSCALL_GETPID, [0, 0, 0])
}

pub fn sys_fork() -> isize {
syscall(SYSCALL_FORK, [0, 0, 0])
pub fn sys_fork(priority: u32) -> isize {
syscall(SYSCALL_FORK, [priority as usize, 0, 0])
}

pub fn sys_exec(path: &str) -> isize {
Expand Down

0 comments on commit f106395

Please sign in to comment.