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