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>
This commit is contained in:
committed by
Damien George
parent
8a2ff2ca73
commit
40e1c111e1
@@ -132,13 +132,13 @@ static MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_lock_obj, mp_micropython_he
|
||||
|
||||
static mp_obj_t mp_micropython_heap_unlock(void) {
|
||||
gc_unlock();
|
||||
return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth));
|
||||
return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth) >> GC_LOCK_DEPTH_SHIFT);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_unlock_obj, mp_micropython_heap_unlock);
|
||||
|
||||
#if MICROPY_PY_MICROPYTHON_HEAP_LOCKED
|
||||
static mp_obj_t mp_micropython_heap_locked(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth));
|
||||
return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth) >> GC_LOCK_DEPTH_SHIFT);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_locked_obj, mp_micropython_heap_locked);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user