From b153bc81f0f206fdf99afad3fd8fbd37f7ca15f6 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 12 Oct 2023 08:50:50 +0100 Subject: [PATCH] Bugfix: Rp2040 `os_timer_setfn()` can stall other timers. (#2672) If called on first timer in queue then subsequent timers get disconnected. Must explicitly `disarm` the timer first so it's properly removed from queue. This is consistent with esp8266 behaviour. Also applied to host timer from whence the code originated. This bug might explain root cause of #2594, where code hangs during intensive timer usage. Specifically, this issue gets triggered if attempting to change the callback on an active timer. (If the timer is inactive then it's not in the queue so doesn't matter.) --- Sming/Arch/Host/Components/driver/os_timer.cpp | 9 +++++---- Sming/Arch/Rp2040/Components/driver/os_timer.cpp | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Sming/Arch/Host/Components/driver/os_timer.cpp b/Sming/Arch/Host/Components/driver/os_timer.cpp index ec80e5237d..e546c35256 100644 --- a/Sming/Arch/Host/Components/driver/os_timer.cpp +++ b/Sming/Arch/Host/Components/driver/os_timer.cpp @@ -93,11 +93,12 @@ void os_timer_disarm(struct os_timer_t* ptimer) void os_timer_setfn(struct os_timer_t* ptimer, os_timer_func_t* pfunction, void* parg) { - if(ptimer != nullptr) { - ptimer->timer_func = pfunction; - ptimer->timer_arg = parg; - ptimer->timer_next = reinterpret_cast(-1); + if(ptimer == nullptr) { + return; } + os_timer_disarm(ptimer); + ptimer->timer_func = pfunction; + ptimer->timer_arg = parg; } void os_timer_done(struct os_timer_t* ptimer) diff --git a/Sming/Arch/Rp2040/Components/driver/os_timer.cpp b/Sming/Arch/Rp2040/Components/driver/os_timer.cpp index ee8312357a..b524d56ceb 100644 --- a/Sming/Arch/Rp2040/Components/driver/os_timer.cpp +++ b/Sming/Arch/Rp2040/Components/driver/os_timer.cpp @@ -173,11 +173,12 @@ void IRAM_ATTR os_timer_disarm(struct os_timer_t* ptimer) void os_timer_setfn(struct os_timer_t* ptimer, os_timer_func_t* pfunction, void* parg) { - if(ptimer != nullptr) { - ptimer->timer_func = pfunction; - ptimer->timer_arg = parg; - ptimer->timer_next = reinterpret_cast(-1); + if(ptimer == nullptr) { + return; } + os_timer_disarm(ptimer); + ptimer->timer_func = pfunction; + ptimer->timer_arg = parg; } void os_timer_done(struct os_timer_t* ptimer)