Small Fix && cargo fmt

This commit is contained in:
Yifan Wu 2022-01-22 12:40:54 -08:00
parent c9583b0f53
commit ae3ba9c26f
83 changed files with 1085 additions and 1079 deletions

View file

@ -23,4 +23,3 @@ impl TaskContext {
}
}
}

View file

@ -1,9 +1,12 @@
use alloc::{vec::Vec, sync::{Arc, Weak}};
use lazy_static::*;
use crate::sync::UPSafeCell;
use crate::mm::{KERNEL_SPACE, MapPermission, PhysPageNum, VirtAddr};
use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT_BASE, USER_STACK_SIZE};
use super::ProcessControlBlock;
use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT_BASE, USER_STACK_SIZE};
use crate::mm::{MapPermission, PhysPageNum, VirtAddr, KERNEL_SPACE};
use crate::sync::UPSafeCell;
use alloc::{
sync::{Arc, Weak},
vec::Vec,
};
use lazy_static::*;
pub struct RecycleAllocator {
current: usize,
@ -29,20 +32,18 @@ impl RecycleAllocator {
assert!(id < self.current);
assert!(
self.recycled.iter().find(|i| **i == id).is_none(),
"id {} has been deallocated!", id
"id {} has been deallocated!",
id
);
self.recycled.push(id);
}
}
lazy_static! {
static ref PID_ALLOCATOR: UPSafeCell<RecycleAllocator> = unsafe {
UPSafeCell::new(RecycleAllocator::new())
};
static ref KSTACK_ALLOCATOR: UPSafeCell<RecycleAllocator> = unsafe {
UPSafeCell::new(RecycleAllocator::new())
};
static ref PID_ALLOCATOR: UPSafeCell<RecycleAllocator> =
unsafe { UPSafeCell::new(RecycleAllocator::new()) };
static ref KSTACK_ALLOCATOR: UPSafeCell<RecycleAllocator> =
unsafe { UPSafeCell::new(RecycleAllocator::new()) };
}
pub struct PidHandle(pub usize);
@ -69,13 +70,11 @@ pub struct KernelStack(pub usize);
pub fn kstack_alloc() -> KernelStack {
let kstack_id = KSTACK_ALLOCATOR.exclusive_access().alloc();
let (kstack_bottom, kstack_top) = kernel_stack_position(kstack_id);
KERNEL_SPACE
.exclusive_access()
.insert_framed_area(
kstack_bottom.into(),
kstack_top.into(),
MapPermission::R | MapPermission::W,
);
KERNEL_SPACE.exclusive_access().insert_framed_area(
kstack_bottom.into(),
kstack_top.into(),
MapPermission::R | MapPermission::W,
);
KernelStack(kstack_id)
}
@ -91,11 +90,15 @@ impl Drop for KernelStack {
impl KernelStack {
#[allow(unused)]
pub fn push_on_top<T>(&self, value: T) -> *mut T where
T: Sized, {
pub fn push_on_top<T>(&self, value: T) -> *mut T
where
T: Sized,
{
let kernel_stack_top = self.get_top();
let ptr_mut = (kernel_stack_top - core::mem::size_of::<T>()) as *mut T;
unsafe { *ptr_mut = value; }
unsafe {
*ptr_mut = value;
}
ptr_mut
}
pub fn get_top(&self) -> usize {
@ -142,23 +145,19 @@ impl TaskUserRes {
// alloc user stack
let ustack_bottom = ustack_bottom_from_tid(self.ustack_base, self.tid);
let ustack_top = ustack_bottom + USER_STACK_SIZE;
process_inner
.memory_set
.insert_framed_area(
ustack_bottom.into(),
ustack_top.into(),
MapPermission::R | MapPermission::W | MapPermission::U,
);
process_inner.memory_set.insert_framed_area(
ustack_bottom.into(),
ustack_top.into(),
MapPermission::R | MapPermission::W | MapPermission::U,
);
// alloc trap_cx
let trap_cx_bottom = trap_cx_bottom_from_tid(self.tid);
let trap_cx_top = trap_cx_bottom + PAGE_SIZE;
process_inner
.memory_set
.insert_framed_area(
trap_cx_bottom.into(),
trap_cx_top.into(),
MapPermission::R | MapPermission::W,
);
process_inner.memory_set.insert_framed_area(
trap_cx_bottom.into(),
trap_cx_top.into(),
MapPermission::R | MapPermission::W,
);
}
fn dealloc_user_res(&self) {
@ -167,10 +166,14 @@ impl TaskUserRes {
let mut process_inner = process.inner_exclusive_access();
// dealloc ustack manually
let ustack_bottom_va: VirtAddr = ustack_bottom_from_tid(self.ustack_base, self.tid).into();
process_inner.memory_set.remove_area_with_start_vpn(ustack_bottom_va.into());
process_inner
.memory_set
.remove_area_with_start_vpn(ustack_bottom_va.into());
// dealloc trap_cx manually
let trap_cx_bottom_va: VirtAddr = trap_cx_bottom_from_tid(self.tid).into();
process_inner.memory_set.remove_area_with_start_vpn(trap_cx_bottom_va.into());
process_inner
.memory_set
.remove_area_with_start_vpn(trap_cx_bottom_va.into());
}
#[allow(unused)]
@ -197,12 +200,18 @@ impl TaskUserRes {
let process = self.process.upgrade().unwrap();
let process_inner = process.inner_exclusive_access();
let trap_cx_bottom_va: VirtAddr = trap_cx_bottom_from_tid(self.tid).into();
process_inner.memory_set.translate(trap_cx_bottom_va.into()).unwrap().ppn()
process_inner
.memory_set
.translate(trap_cx_bottom_va.into())
.unwrap()
.ppn()
}
pub fn ustack_base(&self) -> usize { self.ustack_base }
pub fn ustack_base(&self) -> usize {
self.ustack_base
}
pub fn ustack_top(&self) -> usize {
ustack_bottom_from_tid(self.ustack_base, self.tid) + USER_STACK_SIZE
ustack_bottom_from_tid(self.ustack_base, self.tid) + USER_STACK_SIZE
}
}
@ -212,4 +221,3 @@ impl Drop for TaskUserRes {
self.dealloc_user_res();
}
}

View file

@ -1,5 +1,5 @@
use crate::sync::UPSafeCell;
use super::TaskControlBlock;
use crate::sync::UPSafeCell;
use alloc::collections::VecDeque;
use alloc::sync::Arc;
use lazy_static::*;
@ -11,7 +11,9 @@ pub struct TaskManager {
/// A simple FIFO scheduler.
impl TaskManager {
pub fn new() -> Self {
Self { ready_queue: VecDeque::new(), }
Self {
ready_queue: VecDeque::new(),
}
}
pub fn add(&mut self, task: Arc<TaskControlBlock>) {
self.ready_queue.push_back(task);
@ -22,9 +24,8 @@ impl TaskManager {
}
lazy_static! {
pub static ref TASK_MANAGER: UPSafeCell<TaskManager> = unsafe {
UPSafeCell::new(TaskManager::new())
};
pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
unsafe { UPSafeCell::new(TaskManager::new()) };
}
pub fn add_task(task: Arc<TaskControlBlock>) {

View file

@ -1,38 +1,26 @@
mod context;
mod id;
mod manager;
mod process;
mod processor;
mod switch;
mod task;
mod manager;
mod processor;
mod id;
mod process;
use crate::fs::{open_file, OpenFlags};
use switch::__switch;
use alloc::sync::Arc;
use manager::fetch_task;
use lazy_static::*;
use manager::fetch_task;
use process::ProcessControlBlock;
use switch::__switch;
pub use context::TaskContext;
pub use id::{kstack_alloc, pid_alloc, KernelStack, PidHandle};
pub use manager::add_task;
pub use processor::{
run_tasks,
current_task,
current_process,
current_user_token,
current_trap_cx_user_va,
current_trap_cx,
current_kstack_top,
take_current_task,
schedule,
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
current_user_token, run_tasks, schedule, take_current_task,
};
pub use task::{TaskControlBlock, TaskStatus};
pub use manager::add_task;
pub use id::{
PidHandle,
pid_alloc,
KernelStack,
kstack_alloc,
};
pub fn suspend_current_and_run_next() {
// There must be an application running.
@ -86,7 +74,7 @@ pub fn exit_current_and_run_next(exit_code: i32) {
// move all child processes under init process
let mut initproc_inner = INITPROC.inner_exclusive_access();
for child in process_inner.children.iter() {
child.inner_exclusive_access().parent = Some(Arc::downgrade(&INITPROC));
child.inner_exclusive_access().parent = Some(Arc::downgrade(&INITPROC));
initproc_inner.children.push(child.clone());
}
}
@ -103,6 +91,8 @@ pub fn exit_current_and_run_next(exit_code: i32) {
process_inner.children.clear();
// deallocate other data in user space i.e. program code/data section
process_inner.memory_set.recycle_data_pages();
// drop file descriptors
process_inner.fd_table.clear();
}
drop(process);
// we do not have to save task context

View file

@ -1,20 +1,16 @@
use crate::mm::{
MemorySet,
KERNEL_SPACE,
translated_refmut,
};
use crate::trap::{TrapContext, trap_handler};
use crate::sync::{UPSafeCell, Mutex, Semaphore, Condvar};
use core::cell::RefMut;
use super::add_task;
use super::id::RecycleAllocator;
use super::TaskControlBlock;
use super::{PidHandle, pid_alloc};
use super::add_task;
use alloc::sync::{Weak, Arc};
use super::{pid_alloc, PidHandle};
use crate::fs::{File, Stdin, Stdout};
use crate::mm::{translated_refmut, MemorySet, KERNEL_SPACE};
use crate::sync::{Condvar, Mutex, Semaphore, UPSafeCell};
use crate::trap::{trap_handler, TrapContext};
use alloc::string::String;
use alloc::sync::{Arc, Weak};
use alloc::vec;
use alloc::vec::Vec;
use alloc::string::String;
use crate::fs::{File, Stdin, Stdout};
use core::cell::RefMut;
pub struct ProcessControlBlock {
// immutable
@ -34,7 +30,7 @@ pub struct ProcessControlBlockInner {
pub task_res_allocator: RecycleAllocator,
pub mutex_list: Vec<Option<Arc<dyn Mutex>>>,
pub semaphore_list: Vec<Option<Arc<Semaphore>>>,
pub condvar_list: Vec<Option<Arc<Condvar>>>,
pub condvar_list: Vec<Option<Arc<Condvar>>>,
}
impl ProcessControlBlockInner {
@ -44,8 +40,7 @@ impl ProcessControlBlockInner {
}
pub fn alloc_fd(&mut self) -> usize {
if let Some(fd) = (0..self.fd_table.len())
.find(|fd| self.fd_table[*fd].is_none()) {
if let Some(fd) = (0..self.fd_table.len()).find(|fd| self.fd_table[*fd].is_none()) {
fd
} else {
self.fd_table.push(None);
@ -57,7 +52,7 @@ impl ProcessControlBlockInner {
self.task_res_allocator.alloc()
}
pub fn dealloc_tid(&mut self, tid: usize){
pub fn dealloc_tid(&mut self, tid: usize) {
self.task_res_allocator.dealloc(tid)
}
@ -82,26 +77,28 @@ impl ProcessControlBlock {
let pid_handle = pid_alloc();
let process = Arc::new(Self {
pid: pid_handle,
inner: unsafe { UPSafeCell::new(ProcessControlBlockInner {
is_zombie: false,
memory_set,
parent: None,
children: Vec::new(),
exit_code: 0,
fd_table: vec![
// 0 -> stdin
Some(Arc::new(Stdin)),
// 1 -> stdout
Some(Arc::new(Stdout)),
// 2 -> stderr
Some(Arc::new(Stdout)),
],
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
semaphore_list: Vec::new(),
condvar_list: Vec::new(),
})}
inner: unsafe {
UPSafeCell::new(ProcessControlBlockInner {
is_zombie: false,
memory_set,
parent: None,
children: Vec::new(),
exit_code: 0,
fd_table: vec![
// 0 -> stdin
Some(Arc::new(Stdin)),
// 1 -> stdout
Some(Arc::new(Stdout)),
// 2 -> stderr
Some(Arc::new(Stdout)),
],
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
semaphore_list: Vec::new(),
condvar_list: Vec::new(),
})
},
});
// create a main thread, we should allocate ustack and trap_cx here
let task = Arc::new(TaskControlBlock::new(
@ -154,7 +151,7 @@ impl ProcessControlBlock {
.map(|arg| {
translated_refmut(
new_token,
(argv_base + arg * core::mem::size_of::<usize>()) as *mut usize
(argv_base + arg * core::mem::size_of::<usize>()) as *mut usize,
)
})
.collect();
@ -201,29 +198,37 @@ impl ProcessControlBlock {
new_fd_table.push(None);
}
}
// create child process pcb
// create child process pcb
let child = Arc::new(Self {
pid,
inner: unsafe { UPSafeCell::new(ProcessControlBlockInner {
is_zombie: false,
memory_set,
parent: Some(Arc::downgrade(self)),
children: Vec::new(),
exit_code: 0,
fd_table: new_fd_table,
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
semaphore_list: Vec::new(),
condvar_list: Vec::new(),
})}
inner: unsafe {
UPSafeCell::new(ProcessControlBlockInner {
is_zombie: false,
memory_set,
parent: Some(Arc::downgrade(self)),
children: Vec::new(),
exit_code: 0,
fd_table: new_fd_table,
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
semaphore_list: Vec::new(),
condvar_list: Vec::new(),
})
},
});
// add child
parent.children.push(Arc::clone(&child));
// create main thread of child process
let task = Arc::new(TaskControlBlock::new(
Arc::clone(&child),
parent.get_task(0).inner_exclusive_access().res.as_ref().unwrap().ustack_base(),
parent
.get_task(0)
.inner_exclusive_access()
.res
.as_ref()
.unwrap()
.ustack_base(),
// here we do not allocate trap_cx or ustack again
// but mention that we allocate a new kstack here
false,
@ -246,4 +251,3 @@ impl ProcessControlBlock {
self.pid.0
}
}

View file

@ -1,10 +1,10 @@
use super::{TaskContext, TaskControlBlock, ProcessControlBlock};
use super::__switch;
use super::{fetch_task, TaskStatus};
use super::{ProcessControlBlock, TaskContext, TaskControlBlock};
use crate::sync::UPSafeCell;
use crate::trap::TrapContext;
use alloc::sync::Arc;
use lazy_static::*;
use super::{fetch_task, TaskStatus};
use super::__switch;
use crate::trap::TrapContext;
use crate::sync::UPSafeCell;
pub struct Processor {
current: Option<Arc<TaskControlBlock>>,
@ -30,9 +30,7 @@ impl Processor {
}
lazy_static! {
pub static ref PROCESSOR: UPSafeCell<Processor> = unsafe {
UPSafeCell::new(Processor::new())
};
pub static ref PROCESSOR: UPSafeCell<Processor> = unsafe { UPSafeCell::new(Processor::new()) };
}
pub fn run_tasks() {
@ -50,13 +48,10 @@ pub fn run_tasks() {
// release processor manually
drop(processor);
unsafe {
__switch(
idle_task_cx_ptr,
next_task_cx_ptr,
);
__switch(idle_task_cx_ptr, next_task_cx_ptr);
}
} else {
println!("no tasks available in run_tasks");
println!("no tasks available in run_tasks");
}
}
}
@ -80,7 +75,10 @@ pub fn current_user_token() -> usize {
}
pub fn current_trap_cx() -> &'static mut TrapContext {
current_task().unwrap().inner_exclusive_access().get_trap_cx()
current_task()
.unwrap()
.inner_exclusive_access()
.get_trap_cx()
}
pub fn current_trap_cx_user_va() -> usize {
@ -94,10 +92,7 @@ pub fn current_trap_cx_user_va() -> usize {
}
pub fn current_kstack_top() -> usize {
current_task()
.unwrap()
.kstack
.get_top()
current_task().unwrap().kstack.get_top()
}
pub fn schedule(switched_task_cx_ptr: *mut TaskContext) {
@ -105,9 +100,6 @@ pub fn schedule(switched_task_cx_ptr: *mut TaskContext) {
let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
drop(processor);
unsafe {
__switch(
switched_task_cx_ptr,
idle_task_cx_ptr,
);
__switch(switched_task_cx_ptr, idle_task_cx_ptr);
}
}

View file

@ -4,8 +4,5 @@ use core::arch::global_asm;
global_asm!(include_str!("switch.S"));
extern "C" {
pub fn __switch(
current_task_cx_ptr: *mut TaskContext,
next_task_cx_ptr: *const TaskContext
);
pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext);
}

View file

@ -1,8 +1,8 @@
use alloc::sync::{Arc, Weak};
use crate::{mm::PhysPageNum, sync::UPSafeCell};
use crate::trap::TrapContext;
use super::id::TaskUserRes;
use super::{KernelStack, ProcessControlBlock, TaskContext, kstack_alloc};
use super::{kstack_alloc, KernelStack, ProcessControlBlock, TaskContext};
use crate::trap::TrapContext;
use crate::{mm::PhysPageNum, sync::UPSafeCell};
use alloc::sync::{Arc, Weak};
use core::cell::RefMut;
pub struct TaskControlBlock {
@ -37,7 +37,7 @@ impl TaskControlBlockInner {
pub fn get_trap_cx(&self) -> &'static mut TrapContext {
self.trap_cx_ppn.get_mut()
}
#[allow(unused)]
fn get_status(&self) -> TaskStatus {
self.task_status
@ -48,7 +48,7 @@ impl TaskControlBlock {
pub fn new(
process: Arc<ProcessControlBlock>,
ustack_base: usize,
alloc_user_res: bool
alloc_user_res: bool,
) -> Self {
let res = TaskUserRes::new(Arc::clone(&process), ustack_base, alloc_user_res);
let trap_cx_ppn = res.trap_cx_ppn();
@ -57,15 +57,15 @@ impl TaskControlBlock {
Self {
process: Arc::downgrade(&process),
kstack,
inner: unsafe { UPSafeCell::new(
TaskControlBlockInner {
inner: unsafe {
UPSafeCell::new(TaskControlBlockInner {
res: Some(res),
trap_cx_ppn,
task_cx: TaskContext::goto_trap_return(kstack_top),
task_status: TaskStatus::Ready,
exit_code: None,
}
)},
})
},
}
}
}