#![no_std]
extern crate alloc;
use core::alloc::{GlobalAlloc, Layout};
use core::cell::UnsafeCell;
use core::ptr::null_mut;
use core::sync::atomic::{AtomicUsize, Ordering::SeqCst};
const ARENA_SIZE: usize = 8192 * 8192;
const MAX_SUPPORTED_ALIGN: usize = 4096;
#[repr(C, align(4096))] struct FAlloc {
arena: UnsafeCell<[u8; ARENA_SIZE]>,
remaining: AtomicUsize, }
#[global_allocator]
static ALLOCATOR: FAlloc = FAlloc {
arena: UnsafeCell::new([0x55; ARENA_SIZE]),
remaining: AtomicUsize::new(ARENA_SIZE),
};
unsafe impl Sync for FAlloc {}
unsafe impl GlobalAlloc for FAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let align = layout.align();
let align_mask_to_round_down = !(align - 1);
if align > MAX_SUPPORTED_ALIGN {
return null_mut();
}
let mut allocated = 0;
if self
.remaining
.fetch_update(SeqCst, SeqCst, |mut remaining| {
if size > remaining {
return None;
}
remaining -= size;
remaining &= align_mask_to_round_down;
allocated = remaining;
Some(remaining)
})
.is_err()
{
return null_mut();
};
self.arena.get().cast::<u8>().add(allocated)
}
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
#[test]
fn it_works() {
let _ = unsafe { ALLOCATOR.alloc(Layout::from_size_align(1024, 4).unwrap()) };
assert!(true);
}
#[test]
fn vec_test() {
let _ = vec![1, 2, 3];
assert!(true);
}
#[test]
fn vec_test_2() {
let mut v = vec![1, 2, 3];
for _ in 0..10000 {
v.push(1)
}
}
}