Update third_party/lang-items to support OpenSK.
This commit is contained in:
94
third_party/lang-items/src/allocator.rs
vendored
94
third_party/lang-items/src/allocator.rs
vendored
@@ -1,7 +1,16 @@
|
||||
use crate::util;
|
||||
use core::alloc::GlobalAlloc;
|
||||
use core::alloc::Layout;
|
||||
#[cfg(any(feature = "debug_allocations", feature = "panic_console"))]
|
||||
use core::fmt::Write;
|
||||
use core::ptr;
|
||||
use core::ptr::NonNull;
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
use core::sync::atomic;
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
use core::sync::atomic::AtomicUsize;
|
||||
#[cfg(any(feature = "debug_allocations", feature = "panic_console"))]
|
||||
use libtock_drivers::console::Console;
|
||||
use linked_list_allocator::Heap;
|
||||
|
||||
static mut HEAP: Heap = Heap::empty();
|
||||
@@ -11,35 +20,90 @@ unsafe fn libtock_alloc_init(app_heap_start: usize, app_heap_size: usize) {
|
||||
HEAP.init(app_heap_start, app_heap_size);
|
||||
}
|
||||
|
||||
struct TockAllocator;
|
||||
// With the "debug_allocations" feature, we use `AtomicUsize` to store the
|
||||
// statistics because:
|
||||
// - it is `Sync`, so we can use it in a static object (the allocator),
|
||||
// - it implements interior mutability, so we can use it in the allocator
|
||||
// methods (that take an immutable `&self` reference).
|
||||
struct TockAllocator {
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
count: AtomicUsize,
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
size: AtomicUsize,
|
||||
}
|
||||
|
||||
impl TockAllocator {
|
||||
const fn new() -> TockAllocator {
|
||||
TockAllocator {
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
count: AtomicUsize::new(0),
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
size: AtomicUsize::new(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl GlobalAlloc for TockAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
HEAP.allocate_first_fit(layout)
|
||||
let ptr = HEAP
|
||||
.allocate_first_fit(layout)
|
||||
.ok()
|
||||
.map_or(ptr::null_mut(), NonNull::as_ptr)
|
||||
.map_or(ptr::null_mut(), NonNull::as_ptr);
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
{
|
||||
self.count.fetch_add(1, atomic::Ordering::SeqCst);
|
||||
self.size.fetch_add(layout.size(), atomic::Ordering::SeqCst);
|
||||
writeln!(
|
||||
Console::new(),
|
||||
"alloc[{}, {}] = {:?} ({} ptrs, {} bytes)",
|
||||
layout.size(),
|
||||
layout.align(),
|
||||
ptr,
|
||||
self.count.load(atomic::Ordering::SeqCst),
|
||||
self.size.load(atomic::Ordering::SeqCst)
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
ptr
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
#[cfg(feature = "debug_allocations")]
|
||||
{
|
||||
self.count.fetch_sub(1, atomic::Ordering::SeqCst);
|
||||
self.size.fetch_sub(layout.size(), atomic::Ordering::SeqCst);
|
||||
writeln!(
|
||||
Console::new(),
|
||||
"dealloc[{}, {}] = {:?} ({} ptrs, {} bytes)",
|
||||
layout.size(),
|
||||
layout.align(),
|
||||
ptr,
|
||||
self.count.load(atomic::Ordering::SeqCst),
|
||||
self.size.load(atomic::Ordering::SeqCst)
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
HEAP.deallocate(NonNull::new_unchecked(ptr), layout)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "arm", target_arch = "riscv32"))]
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: TockAllocator = TockAllocator;
|
||||
static ALLOCATOR: TockAllocator = TockAllocator::new();
|
||||
|
||||
#[cfg(not(feature = "custom_alloc_error_handler"))]
|
||||
#[alloc_error_handler]
|
||||
unsafe fn alloc_error_handler(_: Layout) -> ! {
|
||||
use crate::syscalls;
|
||||
unsafe fn alloc_error_handler(_layout: Layout) -> ! {
|
||||
util::signal_oom();
|
||||
util::signal_panic();
|
||||
|
||||
// Print 0x01 using the LowLevelDebug capsule (if available).
|
||||
let _ = syscalls::command1_insecure(8, 2, 0x01);
|
||||
|
||||
// Signal a panic using the LowLevelDebug capsule (if available).
|
||||
let _ = syscalls::command1_insecure(8, 1, 0x01);
|
||||
|
||||
loop {
|
||||
syscalls::raw::yieldk();
|
||||
#[cfg(feature = "panic_console")]
|
||||
{
|
||||
writeln!(Console::new(), "Couldn't allocate: {:?}", _layout).ok();
|
||||
// Force the kernel to report the panic cause, by reading an invalid address.
|
||||
// The memory protection unit should be setup by the Tock kernel to prevent apps from accessing
|
||||
// address zero.
|
||||
core::ptr::read_volatile(0 as *const usize);
|
||||
}
|
||||
|
||||
util::cycle_leds()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user