Skip to content

Commit

Permalink
over
Browse files Browse the repository at this point in the history
  • Loading branch information
weixin_46533160 committed Jan 15, 2025
1 parent e6cc075 commit dd995a3
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 21 deletions.
3 changes: 3 additions & 0 deletions os/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ pub const TRAP_CONTEXT_BASE: usize = TRAMPOLINE - PAGE_SIZE;
pub const CLOCK_FREQ: usize = 12500000;
/// the physical memory end
pub const MEMORY_END: usize = 0x88000000;

/// big constant for process scheduling
pub const BIG_STRIDE: isize = 1000_000;
9 changes: 8 additions & 1 deletion os/src/mm/frame_allocator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Implementation of [`FrameAllocator`] which
//! controls all the frames in the operating system.
use super::{PhysAddr, PhysPageNum};
use crate::config::MEMORY_END;
use crate::config::{MEMORY_END, PAGE_SIZE};
use crate::sync::UPSafeCell;
use alloc::vec::Vec;
use core::fmt::{self, Debug, Formatter};
Expand Down Expand Up @@ -134,3 +134,10 @@ pub fn frame_allocator_test() {
drop(v);
println!("frame_allocator_test passed!");
}

/// Check if the remaining physical memory is sufficient
pub fn is_mem_sufficient(_len: usize) -> bool {
let fa = FRAME_ALLOCATOR.exclusive_access();
let page_cnt = fa.end - fa.current + fa.recycled.len();
(_len + PAGE_SIZE - 1) / PAGE_SIZE <= page_cnt
}
13 changes: 13 additions & 0 deletions os/src/mm/memory_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ impl MemorySet {
None,
);
}
/// Remove framed area
pub fn remove_framed_area(&mut self, range: VPNRange) {
let mut idx = 0;
for area in self.areas.iter_mut() {
if area.vpn_range.get_start().0 == range.get_start().0
&& area.vpn_range.get_end().0 == range.get_end().0 {
area.unmap(&mut self.page_table);
break;
}
idx += 1;
}
self.areas.remove(idx);
}
/// remove a area
pub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum) {
if let Some((idx, area)) = self
Expand Down
6 changes: 3 additions & 3 deletions os/src/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ mod heap_allocator;
mod memory_set;
mod page_table;

pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
use address::{StepByOne, VPNRange};
pub use frame_allocator::{frame_alloc, FrameTracker};
pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum, VPNRange};
use address::StepByOne;
pub use frame_allocator::{frame_alloc, FrameTracker, is_mem_sufficient};
pub use memory_set::remap_test;
pub use memory_set::{MapPermission, MemorySet, KERNEL_SPACE};
pub use page_table::{translated_byte_buffer, translated_refmut, translated_str, PageTableEntry};
Expand Down
3 changes: 3 additions & 0 deletions os/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ mod process;

use fs::*;
use process::*;

use crate::task::current_task;
/// handle syscall exception with `syscall_id` and other arguments
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
current_task().unwrap().inc_syscall_times(syscall_id);
match syscall_id {
SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
Expand Down
78 changes: 64 additions & 14 deletions os/src/syscall/process.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
//! Process management syscalls
use core::mem::size_of;

use alloc::sync::Arc;

use crate::{
config::MAX_SYSCALL_NUM,
loader::get_app_data_by_name,
mm::{translated_refmut, translated_str},
mm::{is_mem_sufficient, translated_byte_buffer, translated_refmut, translated_str, VirtAddr},
task::{
add_task, current_task, current_user_token, exit_current_and_run_next,
suspend_current_and_run_next, TaskStatus,
},
add_task, current_task, current_user_token, exit_current_and_run_next, suspend_current_and_run_next, TaskStatus
}, timer::get_time_us,
};

#[repr(C)]
Expand Down Expand Up @@ -119,10 +121,24 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
/// HINT: What if [`TimeVal`] is splitted by two pages ?
pub fn sys_get_time(_ts: *mut TimeVal, _tz: usize) -> isize {
trace!(
"kernel:pid[{}] sys_get_time NOT IMPLEMENTED",
"kernel:pid[{}] sys_get_time",
current_task().unwrap().pid.0
);
-1
let _us = get_time_us();
let time_val = TimeVal {
sec: _us / 1_000_000,
usec: _us % 1_000_000,
};
let buffers = translated_byte_buffer(
current_user_token(), _ts as *const u8, size_of::<TimeVal>());
let mut time_val_ptr = &time_val as *const _ as *const u8;
for buffer in buffers {
unsafe {
time_val_ptr.copy_to(buffer.as_mut_ptr(), buffer.len());
time_val_ptr = time_val_ptr.add(buffer.len());
}
}
0
}

