[hal] Notifier: simplify ack API (#8457)

Adding an ack parameter to both set and cancel is cleaner than adding
all the set alarm parameters to the ack function. It also provides an
ack-and-cancel method.
This commit is contained in:
Peter Johnson
2025-12-09 20:28:15 -07:00
committed by GitHub
parent 936be71a7d
commit 06a9a055b3
12 changed files with 111 additions and 177 deletions

View File

@@ -82,49 +82,45 @@ Java_org_wpilib_hardware_hal_NotifierJNI_destroyNotifier
/*
* Class: org_wpilib_hardware_hal_NotifierJNI
* Method: setNotifierAlarm
* Signature: (IJJZ)V
* Signature: (IJJZZ)V
*/
JNIEXPORT void JNICALL
Java_org_wpilib_hardware_hal_NotifierJNI_setNotifierAlarm
(JNIEnv* env, jclass cls, jint notifierHandle, jlong alarmTime,
jlong intervalTime, jboolean absolute)
jlong intervalTime, jboolean absolute, jboolean ack)
{
int32_t status = 0;
HAL_SetNotifierAlarm((HAL_NotifierHandle)notifierHandle,
static_cast<uint64_t>(alarmTime),
static_cast<uint64_t>(intervalTime), absolute, &status);
HAL_SetNotifierAlarm(
(HAL_NotifierHandle)notifierHandle, static_cast<uint64_t>(alarmTime),
static_cast<uint64_t>(intervalTime), absolute, ack, &status);
CheckStatus(env, status);
}
/*
* Class: org_wpilib_hardware_hal_NotifierJNI
* Method: cancelNotifierAlarm
* Signature: (I)V
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_org_wpilib_hardware_hal_NotifierJNI_cancelNotifierAlarm
(JNIEnv* env, jclass cls, jint notifierHandle)
(JNIEnv* env, jclass cls, jint notifierHandle, jboolean ack)
{
int32_t status = 0;
HAL_CancelNotifierAlarm((HAL_NotifierHandle)notifierHandle, &status);
HAL_CancelNotifierAlarm((HAL_NotifierHandle)notifierHandle, ack, &status);
CheckStatus(env, status);
}
/*
* Class: org_wpilib_hardware_hal_NotifierJNI
* Method: acknowledgeNotifierAlarm
* Signature: (IZJJZ)V
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_org_wpilib_hardware_hal_NotifierJNI_acknowledgeNotifierAlarm
(JNIEnv* env, jclass cls, jint notifierHandle, jboolean setAlarm,
jlong alarmTime, jlong intervalTime, jboolean absolute)
(JNIEnv* env, jclass cls, jint notifierHandle)
{
int32_t status = 0;
HAL_AcknowledgeNotifierAlarm((HAL_NotifierHandle)notifierHandle, setAlarm,
static_cast<uint64_t>(alarmTime),
static_cast<uint64_t>(intervalTime), absolute,
&status);
HAL_AcknowledgeNotifierAlarm((HAL_NotifierHandle)notifierHandle, &status);
CheckStatus(env, status);
}

View File

@@ -87,44 +87,34 @@ void HAL_DestroyNotifier(HAL_NotifierHandle notifierHandle);
* @param[in] alarmTime the first alarm time (in microseconds)
* @param[in] intervalTime the periodic interval time (in microseconds)
* @param[in] absolute true if the alarm time is absolute
* @param[in] ack true to acknowledge any prior alarm
* @param[out] status Error status variable. 0 on success.
*/
void HAL_SetNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t alarmTime,
uint64_t intervalTime, HAL_Bool absolute,
int32_t* status);
HAL_Bool ack, int32_t* status);
/**
* Cancels all future notifier alarms for a notifier.
*
* @param[in] notifierHandle the notifier handle
* @param[in] ack true to acknowledge any prior alarm
* @param[out] status Error status variable. 0 on success.
*/
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle, HAL_Bool ack,
int32_t* status);
/**
* Indicates the notifier alarm has been serviced and optionally sets a new
* alarm time. This must be called before waiting for the next alarm.
* Indicates the notifier alarm has been serviced. Makes no change to future
* alarms.
*
* The alarmTime is an absolute time (using the WPI_Now() time base) if
* absolute is true, or relative to the current time if absolute is false.
*
* If intervalTime is non-zero, the notifier will alarm periodically following
* alarmTime at the given interval.
*
* If an absolute alarmTime is in the past, the notifier will alarm immediately.
* One of HAL_SetNotifierAlarm (with ack=true), HAL_CancelNotifierAlarm (with
* ack=true), or this function must be called before waiting for the next alarm.
*
* @param[in] notifierHandle the notifier handle
* @param[in] setAlarm true to set a new alarm time, false to leave the
* alarm unchanged
* @param[in] alarmTime the first alarm time (in microseconds)
* @param[in] intervalTime the periodic interval time (in microseconds)
* @param[in] absolute true if the alarm time is absolute
* @param[out] status Error status variable. 0 on success.
*/
void HAL_AcknowledgeNotifierAlarm(HAL_NotifierHandle notifierHandle,
HAL_Bool setAlarm, uint64_t alarmTime,
uint64_t intervalTime, HAL_Bool absolute,
int32_t* status);
/**

View File

@@ -46,10 +46,6 @@ class NotifierThread : public wpi::util::SafeThread {
public:
void Main() override;
void SetAlarm(HAL_NotifierHandle notifierHandle,
std::shared_ptr<Notifier>& notifier, uint64_t alarmTime,
uint64_t intervalTime, bool absolute, int32_t* status);
void ProcessAlarms(wpi::util::SmallVectorImpl<HAL_NotifierHandle>* signaled);
bool m_paused = false;
@@ -115,30 +111,6 @@ void NotifierThread::Main() {
}
}
void NotifierThread::SetAlarm(HAL_NotifierHandle notifierHandle,
std::shared_ptr<Notifier>& notifier,
uint64_t alarmTime, uint64_t intervalTime,
bool absolute, int32_t* status) {
if (!absolute) {
alarmTime += HAL_GetFPGATime(status);
}
uint64_t prevWakeup = UINT64_MAX;
if (!m_alarmQueue.empty()) {
prevWakeup = m_alarmQueue.top().notifier->alarmTime;
m_alarmQueue.remove({notifierHandle, notifier});
}
notifier->alarmTime = alarmTime;
notifier->intervalTime = intervalTime;
notifier->overrunCount = 0;
m_alarmQueue.push({notifierHandle, notifier});
// wake up notifier thread if needed
if (alarmTime < prevWakeup) {
m_cond.notify_all();
}
}
void NotifierThread::ProcessAlarms(
wpi::util::SmallVectorImpl<HAL_NotifierHandle>* signaled) {
int32_t status = 0;
@@ -278,17 +250,38 @@ void HAL_DestroyNotifier(HAL_NotifierHandle notifierHandle) {
void HAL_SetNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t alarmTime,
uint64_t intervalTime, HAL_Bool absolute,
int32_t* status) {
HAL_Bool ack, int32_t* status) {
auto thr = notifierInstance->owner.GetThread();
auto notifier = thr->m_handles.Get(notifierHandle);
if (!notifier) {
return;
}
thr->SetAlarm(notifierHandle, notifier, alarmTime, intervalTime, absolute,
status);
if (ack) {
notifier->handlerSignaled.clear();
}
if (!absolute) {
alarmTime += HAL_GetFPGATime(status);
}
uint64_t prevWakeup = UINT64_MAX;
if (!thr->m_alarmQueue.empty()) {
prevWakeup = thr->m_alarmQueue.top().notifier->alarmTime;
thr->m_alarmQueue.remove({notifierHandle, notifier});
}
notifier->alarmTime = alarmTime;
notifier->intervalTime = intervalTime;
notifier->overrunCount = 0;
thr->m_alarmQueue.push({notifierHandle, notifier});
// wake up notifier thread if needed
if (alarmTime < prevWakeup) {
thr->m_cond.notify_all();
}
}
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle, HAL_Bool ack,
int32_t* status) {
auto thr = notifierInstance->owner.GetThread();
auto notifier = thr->m_handles.Get(notifierHandle);
@@ -296,14 +289,15 @@ void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
return;
}
if (ack) {
notifier->handlerSignaled.clear();
}
thr->m_alarmQueue.remove({notifierHandle, notifier});
notifier->alarmTime = UINT64_MAX;
notifier->handlerSignaled.clear();
}
void HAL_AcknowledgeNotifierAlarm(HAL_NotifierHandle notifierHandle,
HAL_Bool setAlarm, uint64_t alarmTime,
uint64_t intervalTime, HAL_Bool absolute,
int32_t* status) {
auto thr = notifierInstance->owner.GetThread();
auto notifier = thr->m_handles.Get(notifierHandle);
@@ -311,10 +305,6 @@ void HAL_AcknowledgeNotifierAlarm(HAL_NotifierHandle notifierHandle,
return;
}
notifier->handlerSignaled.clear();
if (setAlarm) {
thr->SetAlarm(notifierHandle, notifier, alarmTime, intervalTime, absolute,
status);
}
}
int32_t HAL_GetNotifierOverrun(HAL_NotifierHandle notifierHandle,

View File

@@ -39,10 +39,6 @@ class NotifierThread : public wpi::util::SafeThread {
public:
void Main() override;
void SetAlarm(HAL_NotifierHandle notifierHandle,
std::shared_ptr<Notifier>& notifier, uint64_t alarmTime,
uint64_t intervalTime, bool absolute, int32_t* status);
void ProcessAlarms();
UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
@@ -101,30 +97,6 @@ void NotifierThread::Main() {
}
}
void NotifierThread::SetAlarm(HAL_NotifierHandle notifierHandle,
std::shared_ptr<Notifier>& notifier,
uint64_t alarmTime, uint64_t intervalTime,
bool absolute, int32_t* status) {
if (!absolute) {
alarmTime += HAL_GetFPGATime(status);
}
uint64_t prevWakeup = UINT64_MAX;
if (!m_alarmQueue.empty()) {
prevWakeup = m_alarmQueue.top().notifier->alarmTime;
m_alarmQueue.remove({notifierHandle, notifier});
}
notifier->alarmTime = alarmTime;
notifier->intervalTime = intervalTime;
notifier->overrunCount = 0;
m_alarmQueue.push({notifierHandle, notifier});
// wake up notifier thread if needed
if (alarmTime < prevWakeup) {
m_cond.notify_all();
}
}
void NotifierThread::ProcessAlarms() {
int32_t status = 0;
uint64_t curTime = HAL_GetFPGATime(&status);
@@ -204,17 +176,38 @@ void HAL_DestroyNotifier(HAL_NotifierHandle notifierHandle) {
void HAL_SetNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t alarmTime,
uint64_t intervalTime, HAL_Bool absolute,
int32_t* status) {
HAL_Bool ack, int32_t* status) {
auto thr = notifierInstance->owner.GetThread();
auto notifier = thr->m_handles.Get(notifierHandle);
if (!notifier) {
return;
}
thr->SetAlarm(notifierHandle, notifier, alarmTime, intervalTime, absolute,
status);
if (ack) {
notifier->handlerSignaled.clear();
}
if (!absolute) {
alarmTime += HAL_GetFPGATime(status);
}
uint64_t prevWakeup = UINT64_MAX;
if (!thr->m_alarmQueue.empty()) {
prevWakeup = thr->m_alarmQueue.top().notifier->alarmTime;
thr->m_alarmQueue.remove({notifierHandle, notifier});
}
notifier->alarmTime = alarmTime;
notifier->intervalTime = intervalTime;
notifier->overrunCount = 0;
thr->m_alarmQueue.push({notifierHandle, notifier});
// wake up notifier thread if needed
if (alarmTime < prevWakeup) {
thr->m_cond.notify_all();
}
}
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle, HAL_Bool ack,
int32_t* status) {
auto thr = notifierInstance->owner.GetThread();
auto notifier = thr->m_handles.Get(notifierHandle);
@@ -222,14 +215,15 @@ void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
return;
}
if (ack) {
notifier->handlerSignaled.clear();
}
thr->m_alarmQueue.remove({notifierHandle, notifier});
notifier->alarmTime = UINT64_MAX;
notifier->handlerSignaled.clear();
}
void HAL_AcknowledgeNotifierAlarm(HAL_NotifierHandle notifierHandle,
HAL_Bool setAlarm, uint64_t alarmTime,
uint64_t intervalTime, HAL_Bool absolute,
int32_t* status) {
auto thr = notifierInstance->owner.GetThread();
auto notifier = thr->m_handles.Get(notifierHandle);
@@ -237,10 +231,6 @@ void HAL_AcknowledgeNotifierAlarm(HAL_NotifierHandle notifierHandle,
return;
}
notifier->handlerSignaled.clear();
if (setAlarm) {
thr->SetAlarm(notifierHandle, notifier, alarmTime, intervalTime, absolute,
status);
}
}
int32_t HAL_GetNotifierOverrun(HAL_NotifierHandle notifierHandle,