diff options
Diffstat (limited to 'vendor/dlmalloc/src')
-rw-r--r-- | vendor/dlmalloc/src/lib.rs | 11 | ||||
-rw-r--r-- | vendor/dlmalloc/src/xous.rs | 117 |
2 files changed, 127 insertions, 1 deletions
diff --git a/vendor/dlmalloc/src/lib.rs b/vendor/dlmalloc/src/lib.rs index 238386fbc..b972ccb73 100644 --- a/vendor/dlmalloc/src/lib.rs +++ b/vendor/dlmalloc/src/lib.rs @@ -81,7 +81,16 @@ mod sys; #[path = "unix.rs"] mod sys; -#[cfg(not(any(target_os = "linux", target_os = "macos", target_family = "wasm")))] +#[cfg(target_os = "xous")] +#[path = "xous.rs"] +mod sys; + +#[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "xous", + target_family = "wasm" +)))] #[path = "dummy.rs"] mod sys; diff --git a/vendor/dlmalloc/src/xous.rs b/vendor/dlmalloc/src/xous.rs new file mode 100644 index 000000000..96cb4e0d3 --- /dev/null +++ b/vendor/dlmalloc/src/xous.rs @@ -0,0 +1,117 @@ +use core::ptr; +use Allocator; + +pub struct System { + _priv: (), +} + +impl System { + pub const fn new() -> System { + System { _priv: () } + } +} + +#[cfg(target_arch = "riscv32")] +mod sys { + use core::arch::asm; + + pub fn increase_heap(length: usize) -> Result<(usize, usize), ()> { + let syscall_no_increase_heap = 10usize; + let memory_flags_read_write = 2usize | 4usize; + + let mut a0 = syscall_no_increase_heap; + let mut a1 = length; + let mut a2 = memory_flags_read_write; + + unsafe { + asm!( + "ecall", + inlateout("a0") a0, + inlateout("a1") a1, + inlateout("a2") a2, + out("a3") _, + out("a4") _, + out("a5") _, + out("a6") _, + out("a7") _, + ) + }; + + let result = a0; + let address = a1; + let length = a2; + + // 3 is the "MemoryRange" type, and the result is only valid + // if we get nonzero address and length. + if result == 3 && address != 0 && length != 0 { + Ok((address, length)) + } else { + Err(()) + } + } +} + +unsafe impl Allocator for System { + /// Allocate an additional `size` bytes on the heap, and return a new + /// chunk of memory, as well as the size of the allocation and some + /// flags. Since flags are unused on this platform, they will always + /// be `0`. + fn alloc(&self, size: usize) -> (*mut u8, usize, u32) { + let size = if size == 0 { + 4096 + } else if size & 4095 == 0 { + size + } else { + size + (4096 - (size & 4095)) + }; + + if let Ok((address, length)) = sys::increase_heap(size) { + let start = address - size + length; + (start as *mut u8, size, 0) + } else { + (ptr::null_mut(), 0, 0) + } + } + + fn remap(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize, _can_move: bool) -> *mut u8 { + // TODO + ptr::null_mut() + } + + fn free_part(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize) -> bool { + false + } + + fn free(&self, _ptr: *mut u8, _size: usize) -> bool { + false + } + + fn can_release_part(&self, _flags: u32) -> bool { + false + } + + fn allocates_zeros(&self) -> bool { + true + } + + fn page_size(&self) -> usize { + 4 * 1024 + } +} + +#[cfg(feature = "global")] +pub fn acquire_global_lock() { + // global feature should not be enabled + unimplemented!() +} + +#[cfg(feature = "global")] +pub fn release_global_lock() { + // global feature should not be enabled + unimplemented!() +} + +#[cfg(feature = "global")] +pub unsafe fn enable_alloc_after_fork() { + // platform does not support `fork()` call +} |