Skip to content

Commit e25fe94

Browse files
committed
py/map: Make map rehashing an atomic operation.
Signed-off-by: Damien George <damien@micropython.org>
1 parent 0000eb2 commit e25fe94

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

py/map.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,28 @@ STATIC void mp_map_rehash(mp_map_t *map) {
134134
DEBUG_printf("mp_map_rehash(%p): " UINT_FMT " -> " UINT_FMT "\n", map, old_alloc, new_alloc);
135135
mp_map_elem_t *old_table = map->table;
136136
mp_map_elem_t *new_table = m_new0(mp_map_elem_t, new_alloc);
137-
// If we reach this point, table resizing succeeded, now we can edit the old map.
138-
map->alloc = new_alloc;
139-
map->used = 0;
140-
map->all_keys_are_qstrs = 1;
141-
map->table = new_table;
137+
138+
// If we reach this point then allocating the new table succeeded, so construct the new map.
139+
mp_map_t new_map = {
140+
.all_keys_are_qstrs = 1,
141+
.is_fixed = 0,
142+
.is_ordered = 0,
143+
.used = 0,
144+
.alloc = new_alloc,
145+
.table = new_table,
146+
};
142147
for (size_t i = 0; i < old_alloc; i++) {
143148
if (old_table[i].key != MP_OBJ_NULL && old_table[i].key != MP_OBJ_SENTINEL) {
144-
mp_map_lookup(map, old_table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = old_table[i].value;
149+
mp_map_lookup(&new_map, old_table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = old_table[i].value;
145150
}
146151
}
152+
153+
// Swap the old map for the new one.
154+
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
155+
*map = new_map;
156+
MICROPY_END_ATOMIC_SECTION(atomic_state);
157+
158+
// Free the old table.
147159
m_del(mp_map_elem_t, old_table, old_alloc);
148160
}
149161

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