Skip to content

Commit 5ff6c12

Browse files
committed
esp32/main: Store native code as linked list instead of list on GC heap.
Finalisers that run during `gc_sweep_all()` may run native code, for example if an open file is closed and the underlying block device is implemented in native code, then the filesystem driver (eg FAT) may call into the native code. Therefore, native code must be freed after the call to `gc_sweep_all()`. That can only be achieved if the GC heap is not used to store the list of allocated native code blocks. Instead, this commit makes the native code blocks a linked list. Signed-off-by: Damien George <damien@micropython.org>
1 parent 6fead31 commit 5ff6c12

File tree

1 file changed

+27
-21
lines changed

1 file changed

+27
-21
lines changed

ports/esp32/main.c

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@
7878
#define MP_TASK_STACK_LIMIT_MARGIN (1024)
7979
#endif
8080

81+
typedef struct _native_code_node_t {
82+
struct _native_code_node_t *next;
83+
uint32_t data[];
84+
} native_code_node_t;
85+
86+
static native_code_node_t *native_code_head = NULL;
87+
88+
static void esp_native_code_free_all(void);
89+
8190
int vprintf_null(const char *format, va_list ap) {
8291
// do nothing: this is used as a log target during raw repl mode
8392
return 0;
@@ -130,8 +139,6 @@ void mp_task(void *pvParameter) {
130139
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
131140
readline_init0();
132141

133-
MP_STATE_PORT(native_code_pointers) = MP_OBJ_NULL;
134-
135142
// initialise peripherals
136143
machine_pins_init();
137144
#if MICROPY_PY_MACHINE_I2S
@@ -182,18 +189,11 @@ void mp_task(void *pvParameter) {
182189
mp_thread_deinit();
183190
#endif
184191

185-
// Free any native code pointers that point to iRAM.
186-
if (MP_STATE_PORT(native_code_pointers) != MP_OBJ_NULL) {
187-
size_t len;
188-
mp_obj_t *items;
189-
mp_obj_list_get(MP_STATE_PORT(native_code_pointers), &len, &items);
190-
for (size_t i = 0; i < len; ++i) {
191-
heap_caps_free(MP_OBJ_TO_PTR(items[i]));
192-
}
193-
}
194-
195192
gc_sweep_all();
196193

194+
// Free any native code pointers that point to iRAM.
195+
esp_native_code_free_all();
196+
197197
mp_hal_stdout_tx_str("MPY: soft reboot\r\n");
198198

199199
// deinitialise peripherals
@@ -232,21 +232,27 @@ void nlr_jump_fail(void *val) {
232232
esp_restart();
233233
}
234234

235+
static void esp_native_code_free_all(void) {
236+
while (native_code_head != NULL) {
237+
native_code_node_t *next = native_code_head->next;
238+
heap_caps_free(native_code_head);
239+
native_code_head = next;
240+
}
241+
}
242+
235243
void *esp_native_code_commit(void *buf, size_t len, void *reloc) {
236244
len = (len + 3) & ~3;
237-
uint32_t *p = heap_caps_malloc(len, MALLOC_CAP_EXEC);
238-
if (p == NULL) {
239-
m_malloc_fail(len);
240-
}
241-
if (MP_STATE_PORT(native_code_pointers) == MP_OBJ_NULL) {
242-
MP_STATE_PORT(native_code_pointers) = mp_obj_new_list(0, NULL);
245+
size_t len_node = sizeof(native_code_node_t) + len;
246+
native_code_node_t *node = heap_caps_malloc(len_node, MALLOC_CAP_EXEC);
247+
if (node == NULL) {
248+
m_malloc_fail(len_node);
243249
}
244-
mp_obj_list_append(MP_STATE_PORT(native_code_pointers), MP_OBJ_TO_PTR(p));
250+
node->next = native_code_head;
251+
native_code_head = node;
252+
void *p = node->data;
245253
if (reloc) {
246254
mp_native_relocate(reloc, buf, (uintptr_t)p);
247255
}
248256
memcpy(p, buf, len);
249257
return p;
250258
}
251-
252-
MP_REGISTER_ROOT_POINTER(mp_obj_t native_code_pointers);

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