Implement many process syscalls.

This commit is contained in:
Yifan Wu 2020-12-10 11:57:26 +08:00
parent 81bef97f09
commit 3642f9c56d
20 changed files with 383 additions and 88 deletions

View file

@ -5,17 +5,11 @@ mod manager;
mod processor;
mod pid;
use crate::loader::{get_num_app, get_app_data};
use crate::trap::TrapContext;
use core::cell::RefCell;
use lazy_static::*;
use crate::loader::{get_app_data_by_name};
use switch::__switch;
use task::{TaskControlBlock, TaskStatus};
use alloc::vec::Vec;
use alloc::sync::Arc;
use spin::Mutex;
use manager::fetch_task;
use pid::{PidHandle, pid_alloc, KernelStack};
pub use context::TaskContext;
pub use processor::{
@ -27,13 +21,21 @@ pub use processor::{
schedule,
};
pub use manager::add_task;
pub use pid::{PidHandle, pid_alloc, KernelStack};
pub fn suspend_current_and_run_next() {
// There must be an application running.
let task = current_task().unwrap();
let task_cx_ptr = task.lock().get_task_cx_ptr2();
// Change status to Ready.
task.lock().task_status = TaskStatus::Ready;
let task = take_current_task().unwrap();
// ---- temporarily hold current PCB lock
let task_cx_ptr = task.acquire_inner_lock().get_task_cx_ptr2();
// ---- release current PCB lock
// ++++ temporarily hold current PCB lock
// Change status to Ready
task.acquire_inner_lock().task_status = TaskStatus::Ready;
// ++++ release current PCB lock
// push back to ready queue.
add_task(task);
// jump to scheduling cycle
@ -41,10 +43,37 @@ pub fn suspend_current_and_run_next() {
}
pub fn exit_current_and_run_next() {
// The resource recycle mechanism needs child processes. Now we just panic!
panic!("An application exited!");
// take from Processor
let task = take_current_task().unwrap();
// **** hold current PCB lock
let mut inner = task.acquire_inner_lock();
// Change status to Zombie
inner.task_status = TaskStatus::Zombie;
// move any child to its parent
// ++++++ hold parent PCB lock here
{
let parent = inner.parent.as_ref().unwrap().upgrade().unwrap();
let mut parent_inner = parent.acquire_inner_lock();
for child in inner.children.iter() {
parent_inner.children.push(child.clone());
}
}
// ++++++ release parent PCB lock here
inner.children.clear();
// deallocate user space
inner.memory_set.clear();
drop(inner);
// **** release current PCB lock
// drop task manually to maintain rc correctly
drop(task);
// we do not have to save task context
let _unused: usize = 0;
schedule(&_unused as *const _);
}
pub fn add_application(elf_data: &[u8], app_id: usize) {
add_task(Arc::new(Mutex::new(TaskControlBlock::new(elf_data, app_id))));
pub fn add_initproc() {
let data = get_app_data_by_name("initproc").unwrap();
add_task(Arc::new(TaskControlBlock::new(data)));
}