py/gc: Make improvements to MICROPY_GC_HOOK_LOOP.
Changes in this commit: - Add MICROPY_GC_HOOK_LOOP to gc_info() and gc_alloc(). Both of these can be long running (many milliseconds) which is too long to be blocking in some applications. - Pass loop variable to MICROPY_GC_HOOK_LOOP(i) macro so that implementers can use it, e.g. to improve performance by only calling a function every X number of iterations. - Drop outer call to MICROPY_GC_HOOK_LOOP in gc_mark_subtree().
This commit is contained in:
parent
7c645b52e3
commit
468ed218c9
14
py/gc.c
14
py/gc.c
@ -285,10 +285,8 @@ STATIC void gc_mark_subtree(size_t block)
|
||||
// Start with the block passed in the argument.
|
||||
size_t sp = 0;
|
||||
for (;;) {
|
||||
MICROPY_GC_HOOK_LOOP
|
||||
|
||||
#if !MICROPY_GC_SPLIT_HEAP
|
||||
mp_state_mem_area_t * area = &MP_STATE_MEM(area);
|
||||
mp_state_mem_area_t *area = &MP_STATE_MEM(area);
|
||||
#endif
|
||||
|
||||
// work out number of consecutive blocks in the chain starting with this one
|
||||
@ -303,7 +301,7 @@ STATIC void gc_mark_subtree(size_t block)
|
||||
// check this block's children
|
||||
void **ptrs = (void **)PTR_FROM_BLOCK(area, block);
|
||||
for (size_t i = n_blocks * BYTES_PER_BLOCK / sizeof(void *); i > 0; i--, ptrs++) {
|
||||
MICROPY_GC_HOOK_LOOP
|
||||
MICROPY_GC_HOOK_LOOP(i);
|
||||
void *ptr = *ptrs;
|
||||
// If this is a heap pointer that hasn't been marked, mark it and push
|
||||
// it's children to the stack.
|
||||
@ -359,7 +357,7 @@ STATIC void gc_deal_with_stack_overflow(void) {
|
||||
// scan entire memory looking for blocks which have been marked but not their children
|
||||
for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) {
|
||||
for (size_t block = 0; block < area->gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) {
|
||||
MICROPY_GC_HOOK_LOOP
|
||||
MICROPY_GC_HOOK_LOOP(block);
|
||||
// trace (again) if mark bit set
|
||||
if (ATB_GET_KIND(area, block) == AT_MARK) {
|
||||
#if MICROPY_GC_SPLIT_HEAP
|
||||
@ -381,7 +379,7 @@ STATIC void gc_sweep(void) {
|
||||
int free_tail = 0;
|
||||
for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) {
|
||||
for (size_t block = 0; block < area->gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) {
|
||||
MICROPY_GC_HOOK_LOOP
|
||||
MICROPY_GC_HOOK_LOOP(block);
|
||||
switch (ATB_GET_KIND(area, block)) {
|
||||
case AT_HEAD:
|
||||
#if MICROPY_ENABLE_FINALISER
|
||||
@ -475,7 +473,7 @@ void gc_collect_root(void **ptrs, size_t len) {
|
||||
mp_state_mem_area_t *area = &MP_STATE_MEM(area);
|
||||
#endif
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
MICROPY_GC_HOOK_LOOP
|
||||
MICROPY_GC_HOOK_LOOP(i);
|
||||
void *ptr = gc_get_ptr(ptrs, i);
|
||||
#if MICROPY_GC_SPLIT_HEAP
|
||||
mp_state_mem_area_t *area = gc_get_ptr_area(ptr);
|
||||
@ -533,6 +531,7 @@ void gc_info(gc_info_t *info) {
|
||||
bool finish = false;
|
||||
info->total += area->gc_pool_end - area->gc_pool_start;
|
||||
for (size_t block = 0, len = 0, len_free = 0; !finish;) {
|
||||
MICROPY_GC_HOOK_LOOP(block);
|
||||
size_t kind = ATB_GET_KIND(area, block);
|
||||
switch (kind) {
|
||||
case AT_FREE:
|
||||
@ -632,6 +631,7 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) {
|
||||
for (; area != NULL; area = NEXT_AREA(area), i = 0) {
|
||||
n_free = 0;
|
||||
for (i = area->gc_last_free_atb_index; i < area->gc_alloc_table_byte_len; i++) {
|
||||
MICROPY_GC_HOOK_LOOP(i);
|
||||
byte a = area->gc_alloc_table_start[i];
|
||||
// *FORMAT-OFF*
|
||||
if (ATB_0_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 0; goto found; } } else { n_free = 0; }
|
||||
|
@ -617,8 +617,9 @@
|
||||
#endif
|
||||
|
||||
// Hook to run code during time consuming garbage collector operations
|
||||
// *i* is the loop index variable (e.g. can be used to run every x loops)
|
||||
#ifndef MICROPY_GC_HOOK_LOOP
|
||||
#define MICROPY_GC_HOOK_LOOP
|
||||
#define MICROPY_GC_HOOK_LOOP(i)
|
||||
#endif
|
||||
|
||||
// Whether to provide m_tracked_calloc, m_tracked_free functions
|
||||
|
Loading…
Reference in New Issue
Block a user