@@ -17,6 +17,7 @@ use core::alloc::GlobalAlloc;
1717use core:: alloc:: Layout ;
1818#[ cfg( feature = "alloc_ref" ) ]
1919use core:: alloc:: { AllocError , Allocator } ;
20+ use core:: mem:: MaybeUninit ;
2021#[ cfg( feature = "use_spin" ) ]
2122use core:: ops:: Deref ;
2223use core:: ptr:: NonNull ;
@@ -73,6 +74,32 @@ impl Heap {
7374 self . holes = HoleList :: new ( heap_bottom, heap_size) ;
7475 }
7576
77+ /// Initialize an empty heap with provided memory.
78+ ///
79+ /// The caller is responsible for procuring a region of raw memory that may be utilized by the
80+ /// allocator. This might be done via any method such as (unsafely) taking a region from the
81+ /// program's memory, from a mutable static, or by allocating and leaking such memory from
82+ /// another allocator.
83+ ///
84+ /// The latter method may be especially useful if the underlying allocator does not perform
85+ /// deallocation (e.g. a simple bump allocator). Then the overlaid linked-list-allocator can
86+ /// provide memory reclamation.
87+ ///
88+ /// # Panics
89+ ///
90+ /// This method panics if the heap is already initialized.
91+ pub fn init_from_slice ( & mut self , mem : & ' static mut [ MaybeUninit < u8 > ] ) {
92+ assert ! ( self . bottom == 0 , "The heap has already been initialized." ) ;
93+ let size = mem. len ( ) ;
94+ let address = mem. as_ptr ( ) as usize ;
95+ // SAFETY: All initialization requires the bottom address to be valid, which implies it
96+ // must not be 0. Initially the address is 0. The assertion above ensures that no
97+ // initialization had been called before.
98+ // The given address and size is valid according to the safety invariants of the mutable
99+ // reference handed to us by the caller.
100+ unsafe { self . init ( address, size) }
101+ }
102+
76103 /// Creates a new heap with the given `bottom` and `size`. The bottom address must be valid
77104 /// and the memory in the `[heap_bottom, heap_bottom + heap_size)` range must not be used for
78105 /// anything else. This function is unsafe because it can cause undefined behavior if the
@@ -90,6 +117,18 @@ impl Heap {
90117 }
91118 }
92119
120+ /// Creates a new heap from a slice of raw memory.
121+ ///
122+ /// This has the same effect as [`init_from_slice`] on an empty heap, but it is combined into a
123+ /// single operation that can not panic.
124+ pub fn from_slice ( mem : & ' static mut [ MaybeUninit < u8 > ] ) -> Heap {
125+ let size = mem. len ( ) ;
126+ let address = mem. as_ptr ( ) as usize ;
127+ // SAFETY: The given address and size is valid according to the safety invariants of the
128+ // mutable reference handed to us by the caller.
129+ unsafe { Self :: new ( address, size) }
130+ }
131+
93132 /// Allocates a chunk of the given size with the given alignment. Returns a pointer to the
94133 /// beginning of that chunk if it was successful. Else it returns `None`.
95134 /// This function scans the list of free memory blocks and uses the first block that is big
0 commit comments