summaryrefslogtreecommitdiffstats
path: root/vendor/dlmalloc/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/dlmalloc/src')
-rw-r--r--vendor/dlmalloc/src/lib.rs11
-rw-r--r--vendor/dlmalloc/src/xous.rs117
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
+}