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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy