memory/manager.rs
1use core::{alloc::GlobalAlloc, ptr::NonNull};
2
3use crate::{Capabilities, Layout, ManagerTrait};
4
5unsafe extern "Rust" {
6 unsafe static __XILA_MEMORY_ALLOCATOR: &'static dyn ManagerTrait;
7}
8
9/// A wrapper type that adapts any type implementing `Allocator_trait` to the standard
10/// Rust `GlobalAlloc` trait.
11///
12/// This enables custom allocators that implement the Xila-specific `Allocator_trait`
13/// to be used as the global memory allocator for Rust's allocation system.
14pub struct Manager(&'static dyn ManagerTrait);
15
16impl Manager {
17 /// Creates a new instance of `Allocator_type` wrapping the provided allocator.
18 ///
19 /// # Parameters
20 /// * `Allocator` - The allocator to wrap
21 ///
22 /// # Returns
23 /// A new instance of `Allocator_type` containing the provided allocator.
24 pub const fn new(allocator: &'static dyn ManagerTrait) -> Self {
25 Self(allocator)
26 }
27}
28
29/// Implementation of the standard library's `GlobalAlloc` trait for any wrapped
30/// type that implements `Allocator_trait`.
31///
32/// This implementation delegates the standard allocation operations to the wrapped
33/// allocator's methods, converting between Rust's and Xila's allocation types.
34///
35/// # Safety
36/// The implementation upholds the safety guarantees required by `GlobalAlloc`:
37/// - Memory is properly aligned according to the layout
38/// - Deallocation uses the same layout that was used for allocation
39unsafe impl GlobalAlloc for Manager {
40 unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
41 unsafe {
42 self.0
43 .allocate(Capabilities::default(), Layout::from(layout))
44 .map_or(core::ptr::null_mut(), |pointer| pointer.as_ptr())
45 }
46 }
47
48 unsafe fn dealloc(&self, pointer: *mut u8, layout: core::alloc::Layout) {
49 if !pointer.is_null() {
50 unsafe {
51 self.0
52 .deallocate(NonNull::new_unchecked(pointer), Layout::from(layout))
53 }
54 }
55 }
56}
57
58pub fn get_instance() -> &'static dyn ManagerTrait {
59 unsafe { __XILA_MEMORY_ALLOCATOR }
60}