diff options
author | Damien George <damien.p.george@gmail.com> | 2016-05-05 10:25:08 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2016-06-28 11:28:49 +0100 |
commit | 3653f5144a9ad719f70e2d310e218cf724afc822 (patch) | |
tree | 1d003f9eb5779eec4ab40441965d75ad9a921aa4 /py | |
parent | dbd54e0b5bf50c42127b8f55a873e466cef2e0b7 (diff) | |
download | micropython-3653f5144a9ad719f70e2d310e218cf724afc822.tar.gz micropython-3653f5144a9ad719f70e2d310e218cf724afc822.zip |
py/gc: Fix GC+thread bug where ptr gets lost because it's not computed.
GC_EXIT() can cause a pending thread (waiting on the mutex) to be
scheduled right away. This other thread may trigger a garbage
collection. If the pointer to the newly-allocated block (allocated by
the original thread) is not computed before the switch (so it's just left
as a block number) then the block will be wrongly reclaimed.
This patch makes sure the pointer is computed before allowing any thread
switch to occur.
Diffstat (limited to 'py')
-rw-r--r-- | py/gc.c | 5 |
1 files changed, 3 insertions, 2 deletions
@@ -434,12 +434,13 @@ found: ATB_FREE_TO_TAIL(bl); } - GC_EXIT(); - // get pointer to first block + // we must create this pointer before unlocking the GC so a collection can find it void *ret_ptr = (void*)(MP_STATE_MEM(gc_pool_start) + start_block * BYTES_PER_BLOCK); DEBUG_printf("gc_alloc(%p)\n", ret_ptr); + GC_EXIT(); + // zero out the additional bytes of the newly allocated blocks // This is needed because the blocks may have previously held pointers // to the heap and will not be set to something else if the caller |