playdate_sys/sys/
allocator.rs1#![cfg(not(test))]
2extern crate alloc;
15
16use core::alloc::{GlobalAlloc, Layout};
17use core::ffi::c_void;
18
19
20#[global_allocator]
21#[cfg(feature = "allocator")]
22pub static GLOBAL: PlaydateAllocator = PlaydateAllocator;
23
24#[alloc_error_handler]
26#[cfg(feature = "allocator")]
27fn alloc_error(layout: Layout) -> ! { panic!("Out of Memory, requested {}.", layout.size()) }
28
29
30pub struct PlaydateAllocator;
31
32unsafe impl GlobalAlloc for PlaydateAllocator {
33 #[inline]
34 unsafe fn alloc(&self, layout: Layout) -> *mut u8 { realloc(core::ptr::null_mut(), layout.size()) as *mut u8 }
35 #[inline]
36 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { dealloc(ptr as *mut c_void); }
37 #[inline]
38 unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 {
39 realloc(ptr as *mut c_void, new_size) as *mut u8
40 }
41}
42
43
44#[track_caller]
45#[allow(static_mut_refs)]
46unsafe fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void {
47 static mut REALLOC: Option<unsafe extern "C" fn(ptr: *mut c_void, size: usize) -> *mut c_void> = None;
49
50 let f = REALLOC.get_or_insert_with(|| {
51 if let Some(realloc) = crate::sys::API.as_ref().and_then(|api| (*api.system).realloc) {
52 realloc
53 } else {
54 panic!("Missed API.realloc")
55 }
56 });
57 f(ptr, size)
58}
59
60
61#[track_caller]
62#[inline(always)]
63pub unsafe fn dealloc(ptr: *mut c_void) { realloc(ptr, 0); }