/// YOUR JOB: Finish sys_task_info to pass testcases
Expand All @@ -139,19 +155,37 @@ pub fn sys_task_info(_ti: *mut TaskInfo) -> isize {
/// YOUR JOB: Implement mmap.
pub fn sys_mmap(_start: usize, _len: usize, _port: usize) -> isize {
trace!(
"kernel:pid[{}] sys_mmap NOT IMPLEMENTED",
"kernel:pid[{}] sys_mmap",
current_task().unwrap().pid.0
);
-1
let start_va = VirtAddr::from(_start);
// 1. illegal start virtual address or port
if !start_va.aligned() || _port & !0x7 != 0 || _port & 0x7 == 0 {
return -1;
}

// 2. Check is there sufficient physical memory
if !is_mem_sufficient(_len) {
return -1;
}

let end_va = VirtAddr::from(_start + _len);
current_task().unwrap().mmap(start_va, end_va, _port)
}

/// YOUR JOB: Implement munmap.
pub fn sys_munmap(_start: usize, _len: usize) -> isize {
trace!(
"kernel:pid[{}] sys_munmap NOT IMPLEMENTED",
"kernel:pid[{}] sys_munmap",
current_task().unwrap().pid.0
);
-1
let start_va = VirtAddr::from(_start);
if !start_va.aligned() {
return -1;
}

let end_va = VirtAddr::from(_start + _len);
current_task().unwrap().munmap(start_va, end_va)
}

/// change data segment size
Expand All @@ -168,17 +202,33 @@ pub fn sys_sbrk(size: i32) -> isize {
/// HINT: fork + exec =/= spawn
pub fn sys_spawn(_path: *const u8) -> isize {
trace!(
"kernel:pid[{}] sys_spawn NOT IMPLEMENTED",
"kernel:pid[{}] sys_spawn",
current_task().unwrap().pid.0
);
-1
// spawn a new process based upon _path
let token = current_user_token();
let _path = translated_str(token, _path);
let data_opt = get_app_data_by_name(_path.as_str());
if data_opt.is_none() { // invalid file name
return -1;
}
let current_task = current_task().unwrap();
let new_task = current_task.spawn(data_opt.unwrap());
let new_pid = new_task.getpid();
add_task(new_task);
new_pid as isize
}

// YOUR JOB: Set task priority.
pub fn sys_set_priority(_prio: isize) -> isize {
trace!(
"kernel:pid[{}] sys_set_priority NOT IMPLEMENTED",
"kernel:pid[{}] sys_set_priority",
current_task().unwrap().pid.0
);
-1
if _prio <= 1 {
return -1;
}
let current_task = current_task().unwrap();
current_task.set_prio(_prio);
_prio
}
18 changes: 17 additions & 1 deletion os/src/task/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,27 @@ impl TaskManager {
}
/// Add process back to ready queue
pub fn add(&mut self, task: Arc<TaskControlBlock>) {
task.inc_stride();
self.ready_queue.push_back(task);
}
/// Take a process out of the ready queue
pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
self.ready_queue.pop_front()
// self.ready_queue.pop_front()
let mut min_stride = isize::MAX;
let mut best_idx = 0;
for (idx, tcb) in self.ready_queue.iter().enumerate() {
let stride = tcb.get_stride();
if min_stride > stride {
min_stride = stride;
best_idx = idx;
}
}
if min_stride == isize::MAX {
None
} else {
self.ready_queue.swap(0, best_idx);
self.ready_queue.pop_front()
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions os/src/task/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use super::__switch;
use super::{fetch_task, TaskStatus};
use super::{TaskContext, TaskControlBlock};
use crate::sync::UPSafeCell;
use crate::timer::get_time_ms;
use crate::trap::TrapContext;
use alloc::sync::Arc;
use lazy_static::*;
Expand Down Expand Up @@ -61,6 +62,11 @@ pub fn run_tasks() {
let mut task_inner = task.inner_exclusive_access();
let next_task_cx_ptr = &task_inner.task_cx as *const TaskContext;
task_inner.task_status = TaskStatus::Running;
// if the task is being called for the first time,
if task_inner.time == 0usize {
// then set it to the current time
task_inner.time = get_time_ms();
}
// release coming task_inner manually
drop(task_inner);
// release coming task TCB manually
Expand Down
Loading

0 comments on commit dd995a3

Please sign in to comment.