#![no_std]
extern crate core;
use core::alloc::{GlobalAlloc, Layout};
use core::cell::UnsafeCell;
use core::mem::MaybeUninit;
use core::ptr::null_mut;
pub struct Heap<const P: usize> {
playarea: usize,
len: UnsafeCell<usize>,
header: UnsafeCell<[MaybeUninit<(*mut u8, usize)>; P]>
}
fn is_allocated(pointer: *mut u8, size: usize) -> bool {
if (pointer..pointer.wrapping_add(size)).contains(&pointer) {
true
} else {
false
}
}
impl<const P: usize> Heap<P> {
const HEADER_ITEM: MaybeUninit<(*mut u8, usize)> = MaybeUninit::uninit();
const HEADER_INIT: [MaybeUninit<(*mut u8, usize)>; P] = [Self::HEADER_ITEM; P];
pub const fn new() -> Self {
Heap {
playarea: P,
len: UnsafeCell::new(0),
header: UnsafeCell::new(Self::HEADER_INIT)
}
}
}
unsafe impl<const P: usize> GlobalAlloc for Heap<P> {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let mut ptr = null_mut();
for pointer in 0..self.playarea {
if !is_allocated(pointer as *mut u8, size) {
ptr = pointer as *mut u8;
break;
}
};
let header_mut = self.header.get();
*header_mut.as_mut().unwrap().get_unchecked_mut(*self.len.get()) = MaybeUninit::new((ptr, size));
*self.len.get() += 1;
ptr
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {}
}
unsafe impl<const P: usize> Sync for Heap<P> {}