py: Add MP_STATE_THREAD to hold state specific to a given thread.
This commit is contained in:
parent
3545ef8bb4
commit
330165a2cc
|
@ -142,7 +142,7 @@ void gc_collect(void) {
|
|||
gc_helper_get_regs(regs);
|
||||
// GC stack (and regs because we captured them)
|
||||
void **regs_ptr = (void**)(void*)®s;
|
||||
gc_collect_root(regs_ptr, ((mp_uint_t)MP_STATE_VM(stack_top) - (mp_uint_t)®s) / sizeof(mp_uint_t));
|
||||
gc_collect_root(regs_ptr, ((mp_uint_t)MP_STATE_THREAD(stack_top) - (mp_uint_t)®s) / sizeof(mp_uint_t));
|
||||
#if MICROPY_EMIT_NATIVE
|
||||
mp_unix_mark_exec();
|
||||
#endif
|
||||
|
|
|
@ -64,7 +64,7 @@ soft_reset:
|
|||
|
||||
// init MicroPython runtime
|
||||
int stack_dummy;
|
||||
MP_STATE_VM(stack_top) = (char*)&stack_dummy;
|
||||
MP_STATE_THREAD(stack_top) = (char*)&stack_dummy;
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
mp_init();
|
||||
mp_hal_init();
|
||||
|
@ -93,7 +93,7 @@ void gc_collect(void) {
|
|||
void *dummy;
|
||||
gc_collect_start();
|
||||
// Node: stack is ascending
|
||||
gc_collect_root(&dummy, ((mp_uint_t)&dummy - (mp_uint_t)MP_STATE_VM(stack_top)) / sizeof(mp_uint_t));
|
||||
gc_collect_root(&dummy, ((mp_uint_t)&dummy - (mp_uint_t)MP_STATE_THREAD(stack_top)) / sizeof(mp_uint_t));
|
||||
gc_collect_end();
|
||||
}
|
||||
|
||||
|
|
4
py/gc.c
4
py/gc.c
|
@ -279,7 +279,7 @@ void gc_collect_start(void) {
|
|||
// correctly in the mp_state_ctx structure. We scan nlr_top, dict_locals,
|
||||
// dict_globals, then the root pointer section of mp_state_vm.
|
||||
void **ptrs = (void**)(void*)&mp_state_ctx;
|
||||
gc_collect_root(ptrs, offsetof(mp_state_ctx_t, vm.stack_top) / sizeof(void*));
|
||||
gc_collect_root(ptrs, offsetof(mp_state_ctx_t, vm.qstr_last_chunk) / sizeof(void*));
|
||||
}
|
||||
|
||||
void gc_collect_root(void **ptrs, size_t len) {
|
||||
|
@ -713,7 +713,7 @@ void gc_dump_alloc_table(void) {
|
|||
}
|
||||
if (c == 'h') {
|
||||
ptrs = (void**)&c;
|
||||
len = ((mp_uint_t)MP_STATE_VM(stack_top) - (mp_uint_t)&c) / sizeof(mp_uint_t);
|
||||
len = ((mp_uint_t)MP_STATE_THREAD(stack_top) - (mp_uint_t)&c) / sizeof(mp_uint_t);
|
||||
for (mp_uint_t i = 0; i < len; i++) {
|
||||
mp_uint_t ptr = (mp_uint_t)ptrs[i];
|
||||
if (VERIFY_PTR(ptr) && BLOCK_FROM_PTR(ptr) == bl) {
|
||||
|
|
|
@ -60,7 +60,7 @@ mp_obj_t mp_micropython_mem_info(size_t n_args, const mp_obj_t *args) {
|
|||
(mp_uint_t)m_get_total_bytes_allocated(), (mp_uint_t)m_get_current_bytes_allocated(), (mp_uint_t)m_get_peak_bytes_allocated());
|
||||
#endif
|
||||
#if MICROPY_STACK_CHECK
|
||||
mp_printf(&mp_plat_print, "stack: " UINT_FMT " out of " INT_FMT "\n", mp_stack_usage(), MP_STATE_VM(stack_limit));
|
||||
mp_printf(&mp_plat_print, "stack: " UINT_FMT " out of " INT_FMT "\n", mp_stack_usage(), MP_STATE_THREAD(stack_limit));
|
||||
#else
|
||||
mp_printf(&mp_plat_print, "stack: " UINT_FMT "\n", mp_stack_usage());
|
||||
#endif
|
||||
|
|
33
py/mpstate.h
33
py/mpstate.h
|
@ -91,9 +91,6 @@ typedef struct _mp_state_vm_t {
|
|||
// this must start at the start of this structure
|
||||
//
|
||||
|
||||
// Note: nlr asm code has the offset of this hard-coded
|
||||
nlr_buf_t *nlr_top;
|
||||
|
||||
qstr_pool_t *last_pool;
|
||||
|
||||
// non-heap memory for creating an exception if we can't allocate RAM
|
||||
|
@ -161,14 +158,6 @@ typedef struct _mp_state_vm_t {
|
|||
size_t qstr_last_alloc;
|
||||
size_t qstr_last_used;
|
||||
|
||||
// Stack top at the start of program
|
||||
// Note: this entry is used to locate the end of the root pointer section.
|
||||
char *stack_top;
|
||||
|
||||
#if MICROPY_STACK_CHECK
|
||||
mp_uint_t stack_limit;
|
||||
#endif
|
||||
|
||||
mp_uint_t mp_optimise_value;
|
||||
|
||||
// size of the emergency exception buf, if it's dynamically allocated
|
||||
|
@ -177,7 +166,22 @@ typedef struct _mp_state_vm_t {
|
|||
#endif
|
||||
} mp_state_vm_t;
|
||||
|
||||
// This structure combines the above 2 structures, and adds the local
|
||||
// This structure holds state that is specific to a given thread.
|
||||
// Everything in this structure is scanned for root pointers.
|
||||
typedef struct _mp_state_thread_t {
|
||||
// Note: nlr asm code has the offset of this hard-coded
|
||||
nlr_buf_t *nlr_top; // ROOT POINTER
|
||||
|
||||
// Stack top at the start of program
|
||||
// Note: this entry is used to locate the end of the root pointer section.
|
||||
char *stack_top;
|
||||
|
||||
#if MICROPY_STACK_CHECK
|
||||
size_t stack_limit;
|
||||
#endif
|
||||
} mp_state_thread_t;
|
||||
|
||||
// This structure combines the above 3 structures, and adds the local
|
||||
// and global dicts.
|
||||
// Note: if this structure changes then revisit all nlr asm code since they
|
||||
// have the offset of nlr_top hard-coded.
|
||||
|
@ -185,7 +189,8 @@ typedef struct _mp_state_ctx_t {
|
|||
// these must come first for root pointer scanning in GC to work
|
||||
mp_obj_dict_t *dict_locals;
|
||||
mp_obj_dict_t *dict_globals;
|
||||
// this must come next for root pointer scanning in GC to work
|
||||
// these must come next in this order for root pointer scanning in GC to work
|
||||
mp_state_thread_t thread;
|
||||
mp_state_vm_t vm;
|
||||
mp_state_mem_t mem;
|
||||
} mp_state_ctx_t;
|
||||
|
@ -196,4 +201,6 @@ extern mp_state_ctx_t mp_state_ctx;
|
|||
#define MP_STATE_VM(x) (mp_state_ctx.vm.x)
|
||||
#define MP_STATE_MEM(x) (mp_state_ctx.mem.x)
|
||||
|
||||
#define MP_STATE_THREAD(x) (mp_state_ctx.thread.x)
|
||||
|
||||
#endif // __MICROPY_INCLUDED_PY_MPSTATE_H__
|
||||
|
|
|
@ -32,23 +32,23 @@
|
|||
|
||||
void mp_stack_ctrl_init(void) {
|
||||
volatile int stack_dummy;
|
||||
MP_STATE_VM(stack_top) = (char*)&stack_dummy;
|
||||
MP_STATE_THREAD(stack_top) = (char*)&stack_dummy;
|
||||
}
|
||||
|
||||
void mp_stack_set_top(void *top) {
|
||||
MP_STATE_VM(stack_top) = top;
|
||||
MP_STATE_THREAD(stack_top) = top;
|
||||
}
|
||||
|
||||
mp_uint_t mp_stack_usage(void) {
|
||||
// Assumes descending stack
|
||||
volatile int stack_dummy;
|
||||
return MP_STATE_VM(stack_top) - (char*)&stack_dummy;
|
||||
return MP_STATE_THREAD(stack_top) - (char*)&stack_dummy;
|
||||
}
|
||||
|
||||
#if MICROPY_STACK_CHECK
|
||||
|
||||
void mp_stack_set_limit(mp_uint_t limit) {
|
||||
MP_STATE_VM(stack_limit) = limit;
|
||||
MP_STATE_THREAD(stack_limit) = limit;
|
||||
}
|
||||
|
||||
void mp_exc_recursion_depth(void) {
|
||||
|
@ -57,7 +57,7 @@ void mp_exc_recursion_depth(void) {
|
|||
}
|
||||
|
||||
void mp_stack_check(void) {
|
||||
if (mp_stack_usage() >= MP_STATE_VM(stack_limit)) {
|
||||
if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) {
|
||||
mp_exc_recursion_depth();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ void gc_collect(void) {
|
|||
void *sp = (void*)&dummy;
|
||||
|
||||
// trace the stack, including the registers (since they live on the stack in this function)
|
||||
gc_collect_root((void**)sp, ((uint32_t)MP_STATE_VM(stack_top) - (uint32_t)sp) / sizeof(uint32_t));
|
||||
gc_collect_root((void**)sp, ((uint32_t)MP_STATE_THREAD(stack_top) - (uint32_t)sp) / sizeof(uint32_t));
|
||||
|
||||
gc_collect_end();
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ void gc_collect(void) {
|
|||
gc_helper_get_regs(regs);
|
||||
// GC stack (and regs because we captured them)
|
||||
void **regs_ptr = (void**)(void*)®s;
|
||||
gc_collect_root(regs_ptr, ((uintptr_t)MP_STATE_VM(stack_top) - (uintptr_t)®s) / sizeof(uintptr_t));
|
||||
gc_collect_root(regs_ptr, ((uintptr_t)MP_STATE_THREAD(stack_top) - (uintptr_t)®s) / sizeof(uintptr_t));
|
||||
#if MICROPY_EMIT_NATIVE
|
||||
mp_unix_mark_exec();
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue