Skip to content

Commit 3360c19

Browse files
committed
Determine offset AFTER kern_return_t check, not before
1 parent 4bf826d commit 3360c19

File tree

1 file changed

+33
-24
lines changed

1 file changed

+33
-24
lines changed

Diff for: src/allocator.c

+33-24
Original file line numberDiff line numberDiff line change
@@ -542,15 +542,14 @@ _dispatch_alloc_maybe_madvise_page(dispatch_continuation_t c)
542542
}
543543
// They are all unallocated, so we could madvise the page. Try to
544544
// take ownership of them all.
545-
int last_locked = 0;
546-
do {
547-
if (!os_atomic_cmpxchg(&page_bitmaps[last_locked], BITMAP_C(0),
545+
for (i = 0; i < BITMAPS_PER_PAGE; i++) {
546+
if (!os_atomic_cmpxchg(&page_bitmaps[i], BITMAP_C(0),
548547
BITMAP_ALL_ONES, relaxed)) {
549548
// We didn't get one; since there is a cont allocated in
550549
// the page, we can't madvise. Give up and unlock all.
551550
goto unlock;
552551
}
553-
} while (++last_locked < (signed)BITMAPS_PER_PAGE);
552+
}
554553
#if DISPATCH_DEBUG
555554
//fprintf(stderr, "%s: madvised page %p for cont %p (next = %p), "
556555
// "[%u+1]=%u bitmaps at %p\n", __func__, page, c, c->do_next,
@@ -654,27 +653,37 @@ _dispatch_allocator_enumerate(task_t remote_task,
654653
vm_address_t zone_address, memory_reader_t reader,
655654
void (^recorder)(vm_address_t, void *, size_t, bool *stop))
656655
{
657-
const size_t heap_size = remote_dal->dal_magazine_size;
658-
const size_t dc_size = remote_dal->dal_allocation_size;
659-
const size_t dc_flags_offset = remote_dal->dal_allocation_isa_offset;
660-
bool stop = false;
661-
void *heap;
662-
663-
while (zone_address) {
664-
// FIXME: improve this by not faulting everything and driving it through
665-
// the bitmap.
666-
kern_return_t kr = reader(remote_task, zone_address, heap_size, &heap);
667-
size_t offs = remote_dal->dal_first_allocation_offset;
668-
if (kr) return kr;
669-
while (offs < heap_size) {
670-
void *isa = *(void **)(heap + offs + dc_flags_offset);
671-
if (isa && isa != remote_dal->dal_deferred_free_isa) {
672-
recorder(zone_address + offs, heap + offs, dc_size, &stop);
673-
if (stop) return KERN_SUCCESS;
656+
if (zone_address)
657+
{
658+
const size_t heap_size = remote_dal->dal_magazine_size;
659+
const size_t dc_size = remote_dal->dal_allocation_size;
660+
const size_t dc_flags_offset = remote_dal->dal_allocation_isa_offset;
661+
bool stop = false;
662+
void *heap = NULL;
663+
664+
do
665+
{
666+
// FIXME: improve this by not faulting everything and driving it through
667+
// the bitmap.
668+
kern_return_t kr;
669+
size_t offs;
670+
671+
kr = reader(remote_task, zone_address, heap_size, &heap);
672+
if (kr)
673+
return kr;
674+
675+
for (offs = remote_dal->dal_first_allocation_offset; offs < heap_size; offs += dc_size)
676+
{
677+
void *isa = *(void **)(heap + offs + dc_flags_offset);
678+
if (isa && isa != remote_dal->dal_deferred_free_isa)
679+
{
680+
recorder(zone_address + offs, heap + offs, dc_size, &stop);
681+
if (stop)
682+
return KERN_SUCCESS;
683+
}
674684
}
675-
offs += dc_size;
676-
}
677-
zone_address = (vm_address_t)((dispatch_heap_t)heap)->header.dh_next;
685+
zone_address = (vm_address_t)((dispatch_heap_t)heap)->header.dh_next;
686+
} while (zone_address);
678687
}
679688

680689
return KERN_SUCCESS;

0 commit comments

Comments
 (0)