diff --git a/py/map.c b/py/map.c index d40e3dc4d0..f6efbcc085 100644 --- a/py/map.c +++ b/py/map.c @@ -32,6 +32,7 @@ #include "py/mpconfig.h" #include "py/misc.h" #include "py/runtime.h" +#include "py/mphal.h" #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) @@ -134,16 +135,28 @@ static void mp_map_rehash(mp_map_t *map) { DEBUG_printf("mp_map_rehash(%p): " UINT_FMT " -> " UINT_FMT "\n", map, old_alloc, new_alloc); mp_map_elem_t *old_table = map->table; mp_map_elem_t *new_table = m_new0(mp_map_elem_t, new_alloc); - // If we reach this point, table resizing succeeded, now we can edit the old map. - map->alloc = new_alloc; - map->used = 0; - map->all_keys_are_qstrs = 1; - map->table = new_table; + + // If we reach this point then allocating the new table succeeded, so construct the new map. + mp_map_t new_map = { + .all_keys_are_qstrs = 1, + .is_fixed = 0, + .is_ordered = 0, + .used = 0, + .alloc = new_alloc, + .table = new_table, + }; for (size_t i = 0; i < old_alloc; i++) { if (old_table[i].key != MP_OBJ_NULL && old_table[i].key != MP_OBJ_SENTINEL) { - mp_map_lookup(map, old_table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = old_table[i].value; + mp_map_lookup(&new_map, old_table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = old_table[i].value; } } + + // Swap the old map for the new one. + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + *map = new_map; + MICROPY_END_ATOMIC_SECTION(atomic_state); + + // Free the old table. m_del(mp_map_elem_t, old_table, old_alloc); } diff --git a/tests/thread/stress_globals.py b/tests/thread/stress_globals.py new file mode 100644 index 0000000000..fe2f77b9ef --- /dev/null +++ b/tests/thread/stress_globals.py @@ -0,0 +1,79 @@ +import time, _thread + + +def thread_task(): + for _ in range(1000): + a00 + print("pass") + + +print("start") +a00 = None + +_thread.start_new_thread(thread_task, ()) + +# create lots of global variables +a01 = None +a02 = None +a03 = None +a04 = None +a05 = None +a06 = None +a07 = None +a10 = None +a11 = None +a12 = None +a13 = None +a14 = None +a15 = None +a16 = None +a17 = None +a18 = None +a19 = None +a20 = None +a21 = None +a22 = None +a23 = None +a24 = None +a25 = None +a26 = None +a27 = None +a28 = None +a29 = None +a30 = None +a31 = None +a32 = None +a33 = None +a34 = None +a35 = None +a36 = None +a37 = None +a38 = None +a39 = None +a40 = None +a41 = None +a42 = None +a43 = None +a44 = None +a45 = None +a46 = None +a47 = None +a48 = None +a49 = None +a50 = None +a51 = None +a52 = None +a53 = None +a54 = None +a55 = None +a56 = None +a57 = None +a58 = None +a59 = None +a60 = None +a61 = None +a62 = None +a63 = None + +# let the thread finish +time.sleep(0.1)