Skip to content
This repository was archived by the owner on Aug 11, 2019. It is now read-only.

Resolve all known deadlock issues with PIT scheduling #6

Merged
merged 5 commits into from
Dec 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ linked_list_allocator = { git = "https://github.com/phil-opp/linked-list-allocat
bit_field = "0.7.0"
x86 = "*"

[dependencies.hole_list_allocator]
path = "libs/hole_list_allocator"

[dependencies.lazy_static]
version = "0.2.4"
features = ["spin_no_std"]
Expand Down
8 changes: 0 additions & 8 deletions libs/hole_list_allocator/Cargo.toml

This file was deleted.

49 changes: 0 additions & 49 deletions libs/hole_list_allocator/src/lib.rs

This file was deleted.

4 changes: 2 additions & 2 deletions src/device/pic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const MODE_8086: u8 = 0x01;
pub struct Pic {
offset: u8,
command: Port<u8>,
data: Port<u8>,
pub data: Port<u8>,
}

impl Pic {
Expand All @@ -37,7 +37,7 @@ impl Pic {

///A master and slave PIC.
pub struct ChainedPics {
pics: [Pic; 2],
pub pics: [Pic; 2],
}

impl ChainedPics {
Expand Down
65 changes: 39 additions & 26 deletions src/interrupts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ pub extern "x86-interrupt" fn timer_handler(_stack_frame: &mut ExceptionStackFra
unsafe { PICS.lock().notify_end_of_interrupt(0x20) };

if PIT_TICKS.fetch_add(1, Ordering::SeqCst) >= 10 {
PIT_TICKS.store(0, Ordering::SeqCst);

unsafe {
disable_interrupts_and_then(|| {
SCHEDULER.resched();
Expand All @@ -96,17 +98,20 @@ pub extern "x86-interrupt" fn timer_handler(_stack_frame: &mut ExceptionStackFra
}

pub extern "x86-interrupt" fn keyboard_handler(_stack_frame: &mut ExceptionStackFrame) {
if let Some(c) = read_char() {
print!("{}", c);
}

unsafe { PICS.lock().notify_end_of_interrupt(0x21) };
disable_interrupts_and_then(|| {
if let Some(c) = read_char() {
print!("{}", c);
}
unsafe { PICS.lock().notify_end_of_interrupt(0x21) };
});
}


pub extern "x86-interrupt" fn divide_by_zero_handler(stack_frame: &mut ExceptionStackFrame) {
println!("\nEXCEPTION: DIVIDE BY ZERO\n{:#?}", stack_frame);
loop {}
disable_interrupts_and_then(|| {
println!("\nEXCEPTION: DIVIDE BY ZERO\n{:#?}", stack_frame);
loop {}
});
}

pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut ExceptionStackFrame) {
Expand All @@ -118,42 +123,50 @@ pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut ExceptionStac
}

pub extern "x86-interrupt" fn invalid_opcode_handler(stack_frame: &mut ExceptionStackFrame) {
println!(
"\nEXCEPTION: INVALID OPCODE at {:#x}\n{:#?}",
stack_frame.instruction_pointer,
stack_frame
);
loop {}
disable_interrupts_and_then(|| {
println!(
"\nEXCEPTION: INVALID OPCODE at {:#x}\n{:#?}",
stack_frame.instruction_pointer,
stack_frame
);
loop {}
});
}

pub extern "x86-interrupt" fn page_fault_handler(
stack_frame: &mut ExceptionStackFrame,
error_code: PageFaultErrorCode,
) {
use x86_64::registers::control_regs;
println!(
"\nEXCEPTION: PAGE FAULT while accessing {:#x}\nerror code: \
{:?}\n{:#?}",
control_regs::cr2(),
error_code,
stack_frame
);
loop {}
disable_interrupts_and_then(|| {
use x86_64::registers::control_regs;
println!(
"\nEXCEPTION: PAGE FAULT while accessing {:#x}\nerror code: \
{:?}\n{:#?}",
control_regs::cr2(),
error_code,
stack_frame
);
loop {}
});
}

pub extern "x86-interrupt" fn double_fault_handler(
stack_frame: &mut ExceptionStackFrame,
_error_code: u64,
) {
println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
loop {}
disable_interrupts_and_then(|| {
println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
loop {}
});
}

pub extern "x86-interrupt" fn gpf_handler(
stack_frame: &mut ExceptionStackFrame,
_error_code: u64,
)
{
println!("\nEXCEPTION: GPF\n{:#?}", stack_frame);
loop {}
disable_interrupts_and_then(|| {
println!("\nEXCEPTION: GPF\n{:#?}", stack_frame);
loop {}
});
}
45 changes: 27 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#![feature(const_unique_new)]
#![feature(const_max_value)]
#![feature(core_intrinsics)]
#![feature(global_allocator)]
#![no_std]

extern crate rlibc;
Expand All @@ -22,9 +23,9 @@ extern crate once;
extern crate bit_field;
#[macro_use]
extern crate lazy_static;
extern crate hole_list_allocator as allocator;
#[macro_use]
extern crate alloc;
extern crate linked_list_allocator;

#[macro_use]
mod macros;
Expand All @@ -42,21 +43,22 @@ pub use runtime_glue::*;

#[no_mangle]
pub extern "C" fn kmain(multiboot_information_address: usize) {
device::vga::buffer::clear_screen();
println!("[ INFO ] lambdaOS: Begin init.");

//Load a multiboot BootInfo structure using the address passed in ebx.
let boot_info = unsafe { multiboot2::load(multiboot_information_address) };

//Safety stuff.
enable_nxe_bit();
enable_write_protect_bit();
// Ensure all interrupt masks are set to prevent issues during setup
disable_interrupts();
{
device::vga::buffer::clear_screen();
println!("[ INFO ] lambdaOS: Begin init.");

//Load a multiboot BootInfo structure using the address passed in ebx.
let boot_info = unsafe { multiboot2::load(multiboot_information_address) };

//Safety stuff.
enable_nxe_bit();
enable_write_protect_bit();

// set up guard page and map the heap pages
let mut memory_controller = memory::init(boot_info);
// set up guard page and map the heap pages
let mut memory_controller = memory::init(boot_info);

// Interrupts.
disable_interrupts_and_then(|| {
unsafe {
// Load IDT.
interrupts::init(&mut memory_controller);
Expand All @@ -65,17 +67,18 @@ pub extern "C" fn kmain(multiboot_information_address: usize) {
// Initalise all other hardware devices.
device::init();
}
});

/*let proc_closure = || {
}
enable_interrupts();

let proc_closure = || {
let max_procs = 50;

for i in 0..max_procs {
syscall::create(process_test, format!("test_process_{}", i));
}
};

disable_interrupts_and_then(proc_closure);*/
proc_closure();

use alloc::String;

Expand All @@ -92,3 +95,9 @@ pub extern "C" fn real_main() {
pub extern "C" fn process_test() {
println!("Inside test process.");
}

use memory::heap_allocator::HeapAllocator;

//Attribute tells Rust to use this as the default heap allocator.
#[global_allocator]
static GLOBAL_ALLOC: HeapAllocator = HeapAllocator::new();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this to being under src/memory/mod.rs? I dislike there being too much clutter in src/lib.rs and feel it would be more appropriate to keep it in the memory module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but there's unfortunately a bug in rust where global allocators need to be defined in src/lib.rs

rust-lang/rust#44113

6 changes: 3 additions & 3 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
macro_rules! print {
($($arg:tt)*) => ({
$crate::device::vga::buffer::print(format_args!($($arg)*));
});
($($arg:tt)*) => ({
$crate::device::vga::buffer::print(format_args!($($arg)*));
});
}

macro_rules! println {
Expand Down
48 changes: 48 additions & 0 deletions src/memory/heap_allocator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use alloc::allocator::{Alloc, AllocErr, Layout};
use linked_list_allocator::LockedHeap;
use utils::disable_interrupts_and_then;

pub const HEAP_START: usize = 0o_000_001_000_000_0000;
pub const HEAP_SIZE: usize = 500 * 1024;

pub struct HeapAllocator {
inner: LockedHeap,
}

impl HeapAllocator {
/// Creates an empty heap. All allocate calls will return `None`.
pub const fn new() -> Self {
HeapAllocator {
inner: LockedHeap::empty(),
}
}

/// Initializes an empty heap
///
/// # Unsafety
///
/// This function must be called at most once and must only be used on an
/// empty heap. Also, it is assumed that interrupts are disabled.
pub unsafe fn init(&self, heap_bottom: usize, heap_size: usize) {
self.inner.lock().init(heap_bottom, heap_size);
}
}

/// Wrappers for inner Alloc implementation
unsafe impl<'a> Alloc for &'a HeapAllocator {
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
disable_interrupts_and_then(|| -> Result<*mut u8, AllocErr> {
self.inner.lock().alloc(layout)
})
}

unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
disable_interrupts_and_then(|| {
self.inner.lock().dealloc(ptr, layout);
});
}

fn oom(&mut self, _: AllocErr) -> ! {
panic!("Out of memory");
}
}
8 changes: 3 additions & 5 deletions src/memory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ pub use self::paging::remap_the_kernel;
pub use self::stack_allocator::Stack;
use self::paging::PhysicalAddress;
use multiboot2::BootInformation;
use allocator;

mod area_frame_allocator;
pub mod heap_allocator;
pub mod paging;
mod stack_allocator;

pub const HEAP_START: usize = 0o_000_001_000_000_0000;
pub const HEAP_SIZE: usize = 500 * 1024;

pub const PAGE_SIZE: usize = 4096;

pub fn init(boot_info: &BootInformation) -> MemoryController {
Expand Down Expand Up @@ -57,6 +54,7 @@ pub fn init(boot_info: &BootInformation) -> MemoryController {
let mut active_table = paging::remap_the_kernel(&mut frame_allocator, boot_info);

use self::paging::Page;
use self::heap_allocator::{HEAP_SIZE, HEAP_START};

let heap_start_page = Page::containing_address(HEAP_START);
let heap_end_page = Page::containing_address(HEAP_START + HEAP_SIZE - 1);
Expand All @@ -67,7 +65,7 @@ pub fn init(boot_info: &BootInformation) -> MemoryController {

//Init the heap
unsafe {
allocator::init(HEAP_START, HEAP_SIZE);
::GLOBAL_ALLOC.init(HEAP_START, HEAP_SIZE);
}

let stack_allocator = {
Expand Down
Loading