mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 16:51:33 +11:00
Start a basic allocator with a super simple test
This commit is contained in:
parent
1c07268f11
commit
7062610aba
76
agb/src/agb_alloc/mod.rs
Normal file
76
agb/src/agb_alloc/mod.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use core::alloc::{GlobalAlloc, Layout};
|
||||||
|
|
||||||
|
use super::interrupt::Mutex;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static __ewram_data_end: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_data_end() -> usize {
|
||||||
|
// TODO: This seems completely wrong, but without the &, rust generates
|
||||||
|
// a double dereference :/. Maybe a bug in nightly?
|
||||||
|
(unsafe { &__ewram_data_end }) as *const _ as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BumpAllocator {
|
||||||
|
current_ptr: Mutex<*mut u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BumpAllocator {
|
||||||
|
fn alloc_safe(&self, layout: Layout) -> *mut u8 {
|
||||||
|
let mut current_ptr = self.current_ptr.lock();
|
||||||
|
|
||||||
|
let mut ptr = *current_ptr as usize;
|
||||||
|
|
||||||
|
if ptr == 0 {
|
||||||
|
ptr = get_data_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
let alignment_bitmask = layout.align() - 1;
|
||||||
|
let fixup = ptr & alignment_bitmask;
|
||||||
|
|
||||||
|
let amount_to_add = layout.align() - fixup;
|
||||||
|
|
||||||
|
let resulting_ptr = ptr + amount_to_add;
|
||||||
|
*current_ptr = (resulting_ptr + layout.size()) as *mut _;
|
||||||
|
|
||||||
|
resulting_ptr as *mut _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl GlobalAlloc for BumpAllocator {
|
||||||
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||||
|
self.alloc_safe(layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[alloc_error_handler]
|
||||||
|
fn alloc_error(layout: Layout) -> ! {
|
||||||
|
panic!(
|
||||||
|
"Failed to allocate size {} with alignment {}",
|
||||||
|
layout.size(),
|
||||||
|
layout.align()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL_ALLOC: BumpAllocator = BumpAllocator {
|
||||||
|
current_ptr: Mutex::new(core::ptr::null_mut()),
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_box(_gba: &mut crate::Gba) {
|
||||||
|
let first_box = Box::new(1);
|
||||||
|
let second_box = Box::new(2);
|
||||||
|
|
||||||
|
assert!(&*first_box as *const _ < &*second_box as *const _);
|
||||||
|
assert_eq!(*first_box, 1);
|
||||||
|
assert_eq!(*second_box, 2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,15 +4,17 @@
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
#![feature(custom_test_frameworks)]
|
#![feature(custom_test_frameworks)]
|
||||||
|
#![feature(alloc_error_handler)]
|
||||||
#![test_runner(crate::test_runner)]
|
#![test_runner(crate::test_runner)]
|
||||||
#![reexport_test_harness_main = "test_main"]
|
#![reexport_test_harness_main = "test_main"]
|
||||||
|
|
||||||
//! # agb
|
//! # agb
|
||||||
//! `agb` is a library for making games on the Game Boy Advance using the Rust
|
//! `agb` is a library for making games on the Game Boy Advance using the Rust
|
||||||
//! programming language. It attempts to be a high level abstraction over the
|
//! programming language. It attempts to be a high level abstraction over the
|
||||||
//! internal workings of the Game Boy Advance whilst still being high
|
//! internal workings of the Game Boy Advance whilst still being high
|
||||||
//! performance and memory efficient.
|
//! performance and memory efficient.
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
/// Implements everything relating to things that are displayed on screen.
|
/// Implements everything relating to things that are displayed on screen.
|
||||||
pub mod display;
|
pub mod display;
|
||||||
/// Button inputs to the system.
|
/// Button inputs to the system.
|
||||||
|
@ -32,6 +34,8 @@ pub mod mgba;
|
||||||
pub mod number;
|
pub mod number;
|
||||||
mod single;
|
mod single;
|
||||||
|
|
||||||
|
mod agb_alloc;
|
||||||
|
|
||||||
/// System BIOS calls / syscalls.
|
/// System BIOS calls / syscalls.
|
||||||
pub mod syscall;
|
pub mod syscall;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue