kernel_api/memory/heap.rs
1//! Provides an interface to act as the kernel heap
2
3#![unstable(feature = "kernel_heap", issue = "4")]
4
5use core::alloc::Layout;
6use core::cmp::min;
7use core::ptr;
8use core::ptr::NonNull;
9use super::AllocError;
10
11/// A heap manager
12pub trait Heap {
13 /// Creates a new instance of the heap manager
14 fn new() -> Self where Self: Sized;
15
16 /// Allocates a new area of memory for `layout`
17 ///
18 /// # Errors
19 ///
20 /// Returns [`AllocError`] if the memory could not be allocated
21 fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, AllocError>;
22
23 /// Deallocates the memory pointed to by `ptr`
24 ///
25 /// # Safety
26 ///
27 /// The `ptr` must have been previously allocated by the same allocator with the same layout as `layout`
28 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
29
30 /// Adjusts the size of the allocation pointed to by `ptr`
31 ///
32 /// # Safety
33 ///
34 /// The `ptr` must have been previously allocated by the same allocator with the same layout as `old_layout`
35 ///
36 /// # Errors
37 ///
38 /// If the size could not be adjusted, returns [`AllocError`] and the old pointer is still valid to the original allocation.
39 unsafe fn reallocate(&self, ptr: NonNull<u8>, old_layout: Layout, new_size: usize) -> Result<NonNull<u8>, AllocError> {
40 let new_layout = Layout::from_size_align(new_size, old_layout.align())
41 .expect("Original layout was somehow invalid?");
42
43 let new = self.allocate(new_layout)?;
44 unsafe {
45 ptr::copy_nonoverlapping(ptr.as_ptr(), new.as_ptr(), min(old_layout.size(), new_size));
46 }
47 Ok(new)
48 }
49}