diff options
author | Angus Gratton <angus@redyak.com.au> | 2024-12-04 10:58:06 +1100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2025-02-03 15:02:02 +1100 |
commit | 40e1c111e17864044190596dff6d32955d11280c (patch) | |
tree | 55eb42d4b6a88feedecbc0009ae4a8dbd57faa31 /py/mpstate.h | |
parent | 8a2ff2ca7366f605dd55c93f6b393552b365cd10 (diff) | |
download | micropython-40e1c111e17864044190596dff6d32955d11280c.tar.gz micropython-40e1c111e17864044190596dff6d32955d11280c.zip |
py/gc: Allow gc_free from inside a gc_sweep finalizer.
Do this by tracking being inside gc collection with a
separate flag, GC_COLLECT_FLAG. In gc_free(),
ignore this flag when determining if the heap is locked.
* For finalisers calling gc_free() when heap is otherwise unlocked,
this allows memory to be immediately freed (potentially
avoiding a MemoryError).
* Hard IRQs still can't call gc_free(), as heap will be locked via
gc_lock().
* If finalisers are disabled then all of this code can be compiled
out to save some code size.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Diffstat (limited to 'py/mpstate.h')
-rw-r--r-- | py/mpstate.h | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/py/mpstate.h b/py/mpstate.h index 54eca596da..51f290b55b 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -77,6 +77,18 @@ typedef struct _mp_sched_item_t { mp_obj_t arg; } mp_sched_item_t; +// gc_lock_depth field is a combination of the GC_COLLECT_FLAG +// bit and a lock depth shifted GC_LOCK_DEPTH_SHIFT bits left. +#if MICROPY_ENABLE_FINALISER +#define GC_COLLECT_FLAG 1 +#define GC_LOCK_DEPTH_SHIFT 1 +#else +// If finalisers are disabled then this check doesn't matter, as gc_lock() +// is called anywhere else that heap can't be changed. So save some code size. +#define GC_COLLECT_FLAG 0 +#define GC_LOCK_DEPTH_SHIFT 0 +#endif + // This structure holds information about a single contiguous area of // memory reserved for the memory manager. typedef struct _mp_state_mem_area_t { @@ -268,6 +280,7 @@ typedef struct _mp_state_thread_t { #endif // Locking of the GC is done per thread. + // See GC_LOCK_DEPTH_SHIFT for an explanation of this field. uint16_t gc_lock_depth; //////////////////////////////////////////////////////////// |