mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[hal] Use atomic rather then mutex for DS Data updates (#4787)
Using an atomic here means we are never going against a lock that is touchable from user code. That should make reading the DS data from the DS callback even safer.
This commit is contained in:
@@ -44,7 +44,6 @@ struct JoystickDataCache {
|
||||
HAL_JoystickButtons buttons[kJoystickPorts];
|
||||
HAL_AllianceStationID allianceStation;
|
||||
double matchTime;
|
||||
bool updated;
|
||||
};
|
||||
static_assert(std::is_standard_layout_v<JoystickDataCache>);
|
||||
// static_assert(std::is_trivial_v<JoystickDataCache>);
|
||||
@@ -75,7 +74,9 @@ void JoystickDataCache::Update() {
|
||||
static HAL_ControlWord newestControlWord;
|
||||
static JoystickDataCache caches[3];
|
||||
static JoystickDataCache* currentRead = &caches[0];
|
||||
static JoystickDataCache* currentCache = &caches[1];
|
||||
static JoystickDataCache* currentReadLocal = &caches[0];
|
||||
static std::atomic<JoystickDataCache*> currentCache{&caches[1]};
|
||||
static JoystickDataCache* lastGiven = &caches[1];
|
||||
static JoystickDataCache* cacheToUpdate = &caches[2];
|
||||
|
||||
static ::FRCDriverStation* driverStation;
|
||||
@@ -330,9 +331,9 @@ void HAL_RefreshDSData(void) {
|
||||
controlWord.fmsAttached = SimDriverStationData->fmsAttached;
|
||||
controlWord.dsAttached = SimDriverStationData->dsAttached;
|
||||
std::scoped_lock lock{driverStation->cacheMutex};
|
||||
if (currentCache->updated) {
|
||||
std::swap(currentCache, currentRead);
|
||||
currentCache->updated = false;
|
||||
JoystickDataCache* prev = currentCache.exchange(nullptr);
|
||||
if (prev != nullptr) {
|
||||
currentRead = prev;
|
||||
}
|
||||
newestControlWord = controlWord;
|
||||
}
|
||||
@@ -368,11 +369,18 @@ void NewDriverStationData() {
|
||||
return;
|
||||
}
|
||||
cacheToUpdate->Update();
|
||||
{
|
||||
std::scoped_lock lock{driverStation->cacheMutex};
|
||||
std::swap(currentCache, cacheToUpdate);
|
||||
currentCache->updated = true;
|
||||
|
||||
JoystickDataCache* given = cacheToUpdate;
|
||||
JoystickDataCache* prev = currentCache.exchange(cacheToUpdate);
|
||||
if (prev == nullptr) {
|
||||
cacheToUpdate = currentReadLocal;
|
||||
currentReadLocal = lastGiven;
|
||||
} else {
|
||||
// Current read local does not update
|
||||
cacheToUpdate = prev;
|
||||
}
|
||||
lastGiven = given;
|
||||
|
||||
driverStation->newDataEvents.Wakeup();
|
||||
SimDriverStationData->CallNewDataCallbacks();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user