mirror of
https://github.com/sgmarz/osblog.git
synced 2024-11-24 02:16:19 +04:00
Added locking to the scheduler. Since this is invoked so often, it causes a race with the test_elf process.
This commit is contained in:
parent
ef0997be74
commit
532b246f7b
@ -8,8 +8,8 @@ use crate::syscall::syscall_sleep;
|
||||
pub const DEFAULT_LOCK_SLEEP: usize = 10000;
|
||||
#[repr(u32)]
|
||||
pub enum MutexState {
|
||||
Locked = 0,
|
||||
Unlocked = 1,
|
||||
Unlocked = 0,
|
||||
Locked = 1,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -44,14 +44,14 @@ impl<'a> Mutex {
|
||||
/// Never use a sleep lock for the process list. Sleeping requires
|
||||
/// the process list to function, so you'll deadlock if you do.
|
||||
pub fn sleep_lock(&mut self) {
|
||||
while self.lock() == false {
|
||||
while !self.lock() {
|
||||
syscall_sleep(DEFAULT_LOCK_SLEEP);
|
||||
}
|
||||
}
|
||||
|
||||
/// Can safely be used inside of an interrupt context.
|
||||
pub fn spin_lock(&mut self) {
|
||||
while self.lock() == false {}
|
||||
while !self.lock() {}
|
||||
}
|
||||
|
||||
pub fn unlock(&mut self) {
|
||||
|
@ -59,7 +59,6 @@ pub fn set_running(pid: u16) -> bool {
|
||||
// of process pointers.
|
||||
let mut retval = false;
|
||||
unsafe {
|
||||
PROCESS_LIST_MUTEX.spin_lock();
|
||||
if let Some(mut pl) = PROCESS_LIST.take() {
|
||||
for proc in pl.iter_mut() {
|
||||
if proc.pid == pid {
|
||||
@ -73,7 +72,6 @@ pub fn set_running(pid: u16) -> bool {
|
||||
// Some(pl).
|
||||
PROCESS_LIST.replace(pl);
|
||||
}
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
}
|
||||
retval
|
||||
}
|
||||
@ -86,7 +84,6 @@ pub fn set_waiting(pid: u16) -> bool {
|
||||
// of process pointers.
|
||||
let mut retval = false;
|
||||
unsafe {
|
||||
PROCESS_LIST_MUTEX.spin_lock();
|
||||
if let Some(mut pl) = PROCESS_LIST.take() {
|
||||
for proc in pl.iter_mut() {
|
||||
if proc.pid == pid {
|
||||
@ -100,7 +97,6 @@ pub fn set_waiting(pid: u16) -> bool {
|
||||
// Some(pl).
|
||||
PROCESS_LIST.replace(pl);
|
||||
}
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
}
|
||||
retval
|
||||
}
|
||||
@ -111,7 +107,6 @@ pub fn set_sleeping(pid: u16, duration: usize) -> bool {
|
||||
// of process pointers.
|
||||
let mut retval = false;
|
||||
unsafe {
|
||||
PROCESS_LIST_MUTEX.spin_lock();
|
||||
if let Some(mut pl) = PROCESS_LIST.take() {
|
||||
for proc in pl.iter_mut() {
|
||||
if proc.pid == pid {
|
||||
@ -129,7 +124,6 @@ pub fn set_sleeping(pid: u16, duration: usize) -> bool {
|
||||
// Some(pl).
|
||||
PROCESS_LIST.replace(pl);
|
||||
}
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
}
|
||||
retval
|
||||
}
|
||||
@ -138,7 +132,6 @@ pub fn set_sleeping(pid: u16, duration: usize) -> bool {
|
||||
/// this function does nothing.
|
||||
pub fn delete_process(pid: u16) {
|
||||
unsafe {
|
||||
PROCESS_LIST_MUTEX.spin_lock();
|
||||
if let Some(mut pl) = PROCESS_LIST.take() {
|
||||
for i in 0..pl.len() {
|
||||
let p = pl.get_mut(i).unwrap();
|
||||
@ -154,7 +147,6 @@ pub fn delete_process(pid: u16) {
|
||||
// Some(pl).
|
||||
PROCESS_LIST.replace(pl);
|
||||
}
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +154,6 @@ pub fn delete_process(pid: u16) {
|
||||
/// unsafe since the process can be deleted and we'll still have a pointer.
|
||||
pub unsafe fn get_by_pid(pid: u16) -> *mut Process {
|
||||
let mut ret = null_mut();
|
||||
PROCESS_LIST_MUTEX.spin_lock();
|
||||
if let Some(mut pl) = PROCESS_LIST.take() {
|
||||
for i in pl.iter_mut() {
|
||||
if i.get_pid() == pid {
|
||||
@ -172,7 +163,6 @@ pub unsafe fn get_by_pid(pid: u16) -> *mut Process {
|
||||
}
|
||||
PROCESS_LIST.replace(pl);
|
||||
}
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
ret
|
||||
}
|
||||
|
||||
@ -243,8 +233,6 @@ pub fn add_kernel_process(func: fn()) -> u16 {
|
||||
// then move ownership back to the PROCESS_LIST.
|
||||
// This allows mutual exclusion as anyone else trying to grab
|
||||
// the process list will get None rather than the Deque.
|
||||
unsafe { PROCESS_LIST_MUTEX.spin_lock(); }
|
||||
if let Some(mut pl) = unsafe { PROCESS_LIST.take() } {
|
||||
// .take() will replace PROCESS_LIST with None and give
|
||||
// us the only copy of the Deque.
|
||||
let func_addr = func as usize;
|
||||
@ -286,15 +274,16 @@ pub fn add_kernel_process(func: fn()) -> u16 {
|
||||
(*ret_proc.frame).mode = CpuMode::Machine as usize;
|
||||
(*ret_proc.frame).pid = ret_proc.pid as usize;
|
||||
}
|
||||
|
||||
if let Some(mut pl) = unsafe { PROCESS_LIST.take() } {
|
||||
pl.push_back(ret_proc);
|
||||
// Now, we no longer need the owned Deque, so we hand it
|
||||
// back by replacing the PROCESS_LIST's None with the
|
||||
// Some(pl).
|
||||
unsafe {
|
||||
PROCESS_LIST.replace(pl);
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
}
|
||||
return my_pid;
|
||||
my_pid
|
||||
}
|
||||
else {
|
||||
unsafe { PROCESS_LIST_MUTEX.unlock(); }
|
||||
@ -398,6 +387,7 @@ pub fn add_kernel_process_args(func: fn(args_ptr: usize), args: usize) -> u16 {
|
||||
/// but later, it should call the shell.
|
||||
pub fn init() -> usize {
|
||||
unsafe {
|
||||
PROCESS_LIST_MUTEX.spin_lock();
|
||||
PROCESS_LIST = Some(VecDeque::with_capacity(15));
|
||||
// add_process_default(init_process);
|
||||
add_kernel_process(init_process);
|
||||
@ -412,6 +402,7 @@ pub fn init() -> usize {
|
||||
// println!("Init's frame is at 0x{:08x}", frame);
|
||||
// Put the process list back in the global.
|
||||
PROCESS_LIST.replace(pl);
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
// Return the first instruction's address to execute.
|
||||
// Since we use the MMU, all start here.
|
||||
(*p).pc
|
||||
|
@ -3,12 +3,13 @@
|
||||
// Stephen Marz
|
||||
// 27 Dec 2019
|
||||
|
||||
use crate::process::{ProcessState, PROCESS_LIST};
|
||||
use crate::process::{ProcessState, PROCESS_LIST, PROCESS_LIST_MUTEX};
|
||||
use crate::cpu::get_mtime;
|
||||
|
||||
pub fn schedule() -> usize {
|
||||
let mut frame_addr: usize = 0x1111;
|
||||
unsafe {
|
||||
PROCESS_LIST_MUTEX.spin_lock();
|
||||
if let Some(mut pl) = PROCESS_LIST.take() {
|
||||
// Rust allows us to label loops so that break statements can be
|
||||
// targeted.
|
||||
@ -39,6 +40,7 @@ pub fn schedule() -> usize {
|
||||
else {
|
||||
println!("could not take process list");
|
||||
}
|
||||
PROCESS_LIST_MUTEX.unlock();
|
||||
}
|
||||
frame_addr
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user