mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 08:41:34 +11:00
allocator that can have a custom start point
This commit is contained in:
parent
5761093f19
commit
3c6c7efc79
|
@ -49,9 +49,9 @@ pub(crate) struct BlockAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockAllocator {
|
impl BlockAllocator {
|
||||||
pub(super) const unsafe fn new() -> Self {
|
pub(super) const unsafe fn new(start: fn() -> usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner_allocator: BumpAllocator::new(),
|
inner_allocator: BumpAllocator::new(start),
|
||||||
state: Mutex::new(RefCell::new(BlockAllocatorState {
|
state: Mutex::new(RefCell::new(BlockAllocatorState {
|
||||||
first_free_block: None,
|
first_free_block: None,
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -8,12 +8,14 @@ use bare_metal::{CriticalSection, Mutex};
|
||||||
|
|
||||||
pub(crate) struct BumpAllocator {
|
pub(crate) struct BumpAllocator {
|
||||||
current_ptr: Mutex<RefCell<Option<SendNonNull<u8>>>>,
|
current_ptr: Mutex<RefCell<Option<SendNonNull<u8>>>>,
|
||||||
|
start: Mutex<fn() -> usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BumpAllocator {
|
impl BumpAllocator {
|
||||||
pub const fn new() -> Self {
|
pub const fn new(start: fn() -> usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_ptr: Mutex::new(RefCell::new(None)),
|
current_ptr: Mutex::new(RefCell::new(None)),
|
||||||
|
start: Mutex::new(start),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +27,7 @@ impl BumpAllocator {
|
||||||
let ptr = if let Some(c) = *current_ptr {
|
let ptr = if let Some(c) = *current_ptr {
|
||||||
c.as_ptr() as usize
|
c.as_ptr() as usize
|
||||||
} else {
|
} else {
|
||||||
get_data_end()
|
self.start.borrow(*cs)()
|
||||||
};
|
};
|
||||||
|
|
||||||
let alignment_bitmask = layout.align() - 1;
|
let alignment_bitmask = layout.align() - 1;
|
||||||
|
@ -56,33 +58,3 @@ unsafe impl GlobalAlloc for BumpAllocator {
|
||||||
|
|
||||||
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
|
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_data_end() -> usize {
|
|
||||||
extern "C" {
|
|
||||||
static __ewram_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
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn should_return_data_end_somewhere_in_ewram(_gba: &mut crate::Gba) {
|
|
||||||
let data_end = get_data_end();
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
0x0200_0000 <= data_end,
|
|
||||||
"data end should be bigger than 0x0200_0000, got {}",
|
|
||||||
data_end
|
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
0x0204_0000 > data_end,
|
|
||||||
"data end should be smaller than 0x0203_0000"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl<T> DerefMut for SendNonNull<T> {
|
||||||
const EWRAM_END: usize = 0x0204_0000;
|
const EWRAM_END: usize = 0x0204_0000;
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL_ALLOC: BlockAllocator = unsafe { BlockAllocator::new() };
|
static GLOBAL_ALLOC: BlockAllocator = unsafe { BlockAllocator::new(get_data_end) };
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub unsafe fn number_of_blocks() -> u32 {
|
pub unsafe fn number_of_blocks() -> u32 {
|
||||||
|
@ -49,6 +49,16 @@ fn alloc_error(layout: Layout) -> ! {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_data_end() -> usize {
|
||||||
|
extern "C" {
|
||||||
|
static __ewram_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
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
const EWRAM_START: usize = 0x0200_0000;
|
const EWRAM_START: usize = 0x0200_0000;
|
||||||
|
@ -118,4 +128,19 @@ mod test {
|
||||||
assert_eq!(v1[40], 137);
|
assert_eq!(v1[40], 137);
|
||||||
assert_eq!(v2[78], 1075);
|
assert_eq!(v2[78], 1075);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn should_return_data_end_somewhere_in_ewram(_gba: &mut crate::Gba) {
|
||||||
|
let data_end = get_data_end();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
0x0200_0000 <= data_end,
|
||||||
|
"data end should be bigger than 0x0200_0000, got {}",
|
||||||
|
data_end
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
0x0204_0000 > data_end,
|
||||||
|
"data end should be smaller than 0x0203_0000"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue