You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.6 KiB

  1. //! Bullshit naïve bump allocator for kernel heap testing
  2. //! Lovingly ripped off from^W^W^W inspired by phil-opp's rust os articles
  3. #![feature(const_fn)]
  4. #![no_std]
  5. #[derive(Debug)]
  6. pub struct Heap {
  7. /// Start of the heap we're allocating into.
  8. heap_start: usize,
  9. /// End of the heap we're allocating into.
  10. heap_end: usize,
  11. /// The next free address in the heap. Absolute address, *not* relative to `heap_start`!
  12. next_addr: usize,
  13. }
  14. impl Heap {
  15. /// Create a new allocator using the given range
  16. /// [heap_start, heap_start+heap_size] for the heap
  17. pub const fn new(heap_start: usize, heap_size: usize) -> Heap {
  18. Heap {
  19. heap_start: heap_start,
  20. heap_end: heap_start + heap_size,
  21. next_addr: heap_start,
  22. }
  23. }
  24. /// Allocate a chunk of memory with (size, alignment)
  25. pub fn allocate(&mut self, size: usize, align: usize) -> Option<*mut u8> {
  26. let alloc_start = align_up(self.next_addr, align);
  27. let alloc_end = alloc_start.saturating_add(size);
  28. if alloc_end <= self.heap_end {
  29. self.next_addr = alloc_end;
  30. Some(alloc_start as *mut u8)
  31. } else {
  32. None
  33. }
  34. }
  35. pub fn deallocate(&mut self, _ptr: *mut u8, _size: usize, _align: usize) {
  36. // nothing! just leak
  37. }
  38. }
  39. // unsafe impl Alloc for BumpAllocator {
  40. // #[inline]
  41. // unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
  42. // self.allocate(layout.size(), layout.align()).ok_or(AllocErr::Exhausted {request: layout})
  43. // }
  44. // unsafe fn dealloc(&mut self, _ptr: *mut u8, _layout: Layout) {
  45. // // just leak
  46. // }
  47. // fn oom(&mut self, err: AllocErr) -> ! {
  48. // panic!("kheap OOM: {:?}!", err);
  49. // }
  50. // // Just copy the whole thing up to a new block
  51. // unsafe fn realloc(&mut self, ptr: *mut u8, layout: Layout, new_layout: Layout) -> Result<*mut u8, AllocErr> {
  52. // use core::{ptr, cmp};
  53. // let copy_size = cmp::min(layout.size(), new_layout.size()); // copy len = min(size, size')
  54. // let new_ptr = self.alloc(new_layout)?; // alloc new block
  55. // ptr::copy(ptr, new_ptr, copy_size);
  56. // self.dealloc(ptr, layout); // dealloc old pointer
  57. // Ok(new_ptr)
  58. // }
  59. // }
  60. pub fn align_down(addr: usize, align: usize) -> usize {
  61. if align.is_power_of_two() {
  62. // unset bits after alignment bit
  63. addr & !(align - 1)
  64. } else if align == 0 {
  65. addr
  66. } else {
  67. panic!("`align` must be a power of 2");
  68. }
  69. }
  70. pub fn align_up(addr: usize, align: usize) -> usize {
  71. align_down(addr + align - 1, align)
  72. }