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