Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance fix: Lower operations and function calls by checking for zone_address before doing expensive memory reads #767

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 38 additions & 29 deletions src/allocator.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,23 +534,22 @@ _dispatch_alloc_maybe_madvise_page(dispatch_continuation_t c)
volatile bitmap_t *page_bitmaps;
get_maps_and_indices_for_continuation((dispatch_continuation_t)page, NULL,
NULL, (bitmap_t **)&page_bitmaps, NULL);
unsigned int i;
for (i = 0; i < BITMAPS_PER_PAGE; i++) {
if (page_bitmaps[i] != 0) {
unsigned int last_locked;
for (last_locked = 0; last_locked < BITMAPS_PER_PAGE; last_locked++) {
if (page_bitmaps[last_locked] != 0) {
return;
}
}
// They are all unallocated, so we could madvise the page. Try to
// take ownership of them all.
int last_locked = 0;
do {
for (last_locked = 0; last_locked < BITMAPS_PER_PAGE; last_locked++) {
if (!os_atomic_cmpxchg(&page_bitmaps[last_locked], BITMAP_C(0),
BITMAP_ALL_ONES, relaxed)) {
// We didn't get one; since there is a cont allocated in
// the page, we can't madvise. Give up and unlock all.
goto unlock;
}
} while (++last_locked < (signed)BITMAPS_PER_PAGE);
}
#if DISPATCH_DEBUG
//fprintf(stderr, "%s: madvised page %p for cont %p (next = %p), "
// "[%u+1]=%u bitmaps at %p\n", __func__, page, c, c->do_next,
Expand All @@ -563,10 +562,10 @@ _dispatch_alloc_maybe_madvise_page(dispatch_continuation_t c)
MADV_FREE));

unlock:
while (last_locked > 1) {
page_bitmaps[--last_locked] = BITMAP_C(0);
}
if (last_locked) {
while (last_locked > 1) {
page_bitmaps[--last_locked] = BITMAP_C(0);
}
os_atomic_store(&page_bitmaps[0], BITMAP_C(0), relaxed);
}
return;
Expand Down Expand Up @@ -654,27 +653,37 @@ _dispatch_allocator_enumerate(task_t remote_task,
vm_address_t zone_address, memory_reader_t reader,
void (^recorder)(vm_address_t, void *, size_t, bool *stop))
{
const size_t heap_size = remote_dal->dal_magazine_size;
const size_t dc_size = remote_dal->dal_allocation_size;
const size_t dc_flags_offset = remote_dal->dal_allocation_isa_offset;
bool stop = false;
void *heap;

while (zone_address) {
// FIXME: improve this by not faulting everything and driving it through
// the bitmap.
kern_return_t kr = reader(remote_task, zone_address, heap_size, &heap);
size_t offs = remote_dal->dal_first_allocation_offset;
if (kr) return kr;
while (offs < heap_size) {
void *isa = *(void **)(heap + offs + dc_flags_offset);
if (isa && isa != remote_dal->dal_deferred_free_isa) {
recorder(zone_address + offs, heap + offs, dc_size, &stop);
if (stop) return KERN_SUCCESS;
if (zone_address)
{
const size_t heap_size = remote_dal->dal_magazine_size;
const size_t dc_size = remote_dal->dal_allocation_size;
const size_t dc_flags_offset = remote_dal->dal_allocation_isa_offset;
bool stop = false;
void *heap = NULL;

do
{
// FIXME: improve this by not faulting everything and driving it through
// the bitmap.
kern_return_t kr;
size_t offs;

kr = reader(remote_task, zone_address, heap_size, &heap);
if (kr)
return kr;

for (offs = remote_dal->dal_first_allocation_offset; offs < heap_size; offs += dc_size)
{
void *isa = *(void **)(heap + offs + dc_flags_offset);
if (isa && isa != remote_dal->dal_deferred_free_isa)
{
recorder(zone_address + offs, heap + offs, dc_size, &stop);
if (stop)
return KERN_SUCCESS;
}
}
offs += dc_size;
}
zone_address = (vm_address_t)((dispatch_heap_t)heap)->header.dh_next;
zone_address = (vm_address_t)((dispatch_heap_t)heap)->header.dh_next;
} while (zone_address);
}

return KERN_SUCCESS;
Expand Down