From 1f6633fe441cfbb0e5842435c2cfcaf7963c8333 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 19 Nov 2017 12:50:16 +0100 Subject: [PATCH] Add a heap_allocator module with a basic bump allocator --- src/lib.rs | 1 + src/memory/heap_allocator.rs | 51 ++++++++++++++++++++++++++++++++++++ src/memory/mod.rs | 1 + 3 files changed, 53 insertions(+) create mode 100644 src/memory/heap_allocator.rs diff --git a/src/lib.rs b/src/lib.rs index f3cc88f..93529aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ #![feature(alloc)] #![feature(const_unique_new)] #![feature(unique)] +#![feature(allocator_api)] #![no_std] diff --git a/src/memory/heap_allocator.rs b/src/memory/heap_allocator.rs new file mode 100644 index 0000000..990a2ea --- /dev/null +++ b/src/memory/heap_allocator.rs @@ -0,0 +1,51 @@ +use alloc::heap::{Alloc, AllocErr, Layout}; + +/// A simple allocator that allocates memory linearly and ignores freed memory. +#[derive(Debug)] +pub struct BumpAllocator { + heap_start: usize, + heap_end: usize, + next: usize, +} + +impl BumpAllocator { + pub const fn new(heap_start: usize, heap_end: usize) -> Self { + Self { heap_start, heap_end, next: heap_start } + } +} + +unsafe impl Alloc for BumpAllocator { + unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + let alloc_start = align_up(self.next, layout.align()); + let alloc_end = alloc_start.saturating_add(layout.size()); + + if alloc_end <= self.heap_end { + self.next = alloc_end; + Ok(alloc_start as *mut u8) + } else { + Err(AllocErr::Exhausted{ request: layout }) + } + } + + unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + // do nothing, leak memory + } +} + +/// Align downwards. Returns the greatest x with alignment `align` +/// so that x <= addr. The alignment must be a power of 2. +pub fn align_down(addr: usize, align: usize) -> usize { + if align.is_power_of_two() { + addr & !(align - 1) + } else if align == 0 { + addr + } else { + panic!("`align` must be a power of 2"); + } +} + +/// Align upwards. Returns the smallest x with alignment `align` +/// so that x >= addr. The alignment must be a power of 2. +pub fn align_up(addr: usize, align: usize) -> usize { + align_down(addr + align - 1, align) +} diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 0b833f0..d0251d3 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -3,6 +3,7 @@ pub use self::paging::remap_the_kernel; use self::paging::PhysicalAddress; mod area_frame_allocator; +mod heap_allocator; mod paging; pub const PAGE_SIZE: usize = 4096;