static void alarmCallback(uint32_t, void*) { std::unique_lock<priority_recursive_mutex> sync(notifierMutex); int32_t status = 0; uint64_t currentTime = 0; // the hardware disables itself after each alarm closestTrigger = UINT64_MAX; // process all notifiers Notifier *notifier = notifiers; while (notifier) { if (notifier->triggerTime != UINT64_MAX) { if (currentTime == 0) currentTime = getFPGATime(&status); if (notifier->triggerTime < currentTime) { notifier->triggerTime = UINT64_MAX; auto process = notifier->process; auto param = notifier->param; sync.unlock(); process(currentTime, param); sync.lock(); } else if (notifier->triggerTime < closestTrigger) { updateNotifierAlarm(notifier, notifier->triggerTime, &status); } } notifier = notifier->next; } }
/** * Update the alarm hardware to reflect the current first element in the queue. * Compute the time the next alarm should occur based on the current time and the * period for the first element in the timer queue. * WARNING: this method does not do synchronization! It must be called from somewhere * that is taking care of synchronizing access to the queue. */ void Notifier::UpdateAlarm() { if (timerQueueHead != NULL) { int32_t status = 0; updateNotifierAlarm(m_notifier, (uint32_t)(timerQueueHead->m_expirationTime * 1e6), &status); wpi_setStaticErrorWithContext(timerQueueHead, status, getHALErrorMessage(status)); } }
/** * Update the alarm hardware to reflect the current first element in the queue. * Compute the time the next alarm should occur based on the current time and * the * period for the first element in the timer queue. * WARNING: this method does not do synchronization! It must be called from * somewhere * that is taking care of synchronizing access to the queue. */ void Notifier::UpdateAlarm() { if (timerQueueHead != nullptr) { int32_t status = 0; // This locking is necessary in order to avoid two things: // 1) Race condition issues with calling cleanNotifer() and // updateNotifierAlarm() at the same time. // 2) Avoid deadlock by making it so that this won't block waiting // for the mutex to unlock. // Checking refcount as well is unnecessary, but will not hurt. if (halMutex.try_lock() && refcount != 0) { if (m_notifier) updateNotifierAlarm(m_notifier, (uint32_t)(timerQueueHead->m_expirationTime * 1e6), &status); halMutex.unlock(); } wpi_setStaticErrorWithContext(timerQueueHead, status, getHALErrorMessage(status)); } }