Add MutexSpin and several syscalls.

This commit is contained in:
Yifan Wu 2021-10-07 12:40:47 -07:00
parent d1e55d85d8
commit 8974a29245
8 changed files with 159 additions and 2 deletions

View file

@ -1,3 +1,5 @@
mod up;
mod mutex;
pub use up::UPSafeCell;
pub use up::UPSafeCell;
pub use mutex::{Mutex, MutexSpin};

40
os/src/sync/mutex.rs Normal file
View file

@ -0,0 +1,40 @@
use super::UPSafeCell;
use crate::task::suspend_current_and_run_next;
pub trait Mutex: Sync + Send {
fn lock(&self);
fn unlock(&self);
}
pub struct MutexSpin {
locked: UPSafeCell<bool>,
}
impl MutexSpin {
pub fn new() -> Self {
Self {
locked: unsafe { UPSafeCell::new(false) },
}
}
}
impl Mutex for MutexSpin {
fn lock(&self) {
loop {
let mut locked = self.locked.exclusive_access();
if *locked {
drop(locked);
suspend_current_and_run_next();
continue;
} else {
*locked = true;
return;
}
}
}
fn unlock(&self) {
let mut locked = self.locked.exclusive_access();
*locked = false;
}
}

View file

@ -14,14 +14,19 @@ const SYSCALL_WAITPID: usize = 260;
const SYSCALL_THREAD_CREATE: usize = 1000;
const SYSCALL_GETTID: usize = 1001;
const SYSCALL_WAITTID: usize = 1002;
const SYSCALL_MUTEX_CREATE: usize = 1010;
const SYSCALL_MUTEX_LOCK: usize = 1011;
const SYSCALL_MUTEX_UNLOCK: usize = 1012;
mod fs;
mod process;
mod thread;
mod sync;
use fs::*;
use process::*;
use thread::*;
use sync::*;
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
match syscall_id {
@ -41,6 +46,9 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
SYSCALL_THREAD_CREATE => sys_thread_create(args[0]),
SYSCALL_GETTID => sys_gettid(),
SYSCALL_WAITTID => sys_waittid(args[0]) as isize,
SYSCALL_MUTEX_CREATE => sys_mutex_create(),
SYSCALL_MUTEX_LOCK => sys_mutex_lock(args[0]),
SYSCALL_MUTEX_UNLOCK => sys_mutex_unlock(args[0]),
_ => panic!("Unsupported syscall_id: {}", syscall_id),
}
}

40
os/src/syscall/sync.rs Normal file
View file

@ -0,0 +1,40 @@
use crate::task::current_process;
use crate::sync::MutexSpin;
use alloc::sync::Arc;
pub fn sys_mutex_create() -> isize {
let process = current_process();
let mut process_inner = process.inner_exclusive_access();
if let Some(id) = process_inner
.mutex_list
.iter()
.enumerate()
.find(|(_, item)| item.is_none())
.map(|(id, _)| id) {
process_inner.mutex_list[id] = Some(Arc::new(MutexSpin::new()));
id as isize
} else {
process_inner.mutex_list.push(Some(Arc::new(MutexSpin::new())));
process_inner.mutex_list.len() as isize - 1
}
}
pub fn sys_mutex_lock(mutex_id: usize) -> isize {
let process = current_process();
let process_inner = process.inner_exclusive_access();
let mutex = Arc::clone(process_inner.mutex_list[mutex_id].as_ref().unwrap());
drop(process_inner);
drop(process);
mutex.lock();
0
}
pub fn sys_mutex_unlock(mutex_id: usize) -> isize {
let process = current_process();
let process_inner = process.inner_exclusive_access();
let mutex = Arc::clone(process_inner.mutex_list[mutex_id].as_ref().unwrap());
drop(process_inner);
drop(process);
mutex.unlock();
0
}

View file

@ -4,7 +4,7 @@ use crate::mm::{
translated_refmut,
};
use crate::trap::{TrapContext, trap_handler};
use crate::sync::UPSafeCell;
use crate::sync::{UPSafeCell, Mutex};
use core::cell::RefMut;
use super::id::RecycleAllocator;
use super::TaskControlBlock;
@ -32,6 +32,7 @@ pub struct ProcessControlBlockInner {
pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
pub tasks: Vec<Option<Arc<TaskControlBlock>>>,
pub task_res_allocator: RecycleAllocator,
pub mutex_list: Vec<Option<Arc<dyn Mutex>>>,
}
impl ProcessControlBlockInner {
@ -95,6 +96,7 @@ impl ProcessControlBlock {
],
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
})}
});
// create a main thread, we should allocate ustack and trap_cx here
@ -207,6 +209,7 @@ impl ProcessControlBlock {
fd_table: new_fd_table,
tasks: Vec::new(),
task_res_allocator: RecycleAllocator::new(),
mutex_list: Vec::new(),
})}
});
// add child