Skip to content

Commit 5f16d47

Browse files
committed
vexos: implement global dlmalloc fallback
1 parent 5fdfc65 commit 5f16d47

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

library/std/src/sys/alloc/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ cfg_select! {
9292
target_os = "uefi" => {
9393
mod uefi;
9494
}
95+
target_os = "vexos" => {
96+
mod vexos;
97+
}
9598
target_family = "wasm" => {
9699
mod wasm;
97100
}

library/std/src/sys/alloc/vexos.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
2+
#![allow(static_mut_refs)]
3+
4+
use crate::alloc::{GlobalAlloc, Layout, System};
5+
6+
static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new();
7+
8+
#[stable(feature = "alloc_system_type", since = "1.28.0")]
9+
unsafe impl GlobalAlloc for System {
10+
#[inline]
11+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
12+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
13+
// Calling malloc() is safe because preconditions on this function match the trait method preconditions.
14+
let _lock = lock::lock();
15+
unsafe { DLMALLOC.malloc(layout.size(), layout.align()) }
16+
}
17+
18+
#[inline]
19+
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
20+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
21+
// Calling calloc() is safe because preconditions on this function match the trait method preconditions.
22+
let _lock = lock::lock();
23+
unsafe { DLMALLOC.calloc(layout.size(), layout.align()) }
24+
}
25+
26+
#[inline]
27+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
28+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
29+
// Calling free() is safe because preconditions on this function match the trait method preconditions.
30+
let _lock = lock::lock();
31+
unsafe { DLMALLOC.free(ptr, layout.size(), layout.align()) }
32+
}
33+
34+
#[inline]
35+
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
36+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
37+
// Calling realloc() is safe because preconditions on this function match the trait method preconditions.
38+
let _lock = lock::lock();
39+
unsafe { DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) }
40+
}
41+
}
42+
43+
mod lock {
44+
use crate::sync::atomic::Ordering::{Acquire, Release};
45+
use crate::sync::atomic::{Atomic, AtomicI32};
46+
47+
static LOCKED: Atomic<i32> = AtomicI32::new(0);
48+
49+
pub struct DropLock;
50+
51+
pub fn lock() -> DropLock {
52+
loop {
53+
if LOCKED.swap(1, Acquire) == 0 {
54+
return DropLock;
55+
}
56+
crate::os::xous::ffi::do_yield();
57+
}
58+
}
59+
60+
impl Drop for DropLock {
61+
fn drop(&mut self) {
62+
let r = LOCKED.swap(0, Release);
63+
debug_assert_eq!(r, 1);
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)