8000 py: First steps making GC reentrant. · mimoccc/circuitpython@788f191 · GitHub
[go: up one dir, main page]

Skip to content

Commit 788f191

Browse files
committed
py: First steps making GC reentrant.
1 parent 37ada23 commit 788f191

File tree

9 files changed

+267
-110
lines changed

9 files changed

+267
-110
lines changed

py/gc.c

Lines changed: 245 additions & 78 deletions
Large diffs are not rendered by default.

py/gc.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,12 @@ void gc_init(void *start, void *end);
2828

2929
// These lock/unlock functions can be nested.
3030
// They can be used to prevent the GC from allocating/freeing.
31-
void gc_lock(void);
32-
void gc_unlock(void);
33-
bool gc_is_locked(void);
31+
void gc_disable(void);
32+
void gc_enable(void);
3433

3534
// A given port must implement gc_collect by using the other collect functions.
3635
void gc_collect(void);
37-
void gc_collect_start(void);
36+
bool gc_collect_start(void); // returns true if collection can proceed
3837
void gc_collect_root(void **ptrs, mp_uint_t len);
3938
void gc_collect_end(void);
4039

py/modgc.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,19 @@ MP_DEFINE_CONST_FUN_OBJ_0(gc_collect_obj, py_gc_collect);
5555

5656
/// \function disable()
5757
/// Disable the garbage collector.
58-
STATIC mp_obj_t gc_disable(void) {
59-
gc_lock();
58+
STATIC mp_obj_t mod_gc_disable(void) {
59+
gc_disable();
6060
return mp_const_none;
6161
}
62-
MP_DEFINE_CONST_FUN_OBJ_0(gc_disable_obj, gc_disable);
62+
MP_DEFINE_CONST_FUN_OBJ_0(gc_disable_obj, mod_gc_disable);
6363

6464
/// \function enable()
6565
/// Enable the garbage collector.
66-
STATIC mp_obj_t gc_enable(void) {
67-
gc_unlock();
66+
STATIC mp_obj_t mod_gc_enable(void) {
67+
gc_enable();
6868
return mp_const_none;
6969
}
70-
MP_DEFINE_CONST_FUN_OBJ_0(gc_enable_obj, gc_enable);
70+
MP_DEFINE_CONST_FUN_OBJ_0(gc_enable_obj, mod_gc_enable);
7171

7272
/// \function mem_free()
7373
/// Return the number of bytes of available heap RAM.

py/objexcept.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,8 @@ void mp_obj_exception_clear_traceback(mp_obj_t self_in) {
436436
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, mp_uint_t line, qstr block) {
437437
GET_NATIVE_EXCEPTION(self, self_in);
438438

439-
#if MICROPY_ENABLE_GC
439+
#if 0 && MICROPY_ENABLE_GC
440+
// TODO
440441
if (gc_is_locked()) {
441442
if (self->traceback == MP_OBJ_NULL) {
442443
// We can't allocate any memory, and no memory has been

py/runtime.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,17 +1208,8 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i
12081208

12091209
void *m_malloc_fail(size_t num_bytes) {
12101210
DEBUG_printf("memory allocation failed, allocating " UINT_FMT " bytes\n", num_bytes);
1211-
if (0) {
1212-
// dummy
1213-
#if MICROPY_ENABLE_GC
1214-
} else if (gc_is_locked()) {
1215-
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError,
1216-
"memory allocation failed, heap is locked"));
1217-
#endif
1218-
} else {
1219-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError,
1220-
"memory allocation failed, allocating " UINT_FMT " bytes", num_bytes));
1221-
}
1211+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError,
1212+
"memory allocation failed, allocating " UINT_FMT " bytes", num_bytes));
12221213
}
12231214

12241215
NORETURN void mp_not_implemented(const char *msg) {

stmhal/extint.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,6 @@ void Handle_EXTI_Irq(uint32_t line) {
361361
if (line < EXTI_NUM_VECTORS) {
362362
extint_vector_t *v = &extint_vector[line];
363363
if (v->callback_obj != mp_const_none) {
364-
// When executing code within a handler we must lock the GC to prevent
365-
// any memory allocations. We must also catch any exceptions.
366-
gc_lock();
367364
nlr_buf_t nlr;
368365
if (nlr_push(&nlr) == 0) {
369366
mp_call_function_1(v->callback_obj, MP_OBJ_NEW_SMALL_INT(line));
@@ -375,7 +372,6 @@ void Handle_EXTI_Irq(uint32_t line) {
375372
printf("Uncaught exception in ExtInt interrupt handler line %lu\n", line);
376373
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
377374
}
378-
gc_unlock();
379375
}
380376
}
381377
}

stmhal/gccollect.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ void gc_collect(void) {
4545
uint32_t start = HAL_GetTick();
4646

4747
// start the GC
48-
gc_collect_start();
48+
if (!gc_collect_start()) {
49+
// gc is already running
50+
return;
51+
}
4952

5053
// We need to scan everything in RAM that can hold a pointer.
5154
// The data segment is used, but should not contain pointers, so we just scan the bss.

stmhal/timer.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,9 +1229,6 @@ STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_o
12291229

12301230
// execute callback if it's set
12311231
if (callback != mp_const_none) {
1232-
// When executing code within a handler we must lock the GC to prevent
1233-
// any memory allocations. We must also catch any exceptions.
1234-
gc_lock();
12351232
nlr_buf_t nlr;
12361233
if (nlr_push(&nlr) == 0) {
12371234
mp_call_function_1(callback, tim);
@@ -1247,7 +1244,6 @@ STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_o
12471244
}
12481245
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
12491246
}
1250-
gc_unlock();
12511247
}
12521248
}
12531249
}

unix/gccollect.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ void gc_helper_get_regs(regs_t arr) {
128128
void gc_collect(void) {
129129
//gc_dump_info();
130130

131-
gc_collect_start();
131+
if (!gc_collect_start()) {
132+
// gc is already running
133+
return;
134+
}
135+
132136
// this traces the .bss section
133137
#if defined( __CYGWIN__ )
134138
#define BSS_START __bss_start__

0 commit comments

Comments
 (0)
0