[hal,sim] Add notifier generation counter to WaitForProgramStart (#8947)

This fixes simulation WaitForProgramStart(true) potentially advancing
due to a stale or pre-start notifier created before SetProgramStarted()
was called.
This commit is contained in:
Peter Johnson
2026-06-06 12:17:14 -07:00
committed by GitHub
parent 6e5171cd8f
commit edf77fa007
3 changed files with 15 additions and 2 deletions

View File

@@ -21,6 +21,7 @@ static std::atomic<int64_t> programState{0};
static std::atomic<uint64_t> programStartTime{0};
static std::atomic<uint64_t> programPauseTime{0};
static std::atomic<uint64_t> programStepTime{0};
static std::atomic<uint64_t> 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);

View File

@@ -74,6 +74,7 @@ class NotifierInstance {
};
static NotifierInstance* notifierInstance;
static std::atomic<uint64_t> 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) {

View File

@@ -4,10 +4,13 @@
#pragma once
#include <stdint.h>
namespace wpi::hal {
void PauseNotifiers();
void ResumeNotifiers();
void WakeupNotifiers();
void WaitNotifiers();
void WakeupWaitNotifiers();
uint64_t GetNotifierAlarmSetCount();
} // namespace wpi::hal