77 lines
2.2 KiB
Rust
77 lines
2.2 KiB
Rust
//! Process management syscalls
|
|
|
|
use crate::config::PAGE_SIZE;
|
|
use crate::mm::{MapPermission, VPNRange, VirtAddr};
|
|
use crate::task::{change_program_brk, create_new_map_area, exit_current_and_run_next, get_current_task_page_table_entry, suspend_current_and_run_next, unmap_virtual_page};
|
|
use crate::timer::get_time_ms;
|
|
|
|
/// task exits and submit an exit code
|
|
pub fn sys_exit(exit_code: i32) -> ! {
|
|
println!("[kernel] Application exited with code {}", exit_code);
|
|
exit_current_and_run_next();
|
|
panic!("Unreachable in sys_exit!");
|
|
}
|
|
|
|
/// current task gives up resources for other tasks
|
|
pub fn sys_yield() -> isize {
|
|
suspend_current_and_run_next();
|
|
0
|
|
}
|
|
|
|
/// get current time
|
|
pub fn sys_get_time() -> isize {
|
|
get_time_ms() as isize
|
|
}
|
|
|
|
/// change data segment size
|
|
pub fn sys_sbrk(size: i32) -> isize {
|
|
if let Some(old_brk) = change_program_brk(size) {
|
|
old_brk as isize
|
|
} else {
|
|
-1
|
|
}
|
|
}
|
|
|
|
/// map files or devices into memory
|
|
pub fn sys_mmap(start: usize, len: usize, prot: usize) -> isize {
|
|
if start % PAGE_SIZE != 0 || prot & !0x7 != 0 || prot & 0x7 == 0 {
|
|
return -1;
|
|
}
|
|
let vpn_start = VirtAddr::from(start).floor();
|
|
let vpn_end = VirtAddr::from(start + len).ceil();
|
|
let vpn_range = VPNRange::new(vpn_start, vpn_end);
|
|
for vpn in vpn_range {
|
|
if let Some(pte) = get_current_task_page_table_entry(vpn) {
|
|
if pte.is_valid() {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
create_new_map_area(
|
|
vpn_start.into(),
|
|
vpn_end.into(),
|
|
MapPermission::from_bits_truncate((prot << 1) as u8) | MapPermission::U
|
|
);
|
|
0
|
|
}
|
|
|
|
/// unmap files or devices into memory
|
|
pub fn sys_munmap(start: usize, len: usize) -> isize {
|
|
if start % PAGE_SIZE != 0 {
|
|
return -1;
|
|
}
|
|
let vpn_start = VirtAddr::from(start).floor();
|
|
let vpn_end = VirtAddr::from(start + len).ceil();
|
|
let vpn_range = VPNRange::new(vpn_start, vpn_end);
|
|
for vpn in vpn_range {
|
|
if let Some(pte) = get_current_task_page_table_entry(vpn) {
|
|
if !pte.is_valid() {
|
|
return -1;
|
|
}
|
|
unmap_virtual_page(vpn)
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
0
|
|
}
|