mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +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]
|
#[agb::entry]
|
||||||
fn main(_gba: agb::Gba) -> ! {
|
fn main(_gba: agb::Gba) -> ! {
|
||||||
loop {
|
loop {
|
||||||
let a = Box::new_in(1, agb::EWRAM_ALLOC);
|
let a = Box::new_in(1, agb::ExternalAllocator);
|
||||||
let b = Box::new(1);
|
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!("ewram allocation made to {:?}", &*a as *const _);
|
||||||
agb::println!("global allocation made to {:?}", &*b as *const _);
|
agb::println!("global allocation made to {:?}", &*b as *const _);
|
||||||
agb::println!("iwram allocation made to {:?}", &*c 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::ops::{Deref, DerefMut};
|
||||||
use core::ptr::NonNull;
|
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
|
/// 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
|
/// 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
|
/// 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
|
/// This is the allocator for the Internal Working Ram. This implements the
|
||||||
/// allocator trait, so is meant to be used in specifying where certain
|
/// 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 {
|
static __IWRAM_ALLOC: BlockAllocator = unsafe {
|
||||||
BlockAllocator::new(StartEnd {
|
BlockAllocator::new(StartEnd {
|
||||||
start: iwram_data_end,
|
start: iwram_data_end,
|
||||||
|
@ -227,7 +246,7 @@ mod test {
|
||||||
|
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn allocate_to_iwram_works(_gba: &mut crate::Gba) {
|
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 p = &*a as *const i32;
|
||||||
let addr = p as usize;
|
let addr = p as usize;
|
||||||
assert!(
|
assert!(
|
||||||
|
|
|
@ -190,7 +190,7 @@ pub mod syscall;
|
||||||
/// Interactions with the internal timers
|
/// Interactions with the internal timers
|
||||||
pub mod timer;
|
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")))]
|
#[cfg(not(any(test, feature = "testing")))]
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
|
@ -206,8 +206,6 @@ fn panic_implementation(info: &core::panic::PanicInfo) -> ! {
|
||||||
loop {}
|
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
|
/// 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.
|
/// borrow checker's responsibility to ensure no clashes of global resources.
|
||||||
///
|
///
|
||||||
|
@ -245,7 +243,7 @@ impl Gba {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn new_in_entry() -> Self {
|
pub unsafe fn new_in_entry() -> Self {
|
||||||
GBASINGLE.take()
|
Self::single_new()
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsafe fn single_new() -> Self {
|
const unsafe fn single_new() -> Self {
|
||||||
|
|
Loading…
Reference in a new issue