Implement many process syscalls.
This commit is contained in:
parent
81bef97f09
commit
3642f9c56d
20 changed files with 383 additions and 88 deletions
|
@ -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)));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue