diff options
Diffstat (limited to 'py/modthread.c')
-rw-r--r-- | py/modthread.c | 40 |
1 files changed, 16 insertions, 24 deletions
diff --git a/py/modthread.c b/py/modthread.c index 6f55281adc..d0e71dad3b 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -44,24 +44,19 @@ /****************************************************************/ // Lock object -// Note: with the GIL enabled we can easily synthesise a lock object STATIC const mp_obj_type_t mp_type_thread_lock; typedef struct _mp_obj_thread_lock_t { mp_obj_base_t base; - #if !MICROPY_PY_THREAD_GIL mp_thread_mutex_t mutex; - #endif volatile bool locked; } mp_obj_thread_lock_t; STATIC mp_obj_thread_lock_t *mp_obj_new_thread_lock(void) { mp_obj_thread_lock_t *self = m_new_obj(mp_obj_thread_lock_t); self->base.type = &mp_type_thread_lock; - #if !MICROPY_PY_THREAD_GIL mp_thread_mutex_init(&self->mutex); - #endif self->locked = false; return self; } @@ -73,20 +68,9 @@ STATIC mp_obj_t thread_lock_acquire(size_t n_args, const mp_obj_t *args) { wait = mp_obj_get_int(args[1]); // TODO support timeout arg } - #if MICROPY_PY_THREAD_GIL - if (self->locked) { - if (!wait) { - return mp_const_false; - } - do { - MP_THREAD_GIL_EXIT(); - MP_THREAD_GIL_ENTER(); - } while (self->locked); - } - self->locked = true; - return mp_const_true; - #else + MP_THREAD_GIL_EXIT(); int ret = mp_thread_mutex_lock(&self->mutex, wait); + MP_THREAD_GIL_ENTER(); if (ret == 0) { return mp_const_false; } else if (ret == 1) { @@ -95,7 +79,6 @@ STATIC mp_obj_t thread_lock_acquire(size_t n_args, const mp_obj_t *args) { } else { mp_raise_OSError(-ret); } - #endif } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(thread_lock_acquire_obj, 1, 3, thread_lock_acquire); @@ -103,9 +86,9 @@ STATIC mp_obj_t thread_lock_release(mp_obj_t self_in) { mp_obj_thread_lock_t *self = MP_OBJ_TO_PTR(self_in); // TODO check if already unlocked self->locked = false; - #if !MICROPY_PY_THREAD_GIL + MP_THREAD_GIL_EXIT(); mp_thread_mutex_unlock(&self->mutex); - #endif + MP_THREAD_GIL_ENTER(); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(thread_lock_release_obj, thread_lock_release); @@ -160,6 +143,8 @@ STATIC mp_obj_t mod_thread_stack_size(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_thread_stack_size_obj, 0, 1, mod_thread_stack_size); typedef struct _thread_entry_args_t { + mp_obj_dict_t *dict_locals; + mp_obj_dict_t *dict_globals; size_t stack_size; mp_obj_t fun; size_t n_args; @@ -178,6 +163,10 @@ STATIC void *thread_entry(void *args_in) { mp_stack_set_top(&ts + 1); // need to include ts in root-pointer scan mp_stack_set_limit(args->stack_size); + // set locals and globals from the calling context + mp_locals_set(args->dict_locals); + mp_globals_set(args->dict_globals); + MP_THREAD_GIL_ENTER(); // signal that we are set up and running @@ -186,7 +175,6 @@ STATIC void *thread_entry(void *args_in) { // TODO set more thread-specific state here: // mp_pending_exception? (root pointer) // cur_exception (root pointer) - // dict_locals? (root pointer) uPy doesn't make a new locals dict for functions, just for classes, so it's different to CPy DEBUG_printf("[thread] start ts=%p args=%p stack=%p\n", &ts, &args, MP_STATE_THREAD(stack_top)); @@ -227,7 +215,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) thread_entry_args_t *th_args; // get positional arguments - mp_uint_t pos_args_len; + size_t pos_args_len; mp_obj_t *pos_args_items; mp_obj_get_array(args[1], &pos_args_len, &pos_args_items); @@ -239,7 +227,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) } else { // positional and keyword arguments if (mp_obj_get_type(args[2]) != &mp_type_dict) { - mp_raise_msg(&mp_type_TypeError, "expecting a dict for keyword args"); + mp_raise_TypeError("expecting a dict for keyword args"); } mp_map_t *map = &((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[2]))->map; th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used); @@ -257,6 +245,10 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) th_args->n_args = pos_args_len; memcpy(th_args->args, pos_args_items, pos_args_len * sizeof(mp_obj_t)); + // pass our locals and globals into the new thread + th_args->dict_locals = mp_locals_get(); + th_args->dict_globals = mp_globals_get(); + // set the stack size to use th_args->stack_size = thread_stack_size; |