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}