mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-28 09:30:58 +01:00
mem: actually fully fix the heap bug, add comments for future self
This commit is contained in:
parent
0f2855ada8
commit
df5537b748
@ -976,27 +976,35 @@ namespace ams::mem::impl::heap {
|
|||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* Save the extents of the free span we found. */
|
||||||
|
auto * const prev_ptr = span->start.p;
|
||||||
const size_t prev_pages = span->num_pages;
|
const size_t prev_pages = span->num_pages;
|
||||||
|
|
||||||
|
/* Allocate a new span struct. */
|
||||||
Span *new_span = this->AllocateSpanStruct();
|
Span *new_span = this->AllocateSpanStruct();
|
||||||
if (new_span == nullptr) {
|
if (new_span == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto new_span_guard = SCOPE_GUARD { this->FreeSpanToSpanPage(new_span); };
|
auto new_span_guard = SCOPE_GUARD { this->FreeSpanToSpanPage(new_span); };
|
||||||
|
|
||||||
span = GetSpanFromPointer(std::addressof(this->span_table), span->start.p);
|
/* Allocating the new span potentially invalidates the span we were looking at, so find the span for it in the table. */
|
||||||
const size_t found_pages = span->num_pages;
|
span = GetSpanFromPointer(std::addressof(this->span_table), prev_ptr);
|
||||||
|
const size_t cur_pages = span->num_pages;
|
||||||
|
|
||||||
|
/* If the span was partially allocated, we need to find a new one that's big enough. */
|
||||||
if (found_pages != prev_pages) {
|
if (cur_pages != prev_pages) {
|
||||||
span = this->SearchFreeSpan(num_pages);
|
span = this->SearchFreeSpan(num_pages);
|
||||||
if (span == nullptr) {
|
if (span == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_pages == prev_pages || num_pages != span->num_pages) {
|
/* If the span is big enough to split (span->num_pages > num_pages), we want to split it. */
|
||||||
/* We're going to use the new span. */
|
/* span->num_pages > num_pages is true if the span wasn't partially allocated (cur_pages == prev_pages) */
|
||||||
|
/* OR if the new free span we found has num_pages > num_pages. Note that we know span->num_pages >= num_pages */
|
||||||
|
/* so this > condition can be expressed as span->num_pages != num_pages. */
|
||||||
|
if (cur_pages == prev_pages || num_pages != span->num_pages) {
|
||||||
|
/* We're going to use the new span for our split. */
|
||||||
new_span_guard.Cancel();
|
new_span_guard.Cancel();
|
||||||
|
|
||||||
return this->SplitSpan(span, num_pages, new_span);
|
return this->SplitSpan(span, num_pages, new_span);
|
||||||
|
Loading…
Reference in New Issue
Block a user