1#![no_std]
4#![deny(missing_docs)]
5
6extern crate alloc;
7
8use alloc::alloc::handle_alloc_error;
9use core::{
10 alloc::{GlobalAlloc, Layout},
11 cell::UnsafeCell,
12 ptr::NonNull,
13};
14use customizable_buddy::{BuddyAllocator, LinkedListBuddy, UsizeBuddy};
15
16struct StaticCell<T> {
27 inner: UnsafeCell<T>,
28}
29
30unsafe impl<T> Sync for StaticCell<T> {}
32
33impl<T> StaticCell<T> {
34 const fn new(value: T) -> Self {
36 Self {
37 inner: UnsafeCell::new(value),
38 }
39 }
40
41 #[inline]
47 fn get(&self) -> *mut T {
48 self.inner.get()
49 }
50}
51
52#[inline]
60pub fn init(base_address: usize) {
61 heap_mut().init(
64 core::mem::size_of::<usize>().trailing_zeros() as _,
65 NonNull::new(base_address as *mut u8).unwrap(),
66 );
67}
68
69#[inline]
79pub unsafe fn transfer(region: &'static mut [u8]) {
80 let ptr = NonNull::new(region.as_mut_ptr()).unwrap();
81 heap_mut().transfer(ptr, region.len());
83}
84
85static HEAP: StaticCell<BuddyAllocator<21, UsizeBuddy, LinkedListBuddy>> =
93 StaticCell::new(BuddyAllocator::new());
94
95#[inline]
102fn heap_mut() -> &'static mut BuddyAllocator<21, UsizeBuddy, LinkedListBuddy> {
103 unsafe { &mut *HEAP.get() }
105}
106
107struct Global;
108
109#[global_allocator]
110static GLOBAL: Global = Global;
111
112unsafe impl GlobalAlloc for Global {
115 #[inline]
116 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
117 if let Ok((ptr, _)) = heap_mut().allocate_layout::<u8>(layout) {
120 ptr.as_ptr()
121 } else {
122 handle_alloc_error(layout)
123 }
124 }
125
126 #[inline]
127 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
128 heap_mut().deallocate_layout(NonNull::new(ptr).unwrap(), layout)
131 }
132}