From f305419ae1389650180a7aa546edece916bc5e18 Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Tue, 24 Dec 2024 21:50:39 +0100 Subject: [PATCH] Fix an issue where a timeout could be triggered immediately If a message arrived between `lopp_rec` and `wait_timeout`, the execution didn't resume to testing the received message but instead proceeded to the `timeout` opcode. As a result, a timeout occurred immediately. Signed-off-by: Paul Guyot --- CHANGELOG.md | 1 + src/libAtomVM/opcodesswitch.h | 14 +++++--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f01a21218..963e1d97f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ might lead to a crash in certain situations. - Fix corruption when dealing with specific situations that involve more than 16 x registers when certain VM instructions are used. - Fixed ESP32 GPIO interrupt trigger `none` +- Fixed an issue where a timeout would occur immediately in a race condition ## [0.6.5] - 2024-10-15 diff --git a/src/libAtomVM/opcodesswitch.h b/src/libAtomVM/opcodesswitch.h index 631ad8066c..f83dd1f604 100644 --- a/src/libAtomVM/opcodesswitch.h +++ b/src/libAtomVM/opcodesswitch.h @@ -2551,14 +2551,13 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) } if (needs_to_wait) { - ctx->saved_ip = saved_pc; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" ctx->restore_trap_handler = &&wait_timeout_trap_handler; #pragma GCC diagnostic pop - ctx->saved_module = mod; - ctx = scheduler_wait(ctx); - goto schedule_in; + SCHEDULE_WAIT(mod, saved_pc); + } else { + JUMP_TO_ADDRESS(mod->labels[label]); } #endif @@ -3193,10 +3192,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) if (LIKELY(remaining_reductions)) { JUMP_TO_ADDRESS(mod->labels[label]); } else { - ctx->saved_ip = mod->labels[label]; - ctx->saved_module = mod; - ctx = scheduler_next(ctx->global, ctx); - goto schedule_in; + SCHEDULE_NEXT(mod, mod->labels[label]); } #endif break; @@ -6394,7 +6390,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) case OP_RECV_MARKER_CLEAR: { DEST_REGISTER(reg_a); DECODE_DEST_REGISTER(reg_a, pc); - TRACE("recv_marker_clean/1: reg1=%c%i\n", T_DEST_REG(reg_a)); + TRACE("recv_marker_clear/1: reg1=%c%i\n", T_DEST_REG(reg_a)); break; }