mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[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:
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user