From 48007b8f1e8f3cc0918739eddc858102bd55b22c Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Sat, 28 Apr 2018 22:07:43 -0600
Subject: [PATCH] Update to new allocation API (WIP)

---
 Cargo.lock                   |  4 ++--
 Cargo.toml                   |  6 +++---
 src/allocator/linked_list.rs | 29 ++++++++---------------------
 src/allocator/mod.rs         |  3 +++
 src/context/list.rs          |  2 +-
 src/context/mod.rs           |  2 +-
 src/lib.rs                   |  1 +
 src/panic.rs                 |  5 +++++
 src/syscall/process.rs       |  2 +-
 9 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 12b8faee..cdbedb84 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -108,7 +108,7 @@ dependencies = [
  "linked_list_allocator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "raw-cpuid 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.37",
- "slab_allocator 0.3.0",
+ "slab_allocator 0.3.1",
  "spin 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -270,7 +270,7 @@ dependencies = [
 
 [[package]]
 name = "slab_allocator"
-version = "0.3.0"
+version = "0.3.1"
 dependencies = [
  "linked_list_allocator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "spin 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 4b04fea8..c61645d5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,7 +14,7 @@ clippy = { version = "*", optional = true }
 linked_list_allocator = "0.6"
 raw-cpuid = "3.0"
 redox_syscall = { path = "syscall" }
-slab_allocator = { path = "slab_allocator" }
+slab_allocator = { path = "slab_allocator", optional = true }
 spin = "0.4"
 
 [dependencies.goblin]
@@ -27,11 +27,11 @@ version = "0.7"
 default-features = false
 
 [features]
-default = ["acpi", "graphical_debug"]
+default = []
 acpi = []
 doc = []
 graphical_debug = []
 live = []
 multi_core = []
 pti = []
-slab = []
+slab = ["slab_allocator"]
diff --git a/src/allocator/linked_list.rs b/src/allocator/linked_list.rs
index 61442ebb..b7de5a1b 100644
--- a/src/allocator/linked_list.rs
+++ b/src/allocator/linked_list.rs
@@ -1,4 +1,5 @@
-use alloc::heap::{Alloc, AllocErr, Layout};
+use alloc::heap::{AllocErr, GlobalAlloc, Layout, Opaque};
+use core::ptr::NonNull;
 use linked_list_allocator::Heap;
 use spin::Mutex;
 
@@ -14,8 +15,8 @@ impl Allocator {
     }
 }
 
-unsafe impl<'a> Alloc for &'a Allocator {
-    unsafe fn alloc(&mut self, mut layout: Layout) -> Result<*mut u8, AllocErr> {
+unsafe impl GlobalAlloc for Allocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
         loop {
             let res = if let Some(ref mut heap) = *HEAP.lock() {
                 heap.allocate_first_fit(layout)
@@ -24,9 +25,7 @@ unsafe impl<'a> Alloc for &'a Allocator {
             };
 
             match res {
-                Err(AllocErr::Exhausted { request }) => {
-                    layout = request;
-
+                Err(AllocErr) => {
                     let size = if let Some(ref heap) = *HEAP.lock() {
                         heap.size()
                     } else {
@@ -41,28 +40,16 @@ unsafe impl<'a> Alloc for &'a Allocator {
                         panic!("__rust_allocate: heap not initialized");
                     }
                 },
-                other => return other,
+                other => return other.ok().map_or(0 as *mut Opaque, |allocation| allocation.as_ptr()),
             }
         }
     }
 
-    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
+    unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
         if let Some(ref mut heap) = *HEAP.lock() {
-            heap.deallocate(ptr, layout)
+            heap.deallocate(NonNull::new_unchecked(ptr), layout)
         } else {
             panic!("__rust_deallocate: heap not initialized");
         }
     }
-
-    fn oom(&mut self, error: AllocErr) -> ! {
-        panic!("Out of memory: {:?}", error);
-    }
-
-    fn usable_size(&self, layout: &Layout) -> (usize, usize) {
-        if let Some(ref mut heap) = *HEAP.lock() {
-            heap.usable_size(layout)
-        } else {
-            panic!("__rust_usable_size: heap not initialized");
-        }
-    }
 }
diff --git a/src/allocator/mod.rs b/src/allocator/mod.rs
index 5b5b0cce..05b5dcd5 100644
--- a/src/allocator/mod.rs
+++ b/src/allocator/mod.rs
@@ -8,7 +8,10 @@ pub use self::linked_list::Allocator;
 #[cfg(feature="slab")]
 pub use self::slab::Allocator;
 
+#[cfg(not(feature="slab"))]
 mod linked_list;
+
+#[cfg(feature="slab")]
 mod slab;
 
 unsafe fn map_heap(active_table: &mut ActivePageTable, offset: usize, size: usize) {
diff --git a/src/context/list.rs b/src/context/list.rs
index 6ae441c1..6b2dc3d3 100644
--- a/src/context/list.rs
+++ b/src/context/list.rs
@@ -67,7 +67,7 @@ impl ContextList {
         let context_lock = self.new_context()?;
         {
             let mut context = context_lock.write();
-            let mut fx = unsafe { Box::from_raw(Heap.alloc(Layout::from_size_align_unchecked(512, 16)).unwrap() as *mut [u8; 512]) };
+            let mut fx = unsafe { Box::from_raw(Heap.alloc(Layout::from_size_align_unchecked(512, 16)).unwrap().as_ptr() as *mut [u8; 512]) };
             for b in fx.iter_mut() {
                 *b = 0;
             }
diff --git a/src/context/mod.rs b/src/context/mod.rs
index c715a7ec..fa2b6969 100644
--- a/src/context/mod.rs
+++ b/src/context/mod.rs
@@ -52,7 +52,7 @@ pub fn init() {
     let mut contexts = contexts_mut();
     let context_lock = contexts.new_context().expect("could not initialize first context");
     let mut context = context_lock.write();
-    let mut fx = unsafe { Box::from_raw(Heap.alloc(Layout::from_size_align_unchecked(512, 16)).unwrap() as *mut [u8; 512]) };
+    let mut fx = unsafe { Box::from_raw(Heap.alloc(Layout::from_size_align_unchecked(512, 16)).unwrap().as_ptr() as *mut [u8; 512]) };
     for b in fx.iter_mut() {
         *b = 0;
     }
diff --git a/src/lib.rs b/src/lib.rs
index cbbd38a9..55e1cbd1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -43,6 +43,7 @@ extern crate bitflags;
 extern crate goblin;
 extern crate linked_list_allocator;
 extern crate spin;
+#[cfg(feature = "slab")]
 extern crate slab_allocator;
 
 use alloc::arc::Arc;
diff --git a/src/panic.rs b/src/panic.rs
index 3545e4d3..6e915e6d 100644
--- a/src/panic.rs
+++ b/src/panic.rs
@@ -22,6 +22,11 @@ pub extern "C" fn rust_begin_unwind(fmt: ::core::fmt::Arguments, file: &str, lin
     }
 }
 
+#[lang = "oom"]
+pub extern fn rust_oom() -> ! {
+    panic!("kernel memory allocation failed");
+}
+
 #[allow(non_snake_case)]
 #[no_mangle]
 /// Required to handle panics
diff --git a/src/syscall/process.rs b/src/syscall/process.rs
index ce0aea21..21a259a5 100644
--- a/src/syscall/process.rs
+++ b/src/syscall/process.rs
@@ -113,7 +113,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
             arch = context.arch.clone();
 
             if let Some(ref fx) = context.kfx {
-                let mut new_fx = unsafe { Box::from_raw(Heap.alloc(Layout::from_size_align_unchecked(512, 16)).unwrap() as *mut [u8; 512]) };
+                let mut new_fx = unsafe { Box::from_raw(Heap.alloc(Layout::from_size_align_unchecked(512, 16)).unwrap().as_ptr() as *mut [u8; 512]) };
                 for (new_b, b) in new_fx.iter_mut().zip(fx.iter()) {
                     *new_b = *b;
                 }
-- 
GitLab