Skip to main content

leodos_libcfs/os/
alloc.rs

1//! A `GlobalAlloc` implementation backed by the POSIX heap
2//! (`malloc`/`free`/`posix_memalign`).
3//!
4//! cFS apps that want to use the `alloc` crate (`Box`, `Vec`,
5//! `String`, ...) declare this as their global allocator:
6//!
7//! ```ignore
8//! use leodos_libcfs::os::alloc::CfsAllocator;
9//!
10//! #[global_allocator]
11//! static ALLOCATOR: CfsAllocator = CfsAllocator;
12//! ```
13//!
14//! Alternatively, apps can call [`crate::register_allocator!`]
15//! at crate root to install the allocator with one line.
16//!
17//! Under NOS3 / posix-OSAL, `core-cpu1` is a normal Linux
18//! process, so this just delegates to the C library's
19//! thread-safe heap.
20
21use core::alloc::GlobalAlloc;
22use core::alloc::Layout;
23
24/// A `GlobalAlloc` backed by libc's thread-safe heap.
25pub struct CfsAllocator;
26
27unsafe impl GlobalAlloc for CfsAllocator {
28    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
29        let mut out: *mut libc::c_void = core::ptr::null_mut();
30        let align = layout.align().max(core::mem::size_of::<usize>());
31        let size = layout.size();
32        let status = unsafe { libc::posix_memalign(&mut out, align, size) };
33        if status == 0 {
34            out as *mut u8
35        } else {
36            core::ptr::null_mut()
37        }
38    }
39
40    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
41        unsafe { libc::free(ptr as *mut libc::c_void) };
42    }
43}
44
45/// Declares [`CfsAllocator`] as the crate's `#[global_allocator]`.
46///
47/// cFS apps place this at the crate root:
48///
49/// ```ignore
50/// leodos_libcfs::register_allocator!();
51/// ```
52#[macro_export]
53macro_rules! register_allocator {
54    () => {
55        #[global_allocator]
56        static __LEODOS_GLOBAL_ALLOCATOR: $crate::os::alloc::CfsAllocator =
57            $crate::os::alloc::CfsAllocator;
58    };
59}