diff --git a/hal/src/main/native/sim/MockHooks.cpp b/hal/src/main/native/sim/MockHooks.cpp index f94bfd8766..b05a302ca1 100644 --- a/hal/src/main/native/sim/MockHooks.cpp +++ b/hal/src/main/native/sim/MockHooks.cpp @@ -21,6 +21,7 @@ static std::atomic programState{0}; static std::atomic programStartTime{0}; static std::atomic programPauseTime{0}; static std::atomic programStepTime{0}; +static std::atomic programStartNotifierAlarmCount{0}; namespace wpi::hal::init { void InitializeMockHooks() { @@ -67,6 +68,7 @@ uint64_t GetMonotonicTime() { } void SetProgramStarted(bool started) { + programStartNotifierAlarmCount = GetNotifierAlarmSetCount(); programStarted = started; } bool GetProgramStarted() { @@ -88,9 +90,11 @@ void HALSIM_WaitForProgramStart(HAL_Bool waitForFirstNotifier) { } // Frameworks observe program start before arming their first notifier alarm. - // Wait for that alarm so a following StepTiming() can see and service it. + // Wait for an alarm armed after that program-start edge so a stale notifier + // cannot satisfy this check. while (waitForFirstNotifier && - HALSIM_GetNextNotifierTimeout() == UINT64_MAX) { + (GetNotifierAlarmSetCount() == programStartNotifierAlarmCount || + HALSIM_GetNextNotifierTimeout() == UINT64_MAX)) { count++; if (count % 10 == 0) { wpi::util::print("Waiting for first notifier alarm: {}\n", count); diff --git a/hal/src/main/native/sim/Notifier.cpp b/hal/src/main/native/sim/Notifier.cpp index e7f7066cc0..89e9140747 100644 --- a/hal/src/main/native/sim/Notifier.cpp +++ b/hal/src/main/native/sim/Notifier.cpp @@ -74,6 +74,7 @@ class NotifierInstance { }; static NotifierInstance* notifierInstance; +static std::atomic notifierAlarmSetCount{0}; namespace wpi::hal::init { void InitializeNotifier() { @@ -209,6 +210,10 @@ void wpi::hal::WakeupWaitNotifiers() { DoWaitNotifiers(thr, signaled); } +uint64_t wpi::hal::GetNotifierAlarmSetCount() { + return notifierAlarmSetCount; +} + extern "C" { HAL_NotifierHandle HAL_CreateNotifier(int32_t* status) { @@ -268,6 +273,7 @@ void HAL_SetNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t alarmTime, notifier->intervalTime = intervalTime; notifier->overrunCount = 0; thr->m_alarmQueue.push({notifierHandle, notifier}); + ++notifierAlarmSetCount; // wake up notifier thread if needed if (alarmTime < prevWakeup) { diff --git a/hal/src/main/native/sim/NotifierInternal.hpp b/hal/src/main/native/sim/NotifierInternal.hpp index 7c02082381..204d30a209 100644 --- a/hal/src/main/native/sim/NotifierInternal.hpp +++ b/hal/src/main/native/sim/NotifierInternal.hpp @@ -4,10 +4,13 @@ #pragma once +#include + namespace wpi::hal { void PauseNotifiers(); void ResumeNotifiers(); void WakeupNotifiers(); void WaitNotifiers(); void WakeupWaitNotifiers(); +uint64_t GetNotifierAlarmSetCount(); } // namespace wpi::hal