Skip to main content

rustubs/mm/
allocator.rs

1pub mod buddy;
2
3use crate::proc::sync::spin::SpinMutexIRQ;
4use core::{
5	alloc::{GlobalAlloc, Layout},
6	ops::Deref,
7	ptr::NonNull,
8};
9use linked_list_allocator::Heap;
10
11/// The synchronized kernel heap allocator:
12/// wrapper around linked_list_allocator::Heap
13/// A irqsave variant of linked_list_allocator::LockedHeap, which originally
14/// only uses a spin mutex. This is not safe when used it's used in both kernel
15/// and interrupt context (dead lock)
16pub struct IRQLockedHeap(SpinMutexIRQ<Heap>);
17
18impl IRQLockedHeap {
19	pub const fn empty() -> IRQLockedHeap {
20		IRQLockedHeap(SpinMutexIRQ::new(Heap::empty()))
21	}
22
23	pub unsafe fn new(heap_bottom: *mut u8, heap_size: usize) -> IRQLockedHeap {
24		IRQLockedHeap(SpinMutexIRQ::new(Heap::new(heap_bottom, heap_size)))
25	}
26}
27
28impl Deref for IRQLockedHeap {
29	type Target = SpinMutexIRQ<Heap>;
30
31	fn deref(&self) -> &SpinMutexIRQ<Heap> { &self.0 }
32}
33
34unsafe impl GlobalAlloc for IRQLockedHeap {
35	unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
36		self.0
37			.lock()
38			.allocate_first_fit(layout)
39			.ok()
40			.map_or(core::ptr::null_mut(), |allocation| allocation.as_ptr())
41	}
42
43	unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
44		self.0
45			.lock()
46			.deallocate(NonNull::new_unchecked(ptr), layout)
47	}
48}