Add way to atomically check for new data, and wait otherwise (#2015)

This commit is contained in:
Thad House
2019-11-01 17:09:28 -07:00
committed by Peter Johnson
parent a769f1f227
commit 6f159d1426
3 changed files with 92 additions and 7 deletions

View File

@@ -338,12 +338,45 @@ void HAL_ObserveUserProgramTest(void) {
FRC_NetworkCommunication_observeUserProgramTest();
}
HAL_Bool HAL_IsNewControlData(void) {
static int& GetThreadLocalLastCount() {
// There is a rollover error condition here. At Packet# = n * (uintmax), this
// will return false when instead it should return true. However, this at a
// 20ms rate occurs once every 2.7 years of DS connected runtime, so not
// worth the cycles to check.
thread_local int lastCount{-1};
return lastCount;
}
void HAL_WaitForCachedControlData(void) {
HAL_WaitForCachedControlDataTimeout(0);
}
HAL_Bool HAL_WaitForCachedControlDataTimeout(double timeout) {
int& lastCount = GetThreadLocalLastCount();
std::unique_lock lock{*newDSDataAvailableMutex};
int currentCount = newDSDataAvailableCounter;
if (lastCount != currentCount) {
lastCount = currentCount;
return true;
}
auto timeoutTime =
std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
while (newDSDataAvailableCounter == currentCount) {
if (timeout > 0) {
auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
if (timedOut == std::cv_status::timeout) {
return false;
}
} else {
newDSDataAvailableCond->wait(lock);
}
}
return true;
}
HAL_Bool HAL_IsNewControlData(void) {
int& lastCount = GetThreadLocalLastCount();
std::lock_guard lock{*newDSDataAvailableMutex};
int currentCount = newDSDataAvailableCounter;
if (lastCount == currentCount) return false;