@@ -17,6 +17,7 @@ use core::alloc::GlobalAlloc;
17
17
use core:: alloc:: Layout ;
18
18
#[ cfg( feature = "alloc_ref" ) ]
19
19
use core:: alloc:: { AllocError , Allocator } ;
20
+ use core:: mem:: MaybeUninit ;
20
21
#[ cfg( feature = "use_spin" ) ]
21
22
use core:: ops:: Deref ;
22
23
use core:: ptr:: NonNull ;
@@ -73,6 +74,32 @@ impl Heap {
73
74
self . holes = HoleList :: new ( heap_bottom, heap_size) ;
74
75
}
75
76
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
+
76
103
/// Creates a new heap with the given `bottom` and `size`. The bottom address must be valid
77
104
/// and the memory in the `[heap_bottom, heap_bottom + heap_size)` range must not be used for
78
105
/// anything else. This function is unsafe because it can cause undefined behavior if the
@@ -90,6 +117,18 @@ impl Heap {
90
117
}
91
118
}
92
119
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
+
93
132
/// Allocates a chunk of the given size with the given alignment. Returns a pointer to the
94
133
/// beginning of that chunk if it was successful. Else it returns `None`.
95
134
/// This function scans the list of free memory blocks and uses the first block that is big
0 commit comments