From 9aab33c2e99e8dc134fdb7029c257c0c31649f84 Mon Sep 17 00:00:00 2001 From: Terraneo Federico <fede.tft@miosix.org> Date: Thu, 27 Apr 2023 01:04:51 +0200 Subject: [PATCH] Prevent spurious wakeup in Semaphore --- miosix/kernel/sync.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/miosix/kernel/sync.cpp b/miosix/kernel/sync.cpp index 5d66ed60..b7cc79b9 100644 --- a/miosix/kernel/sync.cpp +++ b/miosix/kernel/sync.cpp @@ -454,6 +454,7 @@ Thread *Semaphore::IRQsignalNoPreempt() } WaitToken *cd=fifo.front(); Thread *t=cd->thread; + cd->thread=nullptr; //Thread pointer doubles as flag against spurious wakeup fifo.pop_front(); t->IRQwakeup(); return t; @@ -500,8 +501,8 @@ void Semaphore::wait() //Otherwise put ourselves in queue and wait WaitToken listItem(Thread::IRQgetCurrentThread()); fifo.push_back(&listItem); //Add entry to tail of list - Thread::IRQenableIrqAndWait(dLock); - fifo.removeFast(&listItem); //In case of spurious wakeup + while(listItem.thread) Thread::IRQenableIrqAndWait(dLock); + //Spurious wakeup handled by while loop, listItem already removed from fifo } TimedWaitResult Semaphore::timedWait(long long absTime) @@ -517,9 +518,15 @@ TimedWaitResult Semaphore::timedWait(long long absTime) //Otherwise put ourselves in queue and wait WaitToken listItem(Thread::IRQgetCurrentThread()); fifo.push_back(&listItem); //Add entry to tail of list - auto result=Thread::IRQenableIrqAndTimedWait(dLock,absTime); - fifo.removeFast(&listItem); //In case of timeout or spurious wakeup - return result; + while(listItem.thread) + { + if(Thread::IRQenableIrqAndTimedWait(dLock,absTime)==TimedWaitResult::Timeout) + { + fifo.removeFast(&listItem); //Remove fifo entry in case of timeout + return TimedWaitResult::Timeout; + } + } + return TimedWaitResult::NoTimeout; } } //namespace miosix -- GitLab