Closed nand-nor closed 5 years ago
Edit: fixing the imp_windows.rs alloc_pages()
function call that broke CI
Thanks, I'll take a look at this within the next couple days.
FYI: I've split out just the alignment of the scratch heap into #87
FYI: I've split out just the alignment of the scratch heap into #87
Should I close this PR then? Based on the above discussion / testing /and #87 the problem seems solved
Based on the above discussion / testing /and #87 the problem seems solved
Great! That was what I was hoping would happen, but I didn't want to close this out until you confirmed that :)
Should I close this PR then?
Yep, I think we can close this PR. If you run into any thing else, please file an issue!
Problem statement
The
wee_alloc
implementation of thestatic_array_backend
feature erroneously causes an out-of-memory error. The context where the problem arises is in compilation for a bare-metal embedded system (OS independent, target is something likearmv7-unknown-linux-gnueabihf
), using thestatic_array_backend
feature and assigningwee_alloc
as the global allocator.The root cause of the resulting error is the implementation of
imp_static_array::alloc_pages()
. The function creates a pointer to a slice of theSCRATCH_HEAP
of the requested size, which is used to create theFreeCell
objects that compose the free list. The function does not enforce that the slice pointer maintain any byte boundary alignment, resulting in unalignedFreeCell
objects. This ultimately creates an edge case error where allocation fails despite adequate memory left in theSCRATCH_HEAP
. The error occurs regardless of the configured static backend array size exported at compile time. Additionally, the failure arises regardless of size policy (e.g. whether or not thesize_classes
feature is enabled).Detailed description of the control flow in which the problem arises
The problem is immediately detectable by enabling the
extra_assertions
feature. With this feature enabled, the first call to allocate memory from the free list results in an alignment assertion failure, because as described above, theFreeCell
objects created from theSCRATCH_HEAP
object do not have the proper alignment. However, whenextra_assertions
feature is not enabled, the edge case in the example system occurs when the first 256 Kb of the free list are exhausted a.k.a. a full walk of the initial free list results inalloc_with_refill()
executing the code branch to create and insert a newFreeCell
.Upon an allocation request, the allocator attempts to allocate from the
SCRATCH_HEAP
. This is done via call to theGlobalAlloc
trait’s implementation ofalloc()
, which callsalloc_impl()
, which then callsalloc_with_refill()
within a function closure passed toself.with_free_list_and_policy_for_size
. Thealloc_with_refill
function first callsalloc_first_fit()
which walks the free list to find aFreeCell
of adequate size. After the 256 Kb exhaustion point,alloc_first_fit
fails to find aFreeCell
of adequate size. At this point, the branch for creating and inserting a newFreeCell
is executed via calls tonew_cell_for_free_list()
andinsert_into_free_list()
. Control flow then returns toalloc_with_refill
, which callsalloc_first_fit
again, which in turn callstry_alloc()
on the newly insertedFreeCell
object, which is the point of failure. The checks intry_alloc()
assert that the newly insertedFreeCell
is large enough to hold the requested allocation size, but that it is not big enough to be split in two. This leads to the final check intry_alloc()
, which determines if theFreeCell
is appropriately aligned, which, because of howalloc_pages()
is implemented for theimpl_static_array
mod, results in a failure to allocate.Steps to reproduce problem
armv7-unknown-linux-gnueabihf
) and use the default backend array bytes sizealloc::Vec::Vec()
an empty vector of u32s, and then push 65 data to it.Proposed problem fix
To address this error, the
imp_static_array::alloc_pages()
function should enforce alignment requirements such that pointers to slices of theSCRATCH_HEAP
are always aligned to the needed byte boundary. The resultingFreeCell
objects will therefore always meet alignment checks, whether or not theextra_assertions
feature is enabled.