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}