Skip to content

Commit

Permalink
py: Add MP_STATE_THREAD to hold state specific to a given thread.
Browse files Browse the repository at this point in the history
  • Loading branch information
dpgeorge committed Jun 28, 2016
1 parent 3545ef8 commit 330165a
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 26 deletions.
2 changes: 1 addition & 1 deletion mpy-cross/gccollect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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*)&regs;
gc_collect_root(regs_ptr, ((mp_uint_t)MP_STATE_VM(stack_top) - (mp_uint_t)&regs) / sizeof(mp_uint_t));
gc_collect_root(regs_ptr, ((mp_uint_t)MP_STATE_THREAD(stack_top) - (mp_uint_t)&regs) / sizeof(mp_uint_t));
#if MICROPY_EMIT_NATIVE
mp_unix_mark_exec();
#endif
Expand Down
4 changes: 2 additions & 2 deletions pic16bit/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ int main(int argc, char **argv) {

// 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();
Expand Down Expand Up @@ -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();
}

Expand Down
4 changes: 2 additions & 2 deletions py/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion py/modmicropython.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 20 additions & 13 deletions py/mpstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -177,15 +166,31 @@ 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.
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;
Expand All @@ -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__
10 changes: 5 additions & 5 deletions py/stackctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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();
}
}
Expand Down
2 changes: 1 addition & 1 deletion qemu-arm/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion unix/gccollect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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*)&regs;
gc_collect_root(regs_ptr, ((uintptr_t)MP_STATE_VM(stack_top) - (uintptr_t)&regs) / sizeof(uintptr_t));
gc_collect_root(regs_ptr, ((uintptr_t)MP_STATE_THREAD(stack_top) - (uintptr_t)&regs) / sizeof(uintptr_t));
#if MICROPY_EMIT_NATIVE
mp_unix_mark_exec();
#endif
Expand Down

0 comments on commit 330165a

Please sign in to comment.