robert-w-gries / rxinu

Rust implementation of Xinu educational operating system
Apache License 2.0
33 stars 4 forks source link

Wrap linked-list-allocator in HeapAllocator to prevent deadlocks #49

Closed robert-w-gries closed 6 years ago

robert-w-gries commented 6 years ago

Fixes #48

There was an issue involving deadlocks where the timer would interrupt String allocation in the syscall::create() call. This revealed a larger problem where allocation of structs, such as Vec or BTreeMap could be interrupted inside a process.

The solution was to wrap all calls to alloc() and dealloc in interrupts::disable_then_restore(). However, our allocator is linked-list-allocator which exists outside of rxinu's control.

Therefore, the solution was to follow the example of le-jzr/sisyphos-kernel-uefi-x86_64 and create a wrapper HeapAllocator object that could disable interrupts then call the inner LockedHeap's alloc and dealloc.

Testing

This was tested by increasing the number of test_processes that we create in src/lib.rs. By increasing the number of created processes to 10000, we are able to consistently hit the deadlock issue at some point.

diff --git a/src/lib.rs b/src/lib.rs
index 69fc445..07b1f7e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -58,7 +58,8 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) {
     kprintln!("\nHEAP START = 0x{:x}", HEAP_START);
     kprintln!("HEAP END = 0x{:x}\n", HEAP_START + HEAP_SIZE);

-    let max_procs = 50;
+    kprintln!("");
+    let max_procs = 10000;
     for i in 0..max_procs {
         syscall::create(test_process, format!("test_process_{}", i));
     }
@@ -77,7 +78,8 @@ pub extern "C" fn rxinu_main() {
 }

 pub extern "C" fn test_process() {
-    kprintln!("In test process!");
+    //kprintln!("In test process!");
+    kprint!(".");
 }