mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
implement allocators as zsts
This commit is contained in:
parent
3ec95a0277
commit
e92e8d39a5
|
@ -9,9 +9,9 @@ use alloc::boxed::Box;
|
|||
#[agb::entry]
|
||||
fn main(_gba: agb::Gba) -> ! {
|
||||
loop {
|
||||
let a = Box::new_in(1, agb::EWRAM_ALLOC);
|
||||
let a = Box::new_in(1, agb::ExternalAllocator);
|
||||
let b = Box::new(1);
|
||||
let c = Box::new_in(3, agb::IWRAM_ALLOC);
|
||||
let c = Box::new_in(3, agb::InternalAllocator);
|
||||
agb::println!("ewram allocation made to {:?}", &*a as *const _);
|
||||
agb::println!("global allocation made to {:?}", &*b as *const _);
|
||||
agb::println!("iwram allocation made to {:?}", &*c as *const _);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use core::alloc::Layout;
|
||||
use core::alloc::{Allocator, Layout};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::ptr::NonNull;
|
||||
|
||||
|
@ -43,6 +43,20 @@ static GLOBAL_ALLOC: BlockAllocator = unsafe {
|
|||
})
|
||||
};
|
||||
|
||||
macro_rules! impl_zst_allocator {
|
||||
($name_of_struct: ty, $name_of_static: ident) => {
|
||||
unsafe impl Allocator for $name_of_struct {
|
||||
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
|
||||
$name_of_static.allocate(layout)
|
||||
}
|
||||
|
||||
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
|
||||
$name_of_static.deallocate(ptr, layout)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// This is the allocator for the External Working Ram. This is currently
|
||||
/// equivalent to the Global Allocator (where things are allocated if no allocator is provided). This implements the allocator trait, so
|
||||
/// is meant to be used in specifying where certain structures should be
|
||||
|
@ -64,7 +78,9 @@ static GLOBAL_ALLOC: BlockAllocator = unsafe {
|
|||
/// );
|
||||
/// # }
|
||||
/// ```
|
||||
pub static EWRAM_ALLOC: &BlockAllocator = &GLOBAL_ALLOC;
|
||||
pub struct ExternalAllocator;
|
||||
|
||||
impl_zst_allocator!(ExternalAllocator, GLOBAL_ALLOC);
|
||||
|
||||
/// This is the allocator for the Internal Working Ram. This implements the
|
||||
/// allocator trait, so is meant to be used in specifying where certain
|
||||
|
@ -86,7 +102,10 @@ pub static EWRAM_ALLOC: &BlockAllocator = &GLOBAL_ALLOC;
|
|||
/// );
|
||||
/// # }
|
||||
/// ```
|
||||
pub static IWRAM_ALLOC: &BlockAllocator = &__IWRAM_ALLOC;
|
||||
pub struct InternalAllocator;
|
||||
|
||||
impl_zst_allocator!(InternalAllocator, __IWRAM_ALLOC);
|
||||
|
||||
static __IWRAM_ALLOC: BlockAllocator = unsafe {
|
||||
BlockAllocator::new(StartEnd {
|
||||
start: iwram_data_end,
|
||||
|
@ -227,7 +246,7 @@ mod test {
|
|||
|
||||
#[test_case]
|
||||
fn allocate_to_iwram_works(_gba: &mut crate::Gba) {
|
||||
let a = Box::new_in(1, IWRAM_ALLOC);
|
||||
let a = Box::new_in(1, InternalAllocator);
|
||||
let p = &*a as *const i32;
|
||||
let addr = p as usize;
|
||||
assert!(
|
||||
|
|
|
@ -190,7 +190,7 @@ pub mod syscall;
|
|||
/// Interactions with the internal timers
|
||||
pub mod timer;
|
||||
|
||||
pub use {agb_alloc::EWRAM_ALLOC, agb_alloc::IWRAM_ALLOC};
|
||||
pub use {agb_alloc::ExternalAllocator, agb_alloc::InternalAllocator};
|
||||
|
||||
#[cfg(not(any(test, feature = "testing")))]
|
||||
#[panic_handler]
|
||||
|
@ -206,8 +206,6 @@ fn panic_implementation(info: &core::panic::PanicInfo) -> ! {
|
|||
loop {}
|
||||
}
|
||||
|
||||
static mut GBASINGLE: single::Singleton<Gba> = single::Singleton::new(unsafe { Gba::single_new() });
|
||||
|
||||
/// The Gba struct is used to control access to the Game Boy Advance's hardware in a way which makes it the
|
||||
/// borrow checker's responsibility to ensure no clashes of global resources.
|
||||
///
|
||||
|
@ -245,7 +243,7 @@ impl Gba {
|
|||
#[doc(hidden)]
|
||||
#[must_use]
|
||||
pub unsafe fn new_in_entry() -> Self {
|
||||
GBASINGLE.take()
|
||||
Self::single_new()
|
||||
}
|
||||
|
||||
const unsafe fn single_new() -> Self {
|
||||
|
|
Loading…
Reference in a new issue