Fix race condition

The first timer interrupt might occur before the heap is initialized. With lazy_static, this causes an allocation failure since the VecDeque is allocated when it's accessed the first time. This commit fixes this by only initializing VecDeque in `add_thread`.
This commit is contained in:
Philipp Oppermann
2020-01-23 08:50:35 +01:00
parent 241c1ab2c9
commit 11a0eb679c

View File

@@ -1,5 +1,4 @@
use alloc::collections::VecDeque; use alloc::collections::VecDeque;
use lazy_static::lazy_static;
use x86_64::structures::paging::{FrameAllocator, Mapper, Size4KiB}; use x86_64::structures::paging::{FrameAllocator, Mapper, Size4KiB};
use x86_64::VirtAddr; use x86_64::VirtAddr;
@@ -17,15 +16,15 @@ pub unsafe fn context_switch(stack_pointer: VirtAddr) {
} }
pub fn scheduler() { pub fn scheduler() {
let next = PAUSED_THREADS.try_lock().and_then(|mut t| t.pop_front()); let next = PAUSED_THREADS.try_lock().and_then(|mut paused_threads| {
paused_threads.as_mut().and_then(|threads| threads.pop_front())
});
if let Some(next) = next { if let Some(next) = next {
unsafe { context_switch(next) }; unsafe { context_switch(next) };
} }
} }
lazy_static! { static PAUSED_THREADS: spin::Mutex<Option<VecDeque<VirtAddr>>> = spin::Mutex::new(None);
static ref PAUSED_THREADS: spin::Mutex<VecDeque<VirtAddr>> = spin::Mutex::new(VecDeque::new());
}
#[no_mangle] #[no_mangle]
fn add_paused_thread(stack_pointer: VirtAddr) { fn add_paused_thread(stack_pointer: VirtAddr) {
@@ -33,7 +32,7 @@ fn add_paused_thread(stack_pointer: VirtAddr) {
} }
fn add_thread(stack_pointer: VirtAddr) { fn add_thread(stack_pointer: VirtAddr) {
PAUSED_THREADS.lock().push_back(stack_pointer); PAUSED_THREADS.lock().get_or_insert_with(VecDeque::new).push_back(stack_pointer);
} }
pub fn create_thread( pub fn create_thread(