[hal,wpilib] Fix TimedRobot notifier race (#8445)

It was possible for the alarm to fire between the set alarm and ack,
resulting in a hang on next wait. It's not possible to ack before set
alarm due to a race in sim step timing, so the fix is to provide an
atomic ack and set alarm; the easiest way to implement this in the API
was to change ack to optionally also set the alarm again.
This commit is contained in:
Peter Johnson
2025-12-04 09:59:59 -07:00
committed by GitHub
parent d1b1703c86
commit 934f8d9c15
12 changed files with 147 additions and 78 deletions

View File

@@ -39,7 +39,7 @@ class Watchdog::Impl {
DerefGreater<Watchdog*>>
m_watchdogs;
void UpdateAlarm();
void UpdateAlarm(bool acknowledge = false);
private:
void Main();
@@ -67,7 +67,7 @@ Watchdog::Impl::~Impl() {
}
}
void Watchdog::Impl::UpdateAlarm() {
void Watchdog::Impl::UpdateAlarm(bool acknowledge) {
int32_t status = 0;
// Return if we are being destructed, or were not created successfully
auto notifier = m_notifier.load();
@@ -76,6 +76,12 @@ void Watchdog::Impl::UpdateAlarm() {
}
if (m_watchdogs.empty()) {
HAL_CancelNotifierAlarm(notifier, &status);
} else if (acknowledge) {
HAL_AcknowledgeNotifierAlarm(
notifier, true,
static_cast<uint64_t>(m_watchdogs.top()->m_expirationTime.value() *
1e6),
0, true, &status);
} else {
HAL_SetNotifierAlarm(notifier,
static_cast<uint64_t>(
@@ -125,9 +131,7 @@ void Watchdog::Impl::Main() {
watchdog->m_callback();
lock.lock();
UpdateAlarm();
HAL_AcknowledgeNotifierAlarm(notifier, &status);
UpdateAlarm(true);
}
}