2025-11-10 16:01:34 +01:00
|
|
|
mod arena;
|
|
|
|
|
mod global;
|
|
|
|
|
|
|
|
|
|
pub use arena::*;
|
|
|
|
|
pub use global::*;
|
|
|
|
|
use std::{alloc::Layout, mem::MaybeUninit};
|
|
|
|
|
|
|
|
|
|
pub type DropFn = Option<unsafe fn(*mut u8)>;
|
|
|
|
|
|
|
|
|
|
pub struct AllocationEntry {
|
2026-02-26 19:40:27 +01:00
|
|
|
ptr: *mut u8,
|
|
|
|
|
layout: Layout,
|
|
|
|
|
drop_fn: DropFn,
|
2025-11-10 16:01:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe impl Send for AllocationEntry {}
|
|
|
|
|
unsafe impl Sync for AllocationEntry {}
|
|
|
|
|
|
|
|
|
|
pub trait Allocator {
|
2026-02-26 19:40:27 +01:00
|
|
|
unsafe fn alloc_unsafe(&self, data: *const u8, layout: Layout, drop: DropFn) -> *mut u8;
|
2025-11-10 16:01:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub trait SyncAllocator: Allocator + Send + Sync {}
|
|
|
|
|
|
|
|
|
|
impl<T: Allocator + Send + Sync> SyncAllocator for T {}
|
|
|
|
|
|
|
|
|
|
impl<'l> dyn Allocator + 'l {
|
2026-02-26 19:40:27 +01:00
|
|
|
pub fn alloc<T>(&'l self, value: T) -> &'l mut T {
|
|
|
|
|
unsafe {
|
|
|
|
|
let value = MaybeUninit::new(value);
|
|
|
|
|
let data = value.as_ptr() as *const u8;
|
|
|
|
|
let layout = Layout::new::<T>();
|
|
|
|
|
let drop: DropFn = match std::mem::needs_drop::<T>() {
|
|
|
|
|
false => None,
|
|
|
|
|
true => Some(|ptr: *mut u8| std::ptr::drop_in_place(ptr as *mut T)),
|
|
|
|
|
};
|
|
|
|
|
&mut *(self.alloc_unsafe(data, layout, drop) as *mut T)
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-10 16:01:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'l> dyn SyncAllocator + 'l {
|
2026-02-26 19:40:27 +01:00
|
|
|
pub fn alloc<T: Send>(&'l self, value: T) -> &'l mut T {
|
|
|
|
|
<dyn Allocator>::alloc(self, value)
|
|
|
|
|
}
|
2025-11-10 16:01:34 +01:00
|
|
|
}
|