mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-12 16:50:22 +02:00
Refactor to add "block_list" type
This commit is contained in:
parent
a8214af467
commit
c7c8fa2d32
1 changed files with 21 additions and 19 deletions
40
whippet.h
40
whippet.h
|
@ -219,17 +219,23 @@ static void block_summary_set_next(struct block_summary *summary,
|
||||||
(summary->next_and_flags & (BLOCK_SIZE - 1)) | next;
|
(summary->next_and_flags & (BLOCK_SIZE - 1)) | next;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void push_block(uintptr_t *loc, size_t *count, uintptr_t block) {
|
// Lock-free block list.
|
||||||
|
struct block_list {
|
||||||
|
size_t count;
|
||||||
|
uintptr_t blocks;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void push_block(struct block_list *list, uintptr_t block) {
|
||||||
|
atomic_fetch_add_explicit(&list->count, 1, memory_order_acq_rel);
|
||||||
struct block_summary *summary = block_summary_for_addr(block);
|
struct block_summary *summary = block_summary_for_addr(block);
|
||||||
uintptr_t next = atomic_load_explicit(loc, memory_order_acquire);
|
uintptr_t next = atomic_load_explicit(&list->blocks, memory_order_acquire);
|
||||||
do {
|
do {
|
||||||
block_summary_set_next(summary, next);
|
block_summary_set_next(summary, next);
|
||||||
} while (!atomic_compare_exchange_weak(loc, &next, block));
|
} while (!atomic_compare_exchange_weak(&list->blocks, &next, block));
|
||||||
atomic_fetch_add_explicit(count, 1, memory_order_acq_rel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t pop_block(uintptr_t *loc, size_t *count) {
|
static uintptr_t pop_block(struct block_list *list) {
|
||||||
uintptr_t head = atomic_load_explicit(loc, memory_order_acquire);
|
uintptr_t head = atomic_load_explicit(&list->blocks, memory_order_acquire);
|
||||||
struct block_summary *summary;
|
struct block_summary *summary;
|
||||||
uintptr_t next;
|
uintptr_t next;
|
||||||
do {
|
do {
|
||||||
|
@ -237,9 +243,9 @@ static uintptr_t pop_block(uintptr_t *loc, size_t *count) {
|
||||||
return 0;
|
return 0;
|
||||||
summary = block_summary_for_addr(head);
|
summary = block_summary_for_addr(head);
|
||||||
next = block_summary_next(summary);
|
next = block_summary_next(summary);
|
||||||
} while (!atomic_compare_exchange_weak(loc, &head, next));
|
} while (!atomic_compare_exchange_weak(&list->blocks, &head, next));
|
||||||
block_summary_set_next(summary, 0);
|
block_summary_set_next(summary, 0);
|
||||||
atomic_fetch_sub_explicit(count, 1, memory_order_acq_rel);
|
atomic_fetch_sub_explicit(&list->count, 1, memory_order_acq_rel);
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,10 +289,8 @@ struct mark_space {
|
||||||
size_t extent;
|
size_t extent;
|
||||||
size_t heap_size;
|
size_t heap_size;
|
||||||
uintptr_t next_block; // atomically
|
uintptr_t next_block; // atomically
|
||||||
uintptr_t empty_blocks; // atomically
|
struct block_list empty;
|
||||||
size_t empty_blocks_count; // atomically
|
struct block_list unavailable;
|
||||||
uintptr_t unavailable_blocks; // atomically
|
|
||||||
size_t unavailable_blocks_count; // atomically
|
|
||||||
ssize_t pending_unavailable_bytes; // atomically
|
ssize_t pending_unavailable_bytes; // atomically
|
||||||
struct slab *slabs;
|
struct slab *slabs;
|
||||||
size_t nslabs;
|
size_t nslabs;
|
||||||
|
@ -483,13 +487,11 @@ static void push_unavailable_block(struct mark_space *space, uintptr_t block) {
|
||||||
ASSERT(!block_summary_has_flag(summary, BLOCK_UNAVAILABLE));
|
ASSERT(!block_summary_has_flag(summary, BLOCK_UNAVAILABLE));
|
||||||
block_summary_set_flag(summary, BLOCK_UNAVAILABLE);
|
block_summary_set_flag(summary, BLOCK_UNAVAILABLE);
|
||||||
madvise((void*)block, BLOCK_SIZE, MADV_DONTNEED);
|
madvise((void*)block, BLOCK_SIZE, MADV_DONTNEED);
|
||||||
push_block(&space->unavailable_blocks, &space->unavailable_blocks_count,
|
push_block(&space->unavailable, block);
|
||||||
block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t pop_unavailable_block(struct mark_space *space) {
|
static uintptr_t pop_unavailable_block(struct mark_space *space) {
|
||||||
uintptr_t block = pop_block(&space->unavailable_blocks,
|
uintptr_t block = pop_block(&space->unavailable);
|
||||||
&space->unavailable_blocks_count);
|
|
||||||
if (!block)
|
if (!block)
|
||||||
return 0;
|
return 0;
|
||||||
struct block_summary *summary = block_summary_for_addr(block);
|
struct block_summary *summary = block_summary_for_addr(block);
|
||||||
|
@ -499,13 +501,13 @@ static uintptr_t pop_unavailable_block(struct mark_space *space) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t pop_empty_block(struct mark_space *space) {
|
static uintptr_t pop_empty_block(struct mark_space *space) {
|
||||||
return pop_block(&space->empty_blocks, &space->empty_blocks_count);
|
return pop_block(&space->empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void push_empty_block(struct mark_space *space, uintptr_t block) {
|
static void push_empty_block(struct mark_space *space, uintptr_t block) {
|
||||||
ASSERT(!block_summary_has_flag(block_summary_for_addr(block),
|
ASSERT(!block_summary_has_flag(block_summary_for_addr(block),
|
||||||
BLOCK_NEEDS_SWEEP));
|
BLOCK_NEEDS_SWEEP));
|
||||||
push_block(&space->empty_blocks, &space->empty_blocks_count, block);
|
push_block(&space->empty, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t mark_space_request_release_memory(struct mark_space *space,
|
static ssize_t mark_space_request_release_memory(struct mark_space *space,
|
||||||
|
@ -800,7 +802,7 @@ static double heap_last_gc_yield(struct heap *heap) {
|
||||||
static double heap_fragmentation(struct heap *heap) {
|
static double heap_fragmentation(struct heap *heap) {
|
||||||
struct mark_space *mark_space = heap_mark_space(heap);
|
struct mark_space *mark_space = heap_mark_space(heap);
|
||||||
size_t mark_space_blocks = mark_space->nslabs * NONMETA_BLOCKS_PER_SLAB;
|
size_t mark_space_blocks = mark_space->nslabs * NONMETA_BLOCKS_PER_SLAB;
|
||||||
mark_space_blocks -= atomic_load(&mark_space->unavailable_blocks_count);
|
mark_space_blocks -= atomic_load(&mark_space->unavailable.count);
|
||||||
size_t mark_space_granules = mark_space_blocks * GRANULES_PER_BLOCK;
|
size_t mark_space_granules = mark_space_blocks * GRANULES_PER_BLOCK;
|
||||||
size_t fragmentation_granules =
|
size_t fragmentation_granules =
|
||||||
mark_space->fragmentation_granules_since_last_collection;
|
mark_space->fragmentation_granules_since_last_collection;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue