Skip to content

Commit cd4fb3a

Browse files
committed
py: Add a fast version of gc_info.
The existing gc_info is very slow on large heaps. This patch adds a fast version that only computes total/used/free which can be used for frequent polling. Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
1 parent 6f0ad59 commit cd4fb3a

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

py/gc.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,25 @@ void gc_info(gc_info_t *info) {
825825
GC_EXIT();
826826
}
827827

828+
// Fast version of gc_info that only computes total/used/free.
829+
void gc_info_fast(gc_info_t *info) {
830+
GC_ENTER();
831+
memset(info, 0, sizeof(*info));
832+
const uint8_t lut[16] = {2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0};
833+
for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) {
834+
size_t free_blocks = 0;
835+
info->total += area->gc_pool_end - area->gc_pool_start;
836+
for (size_t i = 0; i < area->gc_alloc_table_byte_len; i++) {
837+
uint8_t atb = area->gc_alloc_table_start[i];
838+
free_blocks += lut[atb & 0xF] + lut[atb >> 4];
839+
}
840+
info->free += free_blocks;
841+
}
842+
info->free *= BYTES_PER_BLOCK;
843+
info->used = info->total - info->free;
844+
GC_EXIT();
845+
}
846+
828847
#if MICROPY_PY_WEAKREF
829848
// Mark the GC heap pointer as having a weakref.
830849
void gc_weakref_mark(void *ptr) {

py/gc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ typedef struct _gc_info_t {
8686
} gc_info_t;
8787

8888
void gc_info(gc_info_t *info);
89+
void gc_info_fast(gc_info_t *info);
8990
void gc_dump_info(const mp_print_t *print);
9091
void gc_dump_alloc_table(const mp_print_t *print);
9192

0 commit comments

Comments
 (0)