| use core::alloc::GlobalAlloc; | |
| use core::alloc::Layout; | |
| use core::ptr; | |
| use core::ptr::NonNull; | |
| use linked_list_allocator::Heap; | |
| pub static mut HEAP: Heap = Heap::empty(); | |
| struct TockAllocator; | |
| unsafe impl GlobalAlloc for TockAllocator { | |
| unsafe fn alloc(&self, layout: Layout) -> *mut u8 { | |
| HEAP.allocate_first_fit(layout) | |
| .ok() | |
| .map_or(ptr::null_mut(), NonNull::as_ptr) | |
| } | |
| unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { | |
| HEAP.deallocate(NonNull::new_unchecked(ptr), layout) | |
| } | |
| } | |
| #[global_allocator] | |
| static ALLOCATOR: TockAllocator = TockAllocator; | |
| #[cfg(not(feature = "custom_alloc_error_handler"))] | |
| #[alloc_error_handler] | |
| unsafe fn alloc_error_handler(_: Layout) -> ! { | |
| use crate::syscalls; | |
| // Print 0x01 using the LowLevelDebug capsule (if available). | |
| let _ = syscalls::command1_insecure(8, 2, 0x01); | |
| // Signal a panic using the LowLevelDebug capsule (if available). | |
| let _ = syscalls::command1_insecure(8, 1, 0x01); | |
| loop { | |
| syscalls::raw::yieldk(); | |
| } | |
| } |