diff options
| author | zhang san <[email protected]> | 2025-12-08 18:34:25 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-08 18:34:25 +0800 |
| commit | 69980f8b9d29b38dbd4ddf6373b4b45f3a138409 (patch) | |
| tree | 21dd9a8ce80e3d30192e9ffa56ea39a199bae309 /components/rust/core/src/allocator.rs | |
| parent | cd1d47b87c5d47e131730e5506eb3ad77d357653 (diff) | |
Adding Rust Language Support for RT-Thread #10910
Diffstat (limited to 'components/rust/core/src/allocator.rs')
| -rw-r--r-- | components/rust/core/src/allocator.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/components/rust/core/src/allocator.rs b/components/rust/core/src/allocator.rs new file mode 100644 index 0000000000..731a072710 --- /dev/null +++ b/components/rust/core/src/allocator.rs @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2006-2025, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2025-10-10 foxglove RT-Thread GlobalAlloc implementation + */ + +use crate::api::mem::{mem_alloc, mem_alloc_aligned, mem_free, mem_free_aligned, mem_realloc}; +use core::alloc::{GlobalAlloc, Layout}; +use crate::panic::panic_on_atomic_context; +use core::ptr; +use core::ffi::c_void; + +pub struct RttAlloc; +unsafe impl GlobalAlloc for RttAlloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + panic_on_atomic_context("alloc"); + let size = layout.size(); + let align = layout.align(); + + /* Handle zero-sized allocations */ + if size == 0 { + return ptr::null_mut(); + } + + /* Use aligned allocation if alignment is greater than default + * RT-Thread's default alignment is typically 4 or 8 bytes */ + if align > 8 { + match mem_alloc_aligned(size, align) { + Some(ptr) => ptr as *mut u8, + None => ptr::null_mut(), + } + } else { + match mem_alloc(size) { + Some(ptr) => ptr as *mut u8, + None => ptr::null_mut(), + } + } + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + panic_on_atomic_context("dealloc"); + if ptr.is_null() { + return; + } + + let align = layout.align(); + + /* Use aligned deallocation if the original allocation was aligned */ + if align > 8 { + mem_free_aligned(ptr as *mut c_void); + } else { + mem_free(ptr as *mut c_void); + } + } + + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + panic_on_atomic_context("realloc"); + /* Handle zero-sized new allocation */ + if new_size == 0 { + self.dealloc(ptr, layout); + return ptr::null_mut(); + } + + /* Handle null pointer (equivalent to alloc) */ + if ptr.is_null() { + let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); + return self.alloc(new_layout); + } + + /* For aligned allocations, we need to handle realloc manually + * since RT-Thread's rt_realloc may not preserve alignment */ + let align = layout.align(); + if align > 8 { + let new_ptr = match mem_alloc_aligned(new_size, align) { + Some(ptr) => ptr as *mut u8, + None => return ptr::null_mut(), + }; + + /* Copy data from old to new */ + let copy_size = core::cmp::min(layout.size(), new_size); + ptr::copy_nonoverlapping(ptr, new_ptr, copy_size); + + mem_free_aligned(ptr as *mut c_void); + + new_ptr + } else { + match mem_realloc(ptr as *mut c_void, new_size) { + Some(new_ptr) => new_ptr as *mut u8, + None => ptr::null_mut(), + } + } + } +}
\ No newline at end of file |
