diff --git a/hal/src/main/native/athena/AnalogInput.cpp b/hal/src/main/native/athena/AnalogInput.cpp index 59a534da7e..1aa9d8ddcb 100644 --- a/hal/src/main/native/athena/AnalogInput.cpp +++ b/hal/src/main/native/athena/AnalogInput.cpp @@ -14,7 +14,6 @@ #include "AnalogInternal.h" #include "HAL/AnalogAccumulator.h" #include "HAL/HAL.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" #include "PortsInternal.h" @@ -231,7 +230,7 @@ int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle, readSelect.Channel = port->channel; readSelect.Averaged = false; - std::lock_guard sync(analogRegisterWindowMutex); + std::lock_guard sync(analogRegisterWindowMutex); analogInputSystem->writeReadSelect(readSelect, status); analogInputSystem->strobeLatchOutput(status); return static_cast(analogInputSystem->readOutput(status)); @@ -262,7 +261,7 @@ int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle, readSelect.Channel = port->channel; readSelect.Averaged = true; - std::lock_guard sync(analogRegisterWindowMutex); + std::lock_guard sync(analogRegisterWindowMutex); analogInputSystem->writeReadSelect(readSelect, status); analogInputSystem->strobeLatchOutput(status); return static_cast(analogInputSystem->readOutput(status)); diff --git a/hal/src/main/native/athena/AnalogInternal.cpp b/hal/src/main/native/athena/AnalogInternal.cpp index 87e7933bfa..8a81bea257 100644 --- a/hal/src/main/native/athena/AnalogInternal.cpp +++ b/hal/src/main/native/athena/AnalogInternal.cpp @@ -8,15 +8,15 @@ #include "AnalogInternal.h" #include +#include #include "HAL/AnalogInput.h" #include "HAL/ChipObject.h" -#include "HAL/cpp/priority_mutex.h" #include "PortsInternal.h" namespace hal { -priority_recursive_mutex analogRegisterWindowMutex; +std::mutex analogRegisterWindowMutex; std::unique_ptr analogInputSystem; std::unique_ptr analogOutputSystem; @@ -35,7 +35,7 @@ bool analogSampleRateSet = false; */ void initializeAnalog(int32_t* status) { if (analogSystemInitialized) return; - std::lock_guard sync(analogRegisterWindowMutex); + std::lock_guard sync(analogRegisterWindowMutex); if (analogSystemInitialized) return; analogInputSystem.reset(tAI::create(status)); analogOutputSystem.reset(tAO::create(status)); diff --git a/hal/src/main/native/athena/AnalogInternal.h b/hal/src/main/native/athena/AnalogInternal.h index 567c1b9a0a..af38a0226d 100644 --- a/hal/src/main/native/athena/AnalogInternal.h +++ b/hal/src/main/native/athena/AnalogInternal.h @@ -10,10 +10,10 @@ #include #include +#include #include "HAL/ChipObject.h" #include "HAL/Ports.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/IndexedHandleResource.h" #include "PortsInternal.h" @@ -27,7 +27,7 @@ static const uint32_t kAccumulatorChannels[] = {0, 1}; extern std::unique_ptr analogInputSystem; extern std::unique_ptr analogOutputSystem; -extern priority_recursive_mutex analogRegisterWindowMutex; +extern std::mutex analogRegisterWindowMutex; extern bool analogSampleRateSet; struct AnalogPort { diff --git a/hal/src/main/native/athena/DIO.cpp b/hal/src/main/native/athena/DIO.cpp index 72863cbbfe..0e2e18aacd 100644 --- a/hal/src/main/native/athena/DIO.cpp +++ b/hal/src/main/native/athena/DIO.cpp @@ -17,7 +17,7 @@ using namespace hal; // Create a mutex to protect changes to the digital output values -static priority_recursive_mutex digitalDIOMutex; +static std::mutex digitalDIOMutex; static LimitedHandleResource @@ -54,7 +54,7 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle, port->channel = static_cast(channel); - std::lock_guard sync(digitalDIOMutex); + std::lock_guard sync(digitalDIOMutex); tDIO::tOutputEnable outputEnable = digitalSystem->readOutputEnable(status); @@ -115,7 +115,7 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) { digitalChannelHandles.Free(dioPortHandle, HAL_HandleEnum::DIO); if (port == nullptr) return; int32_t status = 0; - std::lock_guard sync(digitalDIOMutex); + std::lock_guard sync(digitalDIOMutex); if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) { // Unset the SPI flag int32_t bitToUnset = 1 << remapSPIChannel(port->channel); @@ -205,7 +205,7 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator, double rawDutyCycle = 256.0 * dutyCycle; if (rawDutyCycle > 255.5) rawDutyCycle = 255.5; { - std::lock_guard sync(digitalPwmMutex); + std::lock_guard sync(digitalPwmMutex); uint16_t pwmPeriodPower = digitalSystem->readPWMPeriodPower(status); if (pwmPeriodPower < 4) { // The resolution of the duty cycle drops close to the highest @@ -265,7 +265,7 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value, if (value != 0) value = 1; } { - std::lock_guard sync(digitalDIOMutex); + std::lock_guard sync(digitalDIOMutex); tDIO::tDO currentDIO = digitalSystem->readDO(status); if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) { @@ -437,7 +437,7 @@ void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex, return; } - std::lock_guard sync(digitalDIOMutex); + std::lock_guard sync(digitalDIOMutex); if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) { // Channels 10-15 are SPI channels, so subtract our MXP channels digitalSystem->writeFilterSelectHdr(port->channel - kNumDigitalMXPChannels, @@ -465,7 +465,7 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) { return 0; } - std::lock_guard sync(digitalDIOMutex); + std::lock_guard sync(digitalDIOMutex); if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) { // Channels 10-15 are SPI channels, so subtract our MXP channels return digitalSystem->readFilterSelectHdr( @@ -492,7 +492,7 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) { void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) { initializeDigital(status); if (*status != 0) return; - std::lock_guard sync(digitalDIOMutex); + std::lock_guard sync(digitalDIOMutex); digitalSystem->writeFilterPeriodHdr(filterIndex, value, status); if (*status == 0) { digitalSystem->writeFilterPeriodMXP(filterIndex, value, status); @@ -517,7 +517,7 @@ int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) { uint32_t hdrPeriod = 0; uint32_t mxpPeriod = 0; { - std::lock_guard sync(digitalDIOMutex); + std::lock_guard sync(digitalDIOMutex); hdrPeriod = digitalSystem->readFilterPeriodHdr(filterIndex, status); if (*status == 0) { mxpPeriod = digitalSystem->readFilterPeriodMXP(filterIndex, status); diff --git a/hal/src/main/native/athena/DigitalInternal.cpp b/hal/src/main/native/athena/DigitalInternal.cpp index 6dca5c4d3c..f04a618591 100644 --- a/hal/src/main/native/athena/DigitalInternal.cpp +++ b/hal/src/main/native/athena/DigitalInternal.cpp @@ -18,13 +18,12 @@ #include "HAL/ChipObject.h" #include "HAL/HAL.h" #include "HAL/Ports.h" -#include "HAL/cpp/priority_mutex.h" #include "PortsInternal.h" namespace hal { // Create a mutex to protect changes to the DO PWM config -priority_recursive_mutex digitalPwmMutex; +std::mutex digitalPwmMutex; std::unique_ptr digitalSystem; std::unique_ptr relaySystem; @@ -32,7 +31,7 @@ std::unique_ptr pwmSystem; std::unique_ptr spiSystem; static std::atomic digitalSystemsInitialized{false}; -static hal::priority_mutex initializeMutex; +static std::mutex initializeMutex; DigitalHandleResource @@ -45,7 +44,7 @@ void initializeDigital(int32_t* status) { // Initial check, as if it's true initialization has finished if (digitalSystemsInitialized) return; - std::lock_guard lock(initializeMutex); + std::lock_guard lock(initializeMutex); // Second check in case another thread was waiting if (digitalSystemsInitialized) return; diff --git a/hal/src/main/native/athena/DigitalInternal.h b/hal/src/main/native/athena/DigitalInternal.h index f17168e31e..582ca492ea 100644 --- a/hal/src/main/native/athena/DigitalInternal.h +++ b/hal/src/main/native/athena/DigitalInternal.h @@ -10,6 +10,7 @@ #include #include +#include #include "HAL/AnalogTrigger.h" #include "HAL/ChipObject.h" @@ -58,7 +59,7 @@ constexpr int32_t kDefaultPwmStepsDown = 1000; constexpr int32_t kPwmDisabled = 0; // Create a mutex to protect changes to the DO PWM config -extern priority_recursive_mutex digitalPwmMutex; +extern std::mutex digitalPwmMutex; extern std::unique_ptr digitalSystem; extern std::unique_ptr relaySystem; diff --git a/hal/src/main/native/athena/FRCDriverStation.cpp b/hal/src/main/native/athena/FRCDriverStation.cpp index 438e321003..08eab3ad5b 100644 --- a/hal/src/main/native/athena/FRCDriverStation.cpp +++ b/hal/src/main/native/athena/FRCDriverStation.cpp @@ -7,16 +7,16 @@ #include #include +#include #include #include #include +#include #include #include #include "HAL/DriverStation.h" -#include "HAL/cpp/priority_condition_variable.h" -#include "HAL/cpp/priority_mutex.h" static_assert(sizeof(int32_t) >= sizeof(int), "FRC_NetworkComm status variable is larger than 32 bits"); @@ -26,9 +26,9 @@ struct HAL_JoystickAxesInt { int16_t axes[HAL_kMaxJoystickAxes]; }; -static hal::priority_mutex msgMutex; -static hal::priority_condition_variable newDSDataAvailableCond; -static hal::priority_mutex newDSDataAvailableMutex; +static std::mutex msgMutex; +static std::condition_variable newDSDataAvailableCond; +static std::mutex newDSDataAvailableMutex; static int newDSDataAvailableCounter{0}; extern "C" { @@ -44,7 +44,7 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode, // Avoid flooding console by keeping track of previous 5 error // messages and only printing again if they're longer than 1 second old. static constexpr int KEEP_MSGS = 5; - std::lock_guard lock(msgMutex); + std::lock_guard lock(msgMutex); static std::string prevMsg[KEEP_MSGS]; static std::chrono::time_point prevMsgTime[KEEP_MSGS]; @@ -258,7 +258,7 @@ bool HAL_IsNewControlData(void) { thread_local int lastCount{-1}; int currentCount = 0; { - std::unique_lock lock(newDSDataAvailableMutex); + std::unique_lock lock(newDSDataAvailableMutex); currentCount = newDSDataAvailableCounter; } if (lastCount == currentCount) return false; @@ -280,7 +280,7 @@ HAL_Bool HAL_WaitForDSDataTimeout(double timeout) { auto timeoutTime = std::chrono::steady_clock::now() + std::chrono::duration(timeout); - std::unique_lock lock(newDSDataAvailableMutex); + std::unique_lock lock(newDSDataAvailableMutex); int currentCount = newDSDataAvailableCounter; while (newDSDataAvailableCounter == currentCount) { if (timeout > 0) { @@ -306,7 +306,7 @@ static int32_t newDataOccur(uint32_t refNum) { // Since we could get other values, require our specific handle // to signal our threads if (refNum != refNumber) return 0; - std::lock_guard lock(newDSDataAvailableMutex); + std::lock_guard lock(newDSDataAvailableMutex); // Nofify all threads newDSDataAvailableCounter++; newDSDataAvailableCond.notify_all(); @@ -320,11 +320,11 @@ static int32_t newDataOccur(uint32_t refNum) { */ void HAL_InitializeDriverStation(void) { static std::atomic_bool initialized{false}; - static hal::priority_mutex initializeMutex; + static std::mutex initializeMutex; // Initial check, as if it's true initialization has finished if (initialized) return; - std::lock_guard lock(initializeMutex); + std::lock_guard lock(initializeMutex); // Second check in case another thread was waiting if (initialized) return; diff --git a/hal/src/main/native/athena/HAL.cpp b/hal/src/main/native/athena/HAL.cpp index ac5087a28d..7c26dc76bb 100644 --- a/hal/src/main/native/athena/HAL.cpp +++ b/hal/src/main/native/athena/HAL.cpp @@ -26,7 +26,6 @@ #include "HAL/Errors.h" #include "HAL/Notifier.h" #include "HAL/cpp/NotifierInternal.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" #include "ctre/ctre.h" #include "visa/visa.h" @@ -36,7 +35,7 @@ using namespace hal; static std::unique_ptr global; static std::unique_ptr watchdog; -static hal::priority_mutex timeMutex; +static std::mutex timeMutex; static uint32_t timeEpoch = 0; static uint32_t prevFPGATime = 0; static HAL_NotifierHandle rolloverNotifier = 0; @@ -225,7 +224,7 @@ uint64_t HAL_GetFPGATime(int32_t* status) { *status = NiFpga_Status_ResourceNotInitialized; return 0; } - std::lock_guard lock(timeMutex); + std::lock_guard lock(timeMutex); uint32_t fpgaTime = global->readLocalTime(status); if (*status != 0) return 0; // check for rollover @@ -271,11 +270,11 @@ static void timerRollover(uint64_t currentTime, HAL_NotifierHandle handle) { void HAL_BaseInitialize(int32_t* status) { static std::atomic_bool initialized{false}; - static hal::priority_mutex initializeMutex; + static std::mutex initializeMutex; // Initial check, as if it's true initialization has finished if (initialized) return; - std::lock_guard lock(initializeMutex); + std::lock_guard lock(initializeMutex); // Second check in case another thread was waiting if (initialized) return; // image 4; Fixes errors caused by multiple processes. Talk to NI about this diff --git a/hal/src/main/native/athena/I2C.cpp b/hal/src/main/native/athena/I2C.cpp index c522419abc..3e97643e75 100644 --- a/hal/src/main/native/athena/I2C.cpp +++ b/hal/src/main/native/athena/I2C.cpp @@ -15,8 +15,8 @@ using namespace hal; -static priority_recursive_mutex digitalI2COnBoardMutex; -static priority_recursive_mutex digitalI2CMXPMutex; +static std::mutex digitalI2COnBoardMutex; +static std::mutex digitalI2CMXPMutex; static uint8_t i2COnboardObjCount = 0; static uint8_t i2CMXPObjCount = 0; @@ -42,10 +42,9 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) { return; } - priority_recursive_mutex& lock = - port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; + std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; { - std::lock_guard sync(lock); + std::lock_guard sync(lock); if (port == 0) { i2COnboardObjCount++; if (i2COnBoardHandle > 0) return; @@ -91,11 +90,10 @@ int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress, } int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle; - priority_recursive_mutex& lock = - port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; + std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; { - std::lock_guard sync(lock); + std::lock_guard sync(lock); return i2clib_writeread( handle, deviceAddress, reinterpret_cast(dataToSend), static_cast(sendSize), reinterpret_cast(dataReceived), @@ -122,10 +120,9 @@ int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress, } int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle; - priority_recursive_mutex& lock = - port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; + std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; { - std::lock_guard sync(lock); + std::lock_guard sync(lock); return i2clib_write(handle, deviceAddress, reinterpret_cast(dataToSend), sendSize); } @@ -152,10 +149,9 @@ int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer, } int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle; - priority_recursive_mutex& lock = - port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; + std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; { - std::lock_guard sync(lock); + std::lock_guard sync(lock); return i2clib_read(handle, deviceAddress, reinterpret_cast(buffer), static_cast(count)); } @@ -166,10 +162,9 @@ void HAL_CloseI2C(HAL_I2CPort port) { // Set port out of range error here return; } - priority_recursive_mutex& lock = - port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; + std::mutex& lock = port == 0 ? digitalI2COnBoardMutex : digitalI2CMXPMutex; { - std::lock_guard sync(lock); + std::lock_guard sync(lock); if ((port == 0 ? i2COnboardObjCount-- : i2CMXPObjCount--) == 0) { int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle; i2clib_close(handle); diff --git a/hal/src/main/native/athena/Notifier.cpp b/hal/src/main/native/athena/Notifier.cpp index 2f0e3fe71c..95b578e141 100644 --- a/hal/src/main/native/athena/Notifier.cpp +++ b/hal/src/main/native/athena/Notifier.cpp @@ -19,7 +19,6 @@ #include "HAL/HAL.h" #include "HAL/cpp/NotifierInternal.h" #include "HAL/cpp/make_unique.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/UnlimitedHandleResource.h" #include "support/SafeThread.h" @@ -27,8 +26,8 @@ using namespace hal; static const int32_t kTimerInterruptNumber = 28; -static hal::priority_mutex notifierInterruptMutex; -static priority_recursive_mutex notifierMutex; +static std::mutex notifierInterruptMutex; +static std::mutex notifierMutex; static std::unique_ptr notifierAlarm; static std::unique_ptr notifierManager; static uint64_t closestTrigger = UINT64_MAX; @@ -101,12 +100,11 @@ static UnlimitedHandleResource notifierHandles; -// internal version of updateAlarm used during the alarmCallback when we know -// that the pointer is a valid pointer. +// Internal version of updateAlarm used during the alarmCallback when we know +// that the pointer is a valid pointer. This function is synchronized by the +// caller locking notifierMutex. void updateNotifierAlarmInternal(std::shared_ptr notifierPointer, uint64_t triggerTime, int32_t* status) { - std::lock_guard sync(notifierMutex); - auto notifier = notifierPointer; // no need for a null check, as this must always be a valid pointer. notifier->triggerTime = triggerTime; @@ -129,7 +127,7 @@ void updateNotifierAlarmInternal(std::shared_ptr notifierPointer, } static void alarmCallback(uint32_t, void*) { - std::unique_lock sync(notifierMutex); + std::unique_lock sync(notifierMutex); int32_t status = 0; uint64_t currentTime = 0; @@ -185,7 +183,7 @@ HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe( if (!notifierAtexitRegistered.test_and_set()) std::atexit(cleanupNotifierAtExit); if (notifierRefCount.fetch_add(1) == 0) { - std::lock_guard sync(notifierInterruptMutex); + std::lock_guard sync(notifierInterruptMutex); // create manager and alarm if not already created if (!notifierManager) { notifierManager = std::make_unique( @@ -196,7 +194,7 @@ HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe( if (!notifierAlarm) notifierAlarm.reset(tAlarm::create(status)); } - std::lock_guard sync(notifierMutex); + std::lock_guard sync(notifierMutex); std::shared_ptr notifier = std::make_shared(); HAL_NotifierHandle handle = notifierHandles.Allocate(notifier); if (handle == HAL_kInvalidHandle) { @@ -239,7 +237,7 @@ HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process, void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) { { - std::lock_guard sync(notifierMutex); + std::lock_guard sync(notifierMutex); auto notifier = notifierHandles.Get(notifierHandle); if (!notifier) return; @@ -257,7 +255,7 @@ void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) { } if (notifierRefCount.fetch_sub(1) == 1) { - std::lock_guard sync(notifierInterruptMutex); + std::lock_guard sync(notifierInterruptMutex); // if this was the last notifier, clean up alarm and manager if (notifierAlarm) { notifierAlarm->writeEnable(false, status); @@ -285,7 +283,7 @@ void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status) { void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t triggerTime, int32_t* status) { - std::lock_guard sync(notifierMutex); + std::lock_guard sync(notifierMutex); auto notifier = notifierHandles.Get(notifierHandle); if (!notifier) return; @@ -293,7 +291,7 @@ void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle, } void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status) { - std::lock_guard sync(notifierMutex); + std::lock_guard sync(notifierMutex); auto notifier = notifierHandles.Get(notifierHandle); if (!notifier) return; notifier->triggerTime = UINT64_MAX; diff --git a/hal/src/main/native/athena/Relay.cpp b/hal/src/main/native/athena/Relay.cpp index 6ca9e39cbc..85485cda26 100644 --- a/hal/src/main/native/athena/Relay.cpp +++ b/hal/src/main/native/athena/Relay.cpp @@ -27,7 +27,7 @@ static IndexedHandleResource sync(digitalRelayMutex); + std::lock_guard sync(digitalRelayMutex); uint8_t relays = 0; if (port->fwd) { relays = relaySystem->readValue_Forward(status); diff --git a/hal/src/main/native/athena/SPI.cpp b/hal/src/main/native/athena/SPI.cpp index e2a5fa79df..da8a7bbd4d 100644 --- a/hal/src/main/native/athena/SPI.cpp +++ b/hal/src/main/native/athena/SPI.cpp @@ -7,7 +7,9 @@ #include "HAL/SPI.h" +#include #include +#include #include #include @@ -17,7 +19,6 @@ #include "HAL/HAL.h" #include "HAL/Notifier.h" #include "HAL/cpp/make_unique.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" using namespace hal; @@ -27,27 +28,19 @@ static int32_t m_spiCS1Handle = 0; static int32_t m_spiCS2Handle = 0; static int32_t m_spiCS3Handle = 0; static int32_t m_spiMXPHandle = 0; -static priority_recursive_mutex spiOnboardMutex; -static priority_recursive_mutex spiMXPMutex; + +static constexpr int32_t kSpiMaxHandles = 5; + +// Indices 0-3 are for onboard CS0-CS2. Index 4 is for MXP. +static std::array spiHandleMutexes; +static std::array spiApiMutexes; +static std::array spiAccumulatorMutexes; // MXP SPI does not count towards this std::atomic spiPortCount{0}; static HAL_DigitalHandle digitalHandles[9]{HAL_kInvalidHandle}; -/** - * Get the semaphore for a SPI port - * - * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP - * @return The semaphore for the SPI port. - */ -static priority_recursive_mutex& spiGetMutex(HAL_SPIPort port) { - if (port < 4) - return spiOnboardMutex; - else - return spiMXPMutex; -} - extern "C" { struct SPIAccumulator { @@ -113,6 +106,11 @@ static void CommonSPIPortFree() { * @param port The number of the port to use. 0-3 for Onboard CS0-CS3, 4 for MXP */ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) { + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + if (HAL_GetSPIHandle(port) != 0) return; switch (port) { case 0: @@ -218,7 +216,11 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) { */ int32_t HAL_TransactionSPI(HAL_SPIPort port, uint8_t* dataToSend, uint8_t* dataReceived, int32_t size) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + return -1; + } + + std::lock_guard sync(spiApiMutexes[port]); return spilib_writeread( HAL_GetSPIHandle(port), reinterpret_cast(dataToSend), reinterpret_cast(dataReceived), static_cast(size)); @@ -235,7 +237,11 @@ int32_t HAL_TransactionSPI(HAL_SPIPort port, uint8_t* dataToSend, * @return The number of bytes written. -1 for an error */ int32_t HAL_WriteSPI(HAL_SPIPort port, uint8_t* dataToSend, int32_t sendSize) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + return -1; + } + + std::lock_guard sync(spiApiMutexes[port]); return spilib_write(HAL_GetSPIHandle(port), reinterpret_cast(dataToSend), static_cast(sendSize)); @@ -255,7 +261,11 @@ int32_t HAL_WriteSPI(HAL_SPIPort port, uint8_t* dataToSend, int32_t sendSize) { * @return Number of bytes read. -1 for error. */ int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + return -1; + } + + std::lock_guard sync(spiApiMutexes[port]); return spilib_read(HAL_GetSPIHandle(port), reinterpret_cast(buffer), static_cast(count)); } @@ -266,16 +276,23 @@ int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) { * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP */ void HAL_CloseSPI(HAL_SPIPort port) { - std::lock_guard sync(spiGetMutex(port)); - if (spiAccumulators[port]) { - int32_t status = 0; - HAL_FreeSPIAccumulator(port, &status); + if (port < 0 || port >= kSpiMaxHandles) { + return; } - spilib_close(HAL_GetSPIHandle(port)); + + int32_t status = 0; + HAL_FreeSPIAccumulator(port, &status); + + { + std::lock_guard sync(spiApiMutexes[port]); + spilib_close(HAL_GetSPIHandle(port)); + } + HAL_SetSPIHandle(port, 0); if (port < 4) { CommonSPIPortFree(); } + switch (port) { // Case 0 does not need to do anything case 1: @@ -296,7 +313,6 @@ void HAL_CloseSPI(HAL_SPIPort port) { default: break; } - return; } /** @@ -306,7 +322,11 @@ void HAL_CloseSPI(HAL_SPIPort port) { * @param speed The speed in Hz (0-1MHz) */ void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + return; + } + + std::lock_guard sync(spiApiMutexes[port]); spilib_setspeed(HAL_GetSPIHandle(port), speed); } @@ -322,7 +342,11 @@ void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) { */ void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst, HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + return; + } + + std::lock_guard sync(spiApiMutexes[port]); spilib_setopts(HAL_GetSPIHandle(port), msbFirst, sampleOnTrailing, clkIdleHigh); } @@ -333,7 +357,12 @@ void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst, * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP */ void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiApiMutexes[port]); if (port < 4) { spiSystem->writeChipSelectActiveHigh_Hdr( spiSystem->readChipSelectActiveHigh_Hdr(status) | (1 << port), status); @@ -348,7 +377,12 @@ void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) { * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP */ void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiApiMutexes[port]); if (port < 4) { spiSystem->writeChipSelectActiveHigh_Hdr( spiSystem->readChipSelectActiveHigh_Hdr(status) & ~(1 << port), status); @@ -364,7 +398,11 @@ void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) { * @return The stored handle for the SPI port. 0 represents no stored handle. */ int32_t HAL_GetSPIHandle(HAL_SPIPort port) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + return 0; + } + + std::lock_guard sync(spiHandleMutexes[port]); switch (port) { case 0: return m_spiCS0Handle; @@ -389,7 +427,11 @@ int32_t HAL_GetSPIHandle(HAL_SPIPort port) { * @param handle The value of the handle for the port. */ void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + return; + } + + std::lock_guard sync(spiHandleMutexes[port]); switch (port) { case 0: m_spiCS0Handle = handle; @@ -420,10 +462,13 @@ static void spiAccumulatorProcess(uint64_t currentTime, // perform SPI transaction uint8_t resp_b[4]; - std::lock_guard sync(spiGetMutex(accum->port)); - spilib_writeread( - HAL_GetSPIHandle(accum->port), reinterpret_cast(accum->cmd), - reinterpret_cast(resp_b), static_cast(accum->xferSize)); + { + std::lock_guard sync(spiApiMutexes[accum->port]); + spilib_writeread(HAL_GetSPIHandle(accum->port), + reinterpret_cast(accum->cmd), + reinterpret_cast(resp_b), + static_cast(accum->xferSize)); + } // convert from bytes uint32_t resp = 0; @@ -488,8 +533,12 @@ void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd, int32_t validValue, int32_t dataShift, int32_t dataSize, HAL_Bool isSigned, HAL_Bool bigEndian, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); - if (port > 4) return; + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); if (!spiAccumulators[port]) spiAccumulators[port] = std::make_unique(); SPIAccumulator* accum = spiAccumulators[port].get(); @@ -530,7 +579,12 @@ void HAL_InitSPIAccumulator(HAL_SPIPort port, int32_t period, int32_t cmd, * Frees a SPI accumulator. */ void HAL_FreeSPIAccumulator(HAL_SPIPort port, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; @@ -545,7 +599,12 @@ void HAL_FreeSPIAccumulator(HAL_SPIPort port, int32_t* status) { * Resets the accumulator to zero. */ void HAL_ResetSPIAccumulator(HAL_SPIPort port, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiApiMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; @@ -567,7 +626,12 @@ void HAL_ResetSPIAccumulator(HAL_SPIPort port, int32_t* status) { */ void HAL_SetSPIAccumulatorCenter(HAL_SPIPort port, int32_t center, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; @@ -581,7 +645,12 @@ void HAL_SetSPIAccumulatorCenter(HAL_SPIPort port, int32_t center, */ void HAL_SetSPIAccumulatorDeadband(HAL_SPIPort port, int32_t deadband, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; @@ -594,7 +663,12 @@ void HAL_SetSPIAccumulatorDeadband(HAL_SPIPort port, int32_t deadband, * Read the last value read by the accumulator engine. */ int32_t HAL_GetSPIAccumulatorLastValue(HAL_SPIPort port, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return 0; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; @@ -609,7 +683,12 @@ int32_t HAL_GetSPIAccumulatorLastValue(HAL_SPIPort port, int32_t* status) { * @return The 64-bit value accumulated since the last Reset(). */ int64_t HAL_GetSPIAccumulatorValue(HAL_SPIPort port, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return 0; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; @@ -627,7 +706,12 @@ int64_t HAL_GetSPIAccumulatorValue(HAL_SPIPort port, int32_t* status) { * @return The number of times samples from the channel were accumulated. */ int64_t HAL_GetSPIAccumulatorCount(HAL_SPIPort port, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return 0; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; @@ -642,6 +726,11 @@ int64_t HAL_GetSPIAccumulatorCount(HAL_SPIPort port, int32_t* status) { * @return The accumulated average value (value / count). */ double HAL_GetSPIAccumulatorAverage(HAL_SPIPort port, int32_t* status) { + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return 0.0; + } + int64_t value; int64_t count; HAL_GetSPIAccumulatorOutput(port, &value, &count, status); @@ -660,7 +749,12 @@ double HAL_GetSPIAccumulatorAverage(HAL_SPIPort port, int32_t* status) { */ void HAL_GetSPIAccumulatorOutput(HAL_SPIPort port, int64_t* value, int64_t* count, int32_t* status) { - std::lock_guard sync(spiGetMutex(port)); + if (port < 0 || port >= kSpiMaxHandles) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + std::lock_guard sync(spiAccumulatorMutexes[port]); SPIAccumulator* accum = spiAccumulators[port].get(); if (!accum) { *status = NULL_PARAMETER; diff --git a/hal/src/main/native/athena/cpp/SerialHelper.cpp b/hal/src/main/native/athena/cpp/SerialHelper.cpp index 392c77e139..10c2bcf449 100644 --- a/hal/src/main/native/athena/cpp/SerialHelper.cpp +++ b/hal/src/main/native/athena/cpp/SerialHelper.cpp @@ -26,7 +26,7 @@ namespace hal { std::string SerialHelper::m_usbNames[2]{"", ""}; -priority_mutex SerialHelper::m_nameMutex; +std::mutex SerialHelper::m_nameMutex; SerialHelper::SerialHelper() { viOpenDefaultRM(reinterpret_cast(&m_resourceHandle)); @@ -287,7 +287,7 @@ done: int32_t SerialHelper::GetIndexForPort(HAL_SerialPort port, int32_t* status) { // Hold lock whenever we're using the names array - std::lock_guard lock(m_nameMutex); + std::lock_guard lock(m_nameMutex); std::string portString = m_usbNames[port - 2]; diff --git a/hal/src/main/native/include/HAL/cpp/SerialHelper.h b/hal/src/main/native/include/HAL/cpp/SerialHelper.h index c0ede644ac..4f7a70ce09 100644 --- a/hal/src/main/native/include/HAL/cpp/SerialHelper.h +++ b/hal/src/main/native/include/HAL/cpp/SerialHelper.h @@ -9,6 +9,7 @@ #include +#include #include #include @@ -16,7 +17,6 @@ #include #include "HAL/SerialPort.h" -#include "HAL/cpp/priority_mutex.h" namespace hal { class SerialHelper { @@ -46,7 +46,7 @@ class SerialHelper { int32_t m_resourceHandle; - static hal::priority_mutex m_nameMutex; + static std::mutex m_nameMutex; static std::string m_usbNames[2]; }; } // namespace hal diff --git a/hal/src/main/native/include/HAL/cpp/priority_condition_variable.h b/hal/src/main/native/include/HAL/cpp/priority_condition_variable.h deleted file mode 100644 index 81aac01ad0..0000000000 --- a/hal/src/main/native/include/HAL/cpp/priority_condition_variable.h +++ /dev/null @@ -1,141 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#pragma once - -/* std::condition_variable provides the native_handle() method to return its - * underlying pthread_cond_t*. WPILib uses this to interface with the FRC - * network communication library. Since WPILib uses a custom mutex class and - * not std::mutex, std::condition_variable_any must be used instead. - * std::condition_variable_any doesn't expose its internal handle, so this - * class provides the same interface and implementation in addition to a - * native_handle() method. - */ - -#include -#include -#include - -#include "priority_mutex.h" - -namespace hal { - -class priority_condition_variable { - typedef std::chrono::system_clock clock; - - public: - typedef std::condition_variable::native_handle_type native_handle_type; - - priority_condition_variable() : m_mutex(std::make_shared()) {} - ~priority_condition_variable() = default; - - priority_condition_variable(const priority_condition_variable&) = delete; - priority_condition_variable& operator=(const priority_condition_variable&) = - delete; - - void notify_one() noexcept { - std::lock_guard lock(*m_mutex); - m_cond.notify_one(); - } - - void notify_all() noexcept { - std::lock_guard lock(*m_mutex); - m_cond.notify_all(); - } - - template - void wait(Lock& _lock) { - std::shared_ptr _mutex = m_mutex; - std::unique_lock my_lock(*_mutex); - Unlock unlock(_lock); - - // *mutex must be unlocked before re-locking _lock so move - // ownership of *_mutex lock to an object with shorter lifetime. - std::unique_lock my_lock2(std::move(my_lock)); - m_cond.wait(my_lock2); - } - - template - void wait(Lock& lock, Predicate p) { - while (!p()) { - wait(lock); - } - } - - template - std::cv_status wait_until( - Lock& _lock, const std::chrono::time_point& atime) { - std::shared_ptr _mutex = m_mutex; - std::unique_lock my_lock(*_mutex); - Unlock unlock(_lock); - - // *_mutex must be unlocked before re-locking _lock so move - // ownership of *_mutex lock to an object with shorter lifetime. - std::unique_lock my_lock2(std::move(my_lock)); - return m_cond.wait_until(my_lock2, atime); - } - - template - bool wait_until(Lock& lock, - const std::chrono::time_point& atime, - Predicate p) { - while (!p()) { - if (wait_until(lock, atime) == std::cv_status::timeout) { - return p(); - } - } - return true; - } - - template - std::cv_status wait_for(Lock& lock, - const std::chrono::duration& rtime) { - return wait_until(lock, clock::now() + rtime); - } - - template - bool wait_for(Lock& lock, const std::chrono::duration& rtime, - Predicate p) { - return wait_until(lock, clock::now() + rtime, std::move(p)); - } - - native_handle_type native_handle() { return m_cond.native_handle(); } - - private: - std::condition_variable m_cond; - std::shared_ptr m_mutex; - - // scoped unlock - unlocks in ctor, re-locks in dtor - template - struct Unlock { - explicit Unlock(Lock& lk) : m_lock(lk) { lk.unlock(); } - - ~Unlock() /*noexcept(false)*/ { - if (std::uncaught_exception()) { - try { - m_lock.lock(); - } catch (...) { - } - } else { - m_lock.lock(); - } - } - - Unlock(const Unlock&) = delete; - Unlock& operator=(const Unlock&) = delete; - - Lock& m_lock; - }; -}; - -} // namespace hal - -// For backwards compatibility -#ifndef NAMESPACED_PRIORITY -using hal::priority_condition_variable; // NOLINT -#endif diff --git a/hal/src/main/native/include/HAL/handles/DigitalHandleResource.h b/hal/src/main/native/include/HAL/handles/DigitalHandleResource.h index 0f01cb8277..eff2448413 100644 --- a/hal/src/main/native/include/HAL/handles/DigitalHandleResource.h +++ b/hal/src/main/native/include/HAL/handles/DigitalHandleResource.h @@ -11,11 +11,11 @@ #include #include +#include #include "HAL/Errors.h" #include "HAL/Types.h" #include "HAL/cpp/make_unique.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" namespace hal { @@ -48,7 +48,7 @@ class DigitalHandleResource : public HandleBase { private: std::array, size> m_structures; - std::array m_handleMutexes; + std::array m_handleMutexes; }; template @@ -59,7 +59,7 @@ THandle DigitalHandleResource::Allocate( *status = RESOURCE_OUT_OF_RANGE; return HAL_kInvalidHandle; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { *status = RESOURCE_IS_ALLOCATED; @@ -77,7 +77,7 @@ std::shared_ptr DigitalHandleResource::Get( if (index < 0 || index >= size) { return nullptr; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // return structure. Null will propogate correctly, so no need to manually // check. return m_structures[index]; @@ -90,14 +90,14 @@ void DigitalHandleResource::Free( int16_t index = getHandleTypedIndex(handle, enumValue, m_version); if (index < 0 || index >= size) return; // lock and deallocated handle - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); m_structures[index].reset(); } template void DigitalHandleResource::ResetHandles() { for (int i = 0; i < size; i++) { - std::lock_guard sync(m_handleMutexes[i]); + std::lock_guard sync(m_handleMutexes[i]); m_structures[i].reset(); } HandleBase::ResetHandles(); diff --git a/hal/src/main/native/include/HAL/handles/IndexedClassedHandleResource.h b/hal/src/main/native/include/HAL/handles/IndexedClassedHandleResource.h index c437f4af0e..2d3ca0f0b6 100644 --- a/hal/src/main/native/include/HAL/handles/IndexedClassedHandleResource.h +++ b/hal/src/main/native/include/HAL/handles/IndexedClassedHandleResource.h @@ -51,7 +51,7 @@ class IndexedClassedHandleResource : public HandleBase { private: std::array[], size> m_structures; - std::array m_handleMutexes; + std::array m_handleMutexes; }; template ::IndexedClassedHandleResource() { m_structures = std::make_unique[]>(size); - m_handleMutexes = std::make_unique(size); + m_handleMutexes = std::make_unique(size); } template ::Allocate( *status = RESOURCE_OUT_OF_RANGE; return HAL_kInvalidHandle; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { *status = RESOURCE_IS_ALLOCATED; @@ -91,7 +91,7 @@ std::shared_ptr IndexedClassedHandleResource< if (index < 0 || index >= size) { return nullptr; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // return structure. Null will propogate correctly, so no need to manually // check. return m_structures[index]; @@ -105,7 +105,7 @@ void IndexedClassedHandleResource::Free( int16_t index = getHandleTypedIndex(handle, enumValue, m_version); if (index < 0 || index >= size) return; // lock and deallocated handle - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); m_structures[index].reset(); } @@ -114,7 +114,7 @@ template ::ResetHandles() { for (int i = 0; i < size; i++) { - std::lock_guard sync(m_handleMutexes[i]); + std::lock_guard sync(m_handleMutexes[i]); m_structures[i].reset(); } HandleBase::ResetHandles(); diff --git a/hal/src/main/native/include/HAL/handles/IndexedHandleResource.h b/hal/src/main/native/include/HAL/handles/IndexedHandleResource.h index e13480447b..d2c1a254a3 100644 --- a/hal/src/main/native/include/HAL/handles/IndexedHandleResource.h +++ b/hal/src/main/native/include/HAL/handles/IndexedHandleResource.h @@ -11,11 +11,11 @@ #include #include +#include #include "HAL/Errors.h" #include "HAL/Types.h" #include "HAL/cpp/make_unique.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" namespace hal { @@ -49,7 +49,7 @@ class IndexedHandleResource : public HandleBase { private: std::array, size> m_structures; - std::array m_handleMutexes; + std::array m_handleMutexes; }; template ::Allocate( *status = RESOURCE_OUT_OF_RANGE; return HAL_kInvalidHandle; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { *status = RESOURCE_IS_ALLOCATED; @@ -80,7 +80,7 @@ IndexedHandleResource::Get(THandle handle) { if (index < 0 || index >= size) { return nullptr; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // return structure. Null will propogate correctly, so no need to manually // check. return m_structures[index]; @@ -94,7 +94,7 @@ void IndexedHandleResource::Free( int16_t index = getHandleTypedIndex(handle, enumValue, m_version); if (index < 0 || index >= size) return; // lock and deallocated handle - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); m_structures[index].reset(); } @@ -102,7 +102,7 @@ template void IndexedHandleResource::ResetHandles() { for (int i = 0; i < size; i++) { - std::lock_guard sync(m_handleMutexes[i]); + std::lock_guard sync(m_handleMutexes[i]); m_structures[i].reset(); } HandleBase::ResetHandles(); diff --git a/hal/src/main/native/include/HAL/handles/LimitedClassedHandleResource.h b/hal/src/main/native/include/HAL/handles/LimitedClassedHandleResource.h index 8662ee8493..ac68b36b74 100644 --- a/hal/src/main/native/include/HAL/handles/LimitedClassedHandleResource.h +++ b/hal/src/main/native/include/HAL/handles/LimitedClassedHandleResource.h @@ -11,10 +11,10 @@ #include #include +#include #include "HAL/Types.h" #include "HAL/cpp/make_unique.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" namespace hal { @@ -48,8 +48,8 @@ class LimitedClassedHandleResource : public HandleBase { private: std::array, size> m_structures; - std::array m_handleMutexes; - hal::priority_mutex m_allocateMutex; + std::array m_handleMutexes; + std::mutex m_allocateMutex; }; template ::Allocate( std::shared_ptr toSet) { // globally lock to loop through indices - std::lock_guard sync(m_allocateMutex); + std::lock_guard sync(m_allocateMutex); for (int16_t i = 0; i < size; i++) { if (m_structures[i] == nullptr) { // if a false index is found, grab its specific mutex // and allocate it. - std::lock_guard sync(m_handleMutexes[i]); + std::lock_guard sync(m_handleMutexes[i]); m_structures[i] = toSet; return static_cast(createHandle(i, enumValue, m_version)); } @@ -80,7 +80,7 @@ std::shared_ptr LimitedClassedHandleResource< if (index < 0 || index >= size) { return nullptr; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // return structure. Null will propogate correctly, so no need to manually // check. return m_structures[index]; @@ -94,8 +94,8 @@ void LimitedClassedHandleResource::Free( int16_t index = getHandleTypedIndex(handle, enumValue, m_version); if (index < 0 || index >= size) return; // lock and deallocated handle - std::lock_guard sync(m_allocateMutex); - std::lock_guard lock(m_handleMutexes[index]); + std::lock_guard sync(m_allocateMutex); + std::lock_guard lock(m_handleMutexes[index]); m_structures[index].reset(); } @@ -104,9 +104,9 @@ template ::ResetHandles() { { - std::lock_guard lock(m_allocateMutex); + std::lock_guard lock(m_allocateMutex); for (int i = 0; i < size; i++) { - std::lock_guard sync(m_handleMutexes[i]); + std::lock_guard sync(m_handleMutexes[i]); m_structures[i].reset(); } } diff --git a/hal/src/main/native/include/HAL/handles/LimitedHandleResource.h b/hal/src/main/native/include/HAL/handles/LimitedHandleResource.h index f04dc86963..5beee3c4fb 100644 --- a/hal/src/main/native/include/HAL/handles/LimitedHandleResource.h +++ b/hal/src/main/native/include/HAL/handles/LimitedHandleResource.h @@ -11,10 +11,10 @@ #include #include +#include #include "HAL/Types.h" #include "HAL/cpp/make_unique.h" -#include "HAL/cpp/priority_mutex.h" #include "HandlesInternal.h" namespace hal { @@ -46,20 +46,20 @@ class LimitedHandleResource : public HandleBase { private: std::array, size> m_structures; - std::array m_handleMutexes; - hal::priority_mutex m_allocateMutex; + std::array m_handleMutexes; + std::mutex m_allocateMutex; }; template THandle LimitedHandleResource::Allocate() { // globally lock to loop through indices - std::lock_guard sync(m_allocateMutex); + std::lock_guard sync(m_allocateMutex); for (int16_t i = 0; i < size; i++) { if (m_structures[i] == nullptr) { // if a false index is found, grab its specific mutex // and allocate it. - std::lock_guard sync(m_handleMutexes[i]); + std::lock_guard sync(m_handleMutexes[i]); m_structures[i] = std::make_shared(); return static_cast(createHandle(i, enumValue, m_version)); } @@ -76,7 +76,7 @@ LimitedHandleResource::Get(THandle handle) { if (index < 0 || index >= size) { return nullptr; } - std::lock_guard sync(m_handleMutexes[index]); + std::lock_guard sync(m_handleMutexes[index]); // return structure. Null will propogate correctly, so no need to manually // check. return m_structures[index]; @@ -90,8 +90,8 @@ void LimitedHandleResource::Free( int16_t index = getHandleTypedIndex(handle, enumValue, m_version); if (index < 0 || index >= size) return; // lock and deallocated handle - std::lock_guard sync(m_allocateMutex); - std::lock_guard lock(m_handleMutexes[index]); + std::lock_guard sync(m_allocateMutex); + std::lock_guard lock(m_handleMutexes[index]); m_structures[index].reset(); } @@ -99,9 +99,9 @@ template void LimitedHandleResource::ResetHandles() { { - std::lock_guard lock(m_allocateMutex); + std::lock_guard lock(m_allocateMutex); for (int i = 0; i < size; i++) { - std::lock_guard sync(m_handleMutexes[i]); + std::lock_guard sync(m_handleMutexes[i]); m_structures[i].reset(); } } diff --git a/hal/src/main/native/include/HAL/handles/UnlimitedHandleResource.h b/hal/src/main/native/include/HAL/handles/UnlimitedHandleResource.h index 23c87a3716..9ea10f343d 100644 --- a/hal/src/main/native/include/HAL/handles/UnlimitedHandleResource.h +++ b/hal/src/main/native/include/HAL/handles/UnlimitedHandleResource.h @@ -10,10 +10,10 @@ #include #include +#include #include #include "HAL/Types.h" -#include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" namespace hal { @@ -48,13 +48,13 @@ class UnlimitedHandleResource : public HandleBase { private: std::vector> m_structures; - hal::priority_mutex m_handleMutex; + std::mutex m_handleMutex; }; template THandle UnlimitedHandleResource::Allocate( std::shared_ptr structure) { - std::lock_guard sync(m_handleMutex); + std::lock_guard sync(m_handleMutex); size_t i; for (i = 0; i < m_structures.size(); i++) { if (m_structures[i] == nullptr) { @@ -73,7 +73,7 @@ template std::shared_ptr UnlimitedHandleResource::Get(THandle handle) { int16_t index = getHandleTypedIndex(handle, enumValue, m_version); - std::lock_guard sync(m_handleMutex); + std::lock_guard sync(m_handleMutex); if (index < 0 || index >= static_cast(m_structures.size())) return nullptr; return m_structures[index]; @@ -83,7 +83,7 @@ template void UnlimitedHandleResource::Free( THandle handle) { int16_t index = getHandleTypedIndex(handle, enumValue, m_version); - std::lock_guard sync(m_handleMutex); + std::lock_guard sync(m_handleMutex); if (index < 0 || index >= static_cast(m_structures.size())) return; m_structures[index].reset(); } @@ -91,7 +91,7 @@ void UnlimitedHandleResource::Free( template void UnlimitedHandleResource::ResetHandles() { { - std::lock_guard lock(m_handleMutex); + std::lock_guard lock(m_handleMutex); for (size_t i = 0; i < m_structures.size(); i++) { m_structures[i].reset(); } diff --git a/hal/src/main/native/shared/handles/HandlesInternal.cpp b/hal/src/main/native/shared/handles/HandlesInternal.cpp index 68a5cc21c5..7fdab2977f 100644 --- a/hal/src/main/native/shared/handles/HandlesInternal.cpp +++ b/hal/src/main/native/shared/handles/HandlesInternal.cpp @@ -8,20 +8,19 @@ #include "HAL/handles/HandlesInternal.h" #include +#include #include -#include "HAL/cpp/priority_mutex.h" - namespace hal { static llvm::SmallVector globalHandles; -static priority_mutex& GetGlobalHandleMutex() { - static priority_mutex globalHandleMutex; +static std::mutex& GetGlobalHandleMutex() { + static std::mutex globalHandleMutex; return globalHandleMutex; } HandleBase::HandleBase() { - std::lock_guard lock(GetGlobalHandleMutex()); + std::lock_guard lock(GetGlobalHandleMutex()); auto index = std::find(globalHandles.begin(), globalHandles.end(), this); if (index == globalHandles.end()) { globalHandles.push_back(this); @@ -31,7 +30,7 @@ HandleBase::HandleBase() { } HandleBase::~HandleBase() { - std::lock_guard lock(GetGlobalHandleMutex()); + std::lock_guard lock(GetGlobalHandleMutex()); auto index = std::find(globalHandles.begin(), globalHandles.end(), this); if (index != globalHandles.end()) { *index = nullptr; @@ -46,7 +45,7 @@ void HandleBase::ResetHandles() { } void HandleBase::ResetGlobalHandles() { - std::unique_lock lock(GetGlobalHandleMutex()); + std::unique_lock lock(GetGlobalHandleMutex()); for (auto&& i : globalHandles) { if (i != nullptr) { lock.unlock(); diff --git a/hal/src/main/native/sim/AnalogInternal.cpp b/hal/src/main/native/sim/AnalogInternal.cpp index 1439432154..2bdb9e513f 100644 --- a/hal/src/main/native/sim/AnalogInternal.cpp +++ b/hal/src/main/native/sim/AnalogInternal.cpp @@ -8,7 +8,6 @@ #include "AnalogInternal.h" #include "HAL/AnalogInput.h" -#include "HAL/cpp/priority_mutex.h" #include "PortsInternal.h" namespace hal { diff --git a/hal/src/main/native/sim/DigitalInternal.cpp b/hal/src/main/native/sim/DigitalInternal.cpp index 1f05c9ded6..6d48a5e6f5 100644 --- a/hal/src/main/native/sim/DigitalInternal.cpp +++ b/hal/src/main/native/sim/DigitalInternal.cpp @@ -11,7 +11,6 @@ #include "HAL/AnalogTrigger.h" #include "HAL/HAL.h" #include "HAL/Ports.h" -#include "HAL/cpp/priority_mutex.h" #include "PortsInternal.h" namespace hal { diff --git a/hal/src/main/native/sim/DriverStation.cpp b/hal/src/main/native/sim/DriverStation.cpp index 9b78b6a0bf..5f9e32a155 100644 --- a/hal/src/main/native/sim/DriverStation.cpp +++ b/hal/src/main/native/sim/DriverStation.cpp @@ -11,17 +11,17 @@ #include #endif +#include #include #include +#include #include -#include "HAL/cpp/priority_condition_variable.h" -#include "HAL/cpp/priority_mutex.h" #include "MockData/DriverStationDataInternal.h" -static hal::priority_mutex msgMutex; -static hal::priority_condition_variable newDSDataAvailableCond; -static hal::priority_mutex newDSDataAvailableMutex; +static std::mutex msgMutex; +static std::condition_variable newDSDataAvailableCond; +static std::mutex newDSDataAvailableMutex; static int newDSDataAvailableCounter{0}; using namespace hal; @@ -38,7 +38,7 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode, // Avoid flooding console by keeping track of previous 5 error // messages and only printing again if they're longer than 1 second old. static constexpr int KEEP_MSGS = 5; - std::lock_guard lock(msgMutex); + std::lock_guard lock(msgMutex); static std::string prevMsg[KEEP_MSGS]; static std::chrono::time_point prevMsgTime[KEEP_MSGS]; @@ -198,7 +198,7 @@ bool HAL_IsNewControlData(void) { // worth the cycles to check. int currentCount = 0; { - std::unique_lock lock(newDSDataAvailableMutex); + std::unique_lock lock(newDSDataAvailableMutex); currentCount = newDSDataAvailableCounter; } if (lastCount == currentCount) return false; @@ -220,7 +220,7 @@ HAL_Bool HAL_WaitForDSDataTimeout(double timeout) { auto timeoutTime = std::chrono::steady_clock::now() + std::chrono::duration(timeout); - std::unique_lock lock(newDSDataAvailableMutex); + std::unique_lock lock(newDSDataAvailableMutex); int currentCount = newDSDataAvailableCounter; while (newDSDataAvailableCounter == currentCount) { if (timeout > 0) { @@ -242,7 +242,7 @@ static int32_t newDataOccur(uint32_t refNum) { // Since we could get other values, require our specific handle // to signal our threads if (refNum != refNumber) return 0; - std::lock_guard lock(newDSDataAvailableMutex); + std::lock_guard lock(newDSDataAvailableMutex); // Nofify all threads newDSDataAvailableCounter++; newDSDataAvailableCond.notify_all(); @@ -256,11 +256,11 @@ static int32_t newDataOccur(uint32_t refNum) { */ void HAL_InitializeDriverStation(void) { static std::atomic_bool initialized{false}; - static hal::priority_mutex initializeMutex; + static std::mutex initializeMutex; // Initial check, as if it's true initialization has finished if (initialized) return; - std::lock_guard lock(initializeMutex); + std::lock_guard lock(initializeMutex); // Second check in case another thread was waiting if (initialized) return; diff --git a/wpilibc/src/main/native/cpp/Commands/Scheduler.cpp b/wpilibc/src/main/native/cpp/Commands/Scheduler.cpp index 1468867db4..93cad48522 100644 --- a/wpilibc/src/main/native/cpp/Commands/Scheduler.cpp +++ b/wpilibc/src/main/native/cpp/Commands/Scheduler.cpp @@ -40,7 +40,7 @@ void Scheduler::SetEnabled(bool enabled) { m_enabled = enabled; } * @param command The command to be scheduled */ void Scheduler::AddCommand(Command* command) { - std::lock_guard sync(m_additionsLock); + std::lock_guard sync(m_additionsLock); if (std::find(m_additions.begin(), m_additions.end(), command) != m_additions.end()) return; @@ -48,7 +48,7 @@ void Scheduler::AddCommand(Command* command) { } void Scheduler::AddButton(ButtonScheduler* button) { - std::lock_guard sync(m_buttonsLock); + std::lock_guard sync(m_buttonsLock); m_buttons.push_back(button); } @@ -114,7 +114,7 @@ void Scheduler::Run() { { if (!m_enabled) return; - std::lock_guard sync(m_buttonsLock); + std::lock_guard sync(m_buttonsLock); for (auto rButtonIter = m_buttons.rbegin(); rButtonIter != m_buttons.rend(); rButtonIter++) { (*rButtonIter)->Execute(); @@ -144,7 +144,7 @@ void Scheduler::Run() { // Add the new things { - std::lock_guard sync(m_additionsLock); + std::lock_guard sync(m_additionsLock); for (auto additionsIter = m_additions.begin(); additionsIter != m_additions.end(); additionsIter++) { ProcessCommandAddition(*additionsIter); diff --git a/wpilibc/src/main/native/cpp/DigitalGlitchFilter.cpp b/wpilibc/src/main/native/cpp/DigitalGlitchFilter.cpp index ab505d6d0c..3e9d83bed1 100644 --- a/wpilibc/src/main/native/cpp/DigitalGlitchFilter.cpp +++ b/wpilibc/src/main/native/cpp/DigitalGlitchFilter.cpp @@ -23,10 +23,10 @@ using namespace frc; std::array DigitalGlitchFilter::m_filterAllocated = { {false, false, false}}; -hal::priority_mutex DigitalGlitchFilter::m_mutex; +std::mutex DigitalGlitchFilter::m_mutex; DigitalGlitchFilter::DigitalGlitchFilter() { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); auto index = std::find(m_filterAllocated.begin(), m_filterAllocated.end(), false); wpi_assert(index != m_filterAllocated.end()); @@ -39,7 +39,7 @@ DigitalGlitchFilter::DigitalGlitchFilter() { DigitalGlitchFilter::~DigitalGlitchFilter() { if (m_channelIndex >= 0) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_filterAllocated[m_channelIndex] = false; } } diff --git a/wpilibc/src/main/native/cpp/DriverStation.cpp b/wpilibc/src/main/native/cpp/DriverStation.cpp index 7d6393576f..fde7158324 100644 --- a/wpilibc/src/main/native/cpp/DriverStation.cpp +++ b/wpilibc/src/main/native/cpp/DriverStation.cpp @@ -90,7 +90,7 @@ double DriverStation::GetStickAxis(int stick, int axis) { wpi_setWPIError(BadJoystickIndex); return 0; } - std::unique_lock lock(m_joystickDataMutex); + std::unique_lock lock(m_joystickDataMutex); if (axis >= m_joystickAxes[stick].count) { // Unlock early so error printing isn't locked. m_joystickDataMutex.unlock(); @@ -116,7 +116,7 @@ int DriverStation::GetStickPOV(int stick, int pov) { wpi_setWPIError(BadJoystickIndex); return -1; } - std::unique_lock lock(m_joystickDataMutex); + std::unique_lock lock(m_joystickDataMutex); if (pov >= m_joystickPOVs[stick].count) { // Unlock early so error printing isn't locked. lock.unlock(); @@ -142,7 +142,7 @@ int DriverStation::GetStickButtons(int stick) const { wpi_setWPIError(BadJoystickIndex); return 0; } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); return m_joystickButtons[stick].buttons; } @@ -163,7 +163,7 @@ bool DriverStation::GetStickButton(int stick, int button) { "ERROR: Button indexes begin at 1 in WPILib for C++ and Java"); return false; } - std::unique_lock lock(m_joystickDataMutex); + std::unique_lock lock(m_joystickDataMutex); if (button > m_joystickButtons[stick].count) { // Unlock early so error printing isn't locked. lock.unlock(); @@ -187,7 +187,7 @@ int DriverStation::GetStickAxisCount(int stick) const { wpi_setWPIError(BadJoystickIndex); return 0; } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); return m_joystickAxes[stick].count; } @@ -202,7 +202,7 @@ int DriverStation::GetStickPOVCount(int stick) const { wpi_setWPIError(BadJoystickIndex); return 0; } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); return m_joystickPOVs[stick].count; } @@ -217,7 +217,7 @@ int DriverStation::GetStickButtonCount(int stick) const { wpi_setWPIError(BadJoystickIndex); return 0; } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); return m_joystickButtons[stick].count; } @@ -232,7 +232,7 @@ bool DriverStation::GetJoystickIsXbox(int stick) const { wpi_setWPIError(BadJoystickIndex); return false; } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); return static_cast(m_joystickDescriptor[stick].isXbox); } @@ -247,7 +247,7 @@ int DriverStation::GetJoystickType(int stick) const { wpi_setWPIError(BadJoystickIndex); return -1; } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); return static_cast(m_joystickDescriptor[stick].type); } @@ -261,7 +261,7 @@ std::string DriverStation::GetJoystickName(int stick) const { if (stick >= kJoystickPorts) { wpi_setWPIError(BadJoystickIndex); } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); std::string retVal(m_joystickDescriptor[stick].name); return retVal; } @@ -277,7 +277,7 @@ int DriverStation::GetJoystickAxisType(int stick, int axis) const { wpi_setWPIError(BadJoystickIndex); return -1; } - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); return m_joystickDescriptor[stick].axisTypes[axis]; } @@ -528,7 +528,7 @@ void DriverStation::GetData() { UpdateControlWord(true, controlWord); // Obtain a write lock on the data, swap the cached data into the // main data arrays - std::lock_guard lock(m_joystickDataMutex); + std::lock_guard lock(m_joystickDataMutex); m_joystickAxes.swap(m_joystickAxesCache); m_joystickPOVs.swap(m_joystickPOVsCache); m_joystickButtons.swap(m_joystickButtonsCache); @@ -629,7 +629,7 @@ void DriverStation::Run() { void DriverStation::UpdateControlWord(bool force, HAL_ControlWord& controlWord) const { auto now = std::chrono::steady_clock::now(); - std::lock_guard lock(m_controlWordMutex); + std::lock_guard lock(m_controlWordMutex); // Update every 50 ms or on force. if ((now - m_lastControlWordUpdate > std::chrono::milliseconds(50)) || force) { diff --git a/wpilibc/src/main/native/cpp/ErrorBase.cpp b/wpilibc/src/main/native/cpp/ErrorBase.cpp index fc462c83bc..d3891a2e94 100644 --- a/wpilibc/src/main/native/cpp/ErrorBase.cpp +++ b/wpilibc/src/main/native/cpp/ErrorBase.cpp @@ -20,7 +20,7 @@ using namespace frc; -hal::priority_mutex ErrorBase::_globalErrorMutex; +std::mutex ErrorBase::_globalErrorMutex; Error ErrorBase::_globalError; /** @@ -64,7 +64,7 @@ void ErrorBase::SetErrnoError(llvm::StringRef contextMessage, m_error.Set(-1, err, filename, function, lineNumber, this); // Update the global error if there is not one already set. - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); if (_globalError.GetCode() == 0) { _globalError.Clone(m_error); } @@ -93,7 +93,7 @@ void ErrorBase::SetImaqError(int success, llvm::StringRef contextMessage, m_error.Set(success, err.str(), filename, function, lineNumber, this); // Update the global error if there is not one already set. - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); if (_globalError.GetCode() == 0) { _globalError.Clone(m_error); } @@ -118,7 +118,7 @@ void ErrorBase::SetError(Error::Code code, llvm::StringRef contextMessage, m_error.Set(code, contextMessage, filename, function, lineNumber, this); // Update the global error if there is not one already set. - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); if (_globalError.GetCode() == 0) { _globalError.Clone(m_error); } @@ -156,7 +156,7 @@ void ErrorBase::SetErrorRange(Error::Code code, int32_t minRange, delete[] buf; // Update the global error if there is not one already set. - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); if (_globalError.GetCode() == 0) { _globalError.Clone(m_error); } @@ -182,7 +182,7 @@ void ErrorBase::SetWPIError(llvm::StringRef errorMessage, Error::Code code, m_error.Set(code, err, filename, function, lineNumber, this); // Update the global error if there is not one already set. - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); if (_globalError.GetCode() == 0) { _globalError.Clone(m_error); } @@ -204,7 +204,7 @@ void ErrorBase::SetGlobalError(Error::Code code, llvm::StringRef contextMessage, llvm::StringRef function, int lineNumber) { // If there was an error if (code != 0) { - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); // Set the current error information for this object. _globalError.Set(code, contextMessage, filename, function, lineNumber, @@ -218,7 +218,7 @@ void ErrorBase::SetGlobalWPIError(llvm::StringRef errorMessage, llvm::StringRef function, int lineNumber) { std::string err = errorMessage.str() + ": " + contextMessage.str(); - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); if (_globalError.GetCode() != 0) { _globalError.Clear(); } @@ -229,6 +229,6 @@ void ErrorBase::SetGlobalWPIError(llvm::StringRef errorMessage, * Retrieve the current global error. */ Error& ErrorBase::GetGlobalError() { - std::lock_guard mutex(_globalErrorMutex); + std::lock_guard mutex(_globalErrorMutex); return _globalError; } diff --git a/wpilibc/src/main/native/cpp/MotorSafetyHelper.cpp b/wpilibc/src/main/native/cpp/MotorSafetyHelper.cpp index c69efde52d..a0ca20859e 100644 --- a/wpilibc/src/main/native/cpp/MotorSafetyHelper.cpp +++ b/wpilibc/src/main/native/cpp/MotorSafetyHelper.cpp @@ -18,7 +18,7 @@ using namespace frc; std::set MotorSafetyHelper::m_helperList; -hal::priority_recursive_mutex MotorSafetyHelper::m_listMutex; +std::mutex MotorSafetyHelper::m_listMutex; /** * The constructor for a MotorSafetyHelper object. @@ -38,12 +38,12 @@ MotorSafetyHelper::MotorSafetyHelper(MotorSafety* safeObject) m_expiration = DEFAULT_SAFETY_EXPIRATION; m_stopTime = Timer::GetFPGATimestamp(); - std::lock_guard sync(m_listMutex); + std::lock_guard sync(m_listMutex); m_helperList.insert(this); } MotorSafetyHelper::~MotorSafetyHelper() { - std::lock_guard sync(m_listMutex); + std::lock_guard sync(m_listMutex); m_helperList.erase(this); } @@ -52,7 +52,7 @@ MotorSafetyHelper::~MotorSafetyHelper() { * Resets the timer on this object that is used to do the timeouts. */ void MotorSafetyHelper::Feed() { - std::lock_guard sync(m_syncMutex); + std::lock_guard sync(m_syncMutex); m_stopTime = Timer::GetFPGATimestamp() + m_expiration; } @@ -61,7 +61,7 @@ void MotorSafetyHelper::Feed() { * @param expirationTime The timeout value in seconds. */ void MotorSafetyHelper::SetExpiration(double expirationTime) { - std::lock_guard sync(m_syncMutex); + std::lock_guard sync(m_syncMutex); m_expiration = expirationTime; } @@ -70,7 +70,7 @@ void MotorSafetyHelper::SetExpiration(double expirationTime) { * @return the timeout value in seconds. */ double MotorSafetyHelper::GetExpiration() const { - std::lock_guard sync(m_syncMutex); + std::lock_guard sync(m_syncMutex); return m_expiration; } @@ -80,7 +80,7 @@ double MotorSafetyHelper::GetExpiration() const { * timed out. */ bool MotorSafetyHelper::IsAlive() const { - std::lock_guard sync(m_syncMutex); + std::lock_guard sync(m_syncMutex); return !m_enabled || m_stopTime > Timer::GetFPGATimestamp(); } @@ -94,7 +94,7 @@ void MotorSafetyHelper::Check() { DriverStation& ds = DriverStation::GetInstance(); if (!m_enabled || ds.IsDisabled() || ds.IsTest()) return; - std::lock_guard sync(m_syncMutex); + std::lock_guard sync(m_syncMutex); if (m_stopTime < Timer::GetFPGATimestamp()) { llvm::SmallString<128> buf; llvm::raw_svector_ostream desc(buf); @@ -111,7 +111,7 @@ void MotorSafetyHelper::Check() { * @param enabled True if motor safety is enforced for this object */ void MotorSafetyHelper::SetSafetyEnabled(bool enabled) { - std::lock_guard sync(m_syncMutex); + std::lock_guard sync(m_syncMutex); m_enabled = enabled; } @@ -121,7 +121,7 @@ void MotorSafetyHelper::SetSafetyEnabled(bool enabled) { * @return True if motor safety is enforced for this device */ bool MotorSafetyHelper::IsSafetyEnabled() const { - std::lock_guard sync(m_syncMutex); + std::lock_guard sync(m_syncMutex); return m_enabled; } @@ -131,7 +131,7 @@ bool MotorSafetyHelper::IsSafetyEnabled() const { * any that have timed out. */ void MotorSafetyHelper::CheckMotors() { - std::lock_guard sync(m_listMutex); + std::lock_guard sync(m_listMutex); for (auto elem : m_helperList) { elem->Check(); } diff --git a/wpilibc/src/main/native/cpp/Notifier.cpp b/wpilibc/src/main/native/cpp/Notifier.cpp index 48cef16b5a..b8c5c544f0 100644 --- a/wpilibc/src/main/native/cpp/Notifier.cpp +++ b/wpilibc/src/main/native/cpp/Notifier.cpp @@ -15,7 +15,7 @@ using namespace frc; -hal::priority_mutex Notifier::m_destructorMutex; +std::mutex Notifier::m_destructorMutex; /** * Create a Notifier for timer event notification. @@ -45,8 +45,8 @@ Notifier::~Notifier() { /* Acquire the mutex; this makes certain that the handler is not being * executed by the interrupt manager. */ - std::lock_guard lockStatic(Notifier::m_destructorMutex); - std::lock_guard lock(m_processMutex); + std::lock_guard lockStatic(Notifier::m_destructorMutex); + std::lock_guard lock(m_processMutex); } /** @@ -69,7 +69,7 @@ void Notifier::Notify(uint64_t currentTimeInt, HAL_NotifierHandle handle) { Notifier* notifier; { // Lock static mutex to grab the notifier param - std::lock_guard lock(Notifier::m_destructorMutex); + std::lock_guard lock(Notifier::m_destructorMutex); int32_t status = 0; auto notifierPointer = HAL_GetNotifierParam(handle, &status); if (notifierPointer == nullptr) return; @@ -96,7 +96,7 @@ void Notifier::Notify(uint64_t currentTimeInt, HAL_NotifierHandle handle) { * @param delay Seconds to wait before the handler is called. */ void Notifier::StartSingle(double delay) { - std::lock_guard sync(m_processMutex); + std::lock_guard sync(m_processMutex); m_periodic = false; m_period = delay; m_expirationTime = GetClock() + m_period; @@ -114,7 +114,7 @@ void Notifier::StartSingle(double delay) { * after the call to this method. */ void Notifier::StartPeriodic(double period) { - std::lock_guard sync(m_processMutex); + std::lock_guard sync(m_processMutex); m_periodic = true; m_period = period; m_expirationTime = GetClock() + m_period; @@ -137,6 +137,6 @@ void Notifier::Stop() { // Wait for a currently executing handler to complete before returning from // Stop() - std::lock_guard lockStatic(Notifier::m_destructorMutex); - std::lock_guard lock(m_processMutex); + std::lock_guard lockStatic(Notifier::m_destructorMutex); + std::lock_guard lock(m_processMutex); } diff --git a/wpilibc/src/main/native/cpp/PIDController.cpp b/wpilibc/src/main/native/cpp/PIDController.cpp index 7db1872f58..2aac12b910 100644 --- a/wpilibc/src/main/native/cpp/PIDController.cpp +++ b/wpilibc/src/main/native/cpp/PIDController.cpp @@ -91,7 +91,7 @@ void PIDController::Calculate() { PIDOutput* pidOutput; { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); pidInput = m_pidInput; pidOutput = m_pidOutput; enabled = m_enabled; @@ -101,7 +101,9 @@ void PIDController::Calculate() { if (pidOutput == nullptr) return; if (enabled) { - std::lock_guard sync(m_mutex); + double feedForward = CalculateFeedForward(); + + std::lock_guard sync(m_mutex); double input = pidInput->PIDGet(); double result; PIDOutput* pidOutput; @@ -121,7 +123,7 @@ void PIDController::Calculate() { } } - m_result = m_D * m_error + m_P * m_totalError + CalculateFeedForward(); + m_result = m_D * m_error + m_P * m_totalError + feedForward; } else { if (m_I != 0) { double potentialIGain = (m_totalError + m_error) * m_I; @@ -136,7 +138,7 @@ void PIDController::Calculate() { } m_result = m_P * m_error + m_I * m_totalError + - m_D * (m_error - m_prevError) + CalculateFeedForward(); + m_D * (m_error - m_prevError) + feedForward; } m_prevError = m_error; @@ -198,7 +200,7 @@ double PIDController::CalculateFeedForward() { */ void PIDController::SetPID(double p, double i, double d) { { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_P = p; m_I = i; m_D = d; @@ -221,7 +223,7 @@ void PIDController::SetPID(double p, double i, double d) { */ void PIDController::SetPID(double p, double i, double d, double f) { { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_P = p; m_I = i; m_D = d; @@ -240,7 +242,7 @@ void PIDController::SetPID(double p, double i, double d, double f) { * @return proportional coefficient */ double PIDController::GetP() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return m_P; } @@ -250,7 +252,7 @@ double PIDController::GetP() const { * @return integral coefficient */ double PIDController::GetI() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return m_I; } @@ -260,7 +262,7 @@ double PIDController::GetI() const { * @return differential coefficient */ double PIDController::GetD() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return m_D; } @@ -270,7 +272,7 @@ double PIDController::GetD() const { * @return Feed forward coefficient */ double PIDController::GetF() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return m_F; } @@ -282,7 +284,7 @@ double PIDController::GetF() const { * @return the latest calculated output */ double PIDController::Get() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return m_result; } @@ -296,7 +298,7 @@ double PIDController::Get() const { * @param continuous true turns on continuous, false turns off continuous */ void PIDController::SetContinuous(bool continuous) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_continuous = continuous; } @@ -308,7 +310,7 @@ void PIDController::SetContinuous(bool continuous) { */ void PIDController::SetInputRange(double minimumInput, double maximumInput) { { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_minimumInput = minimumInput; m_maximumInput = maximumInput; } @@ -323,7 +325,7 @@ void PIDController::SetInputRange(double minimumInput, double maximumInput) { * @param maximumOutput the maximum value to write to the output */ void PIDController::SetOutputRange(double minimumOutput, double maximumOutput) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_minimumOutput = minimumOutput; m_maximumOutput = maximumOutput; } @@ -337,7 +339,7 @@ void PIDController::SetOutputRange(double minimumOutput, double maximumOutput) { */ void PIDController::SetSetpoint(double setpoint) { { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); if (m_maximumInput > m_minimumInput) { if (setpoint > m_maximumInput) @@ -364,7 +366,7 @@ void PIDController::SetSetpoint(double setpoint) { * @return the current setpoint */ double PIDController::GetSetpoint() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return m_setpoint; } @@ -374,7 +376,7 @@ double PIDController::GetSetpoint() const { * @return the change in setpoint over time */ double PIDController::GetDeltaSetpoint() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return (m_setpoint - m_prevSetpoint) / m_setpointTimer.Get(); } @@ -386,7 +388,7 @@ double PIDController::GetDeltaSetpoint() const { double PIDController::GetError() const { double setpoint = GetSetpoint(); { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return GetContinuousError(setpoint - m_pidInput->PIDGet()); } } @@ -417,7 +419,7 @@ PIDSourceType PIDController::GetPIDSourceType() const { double PIDController::GetAvgError() const { double avgError = 0; { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); // Don't divide by zero. if (m_buf.size()) avgError = m_bufTotal / m_buf.size(); } @@ -431,7 +433,7 @@ double PIDController::GetAvgError() const { * @param percentage error which is tolerable */ void PIDController::SetTolerance(double percent) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_toleranceType = kPercentTolerance; m_tolerance = percent; } @@ -443,7 +445,7 @@ void PIDController::SetTolerance(double percent) { * @param percentage error which is tolerable */ void PIDController::SetAbsoluteTolerance(double absTolerance) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_toleranceType = kAbsoluteTolerance; m_tolerance = absTolerance; } @@ -455,7 +457,7 @@ void PIDController::SetAbsoluteTolerance(double absTolerance) { * @param percentage error which is tolerable */ void PIDController::SetPercentTolerance(double percent) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_toleranceType = kPercentTolerance; m_tolerance = percent; } @@ -471,7 +473,7 @@ void PIDController::SetPercentTolerance(double percent) { * @param bufLength Number of previous cycles to average. Defaults to 1. */ void PIDController::SetToleranceBuffer(int bufLength) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_bufLength = bufLength; // Cut the buffer down to size if needed. @@ -493,9 +495,14 @@ void PIDController::SetToleranceBuffer(int bufLength) { * This will return false until at least one input value has been computed. */ bool PIDController::OnTarget() const { - std::lock_guard sync(m_mutex); - if (m_buf.size() == 0) return false; + { + std::lock_guard sync(m_mutex); + if (m_buf.size() == 0) return false; + } + double error = GetAvgError(); + + std::lock_guard sync(m_mutex); switch (m_toleranceType) { case kPercentTolerance: return std::fabs(error) < @@ -516,7 +523,7 @@ bool PIDController::OnTarget() const { */ void PIDController::Enable() { { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_enabled = true; } @@ -528,7 +535,7 @@ void PIDController::Enable() { */ void PIDController::Disable() { { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_pidOutput->PIDWrite(0); m_enabled = false; } @@ -540,7 +547,7 @@ void PIDController::Disable() { * Return true if PIDController is enabled. */ bool PIDController::IsEnabled() const { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); return m_enabled; } @@ -550,7 +557,7 @@ bool PIDController::IsEnabled() const { void PIDController::Reset() { Disable(); - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_prevError = 0; m_totalError = 0; m_result = 0; @@ -579,7 +586,7 @@ void PIDController::InitTable(std::shared_ptr subtable) { m_pListener = m_pEntry.AddListener( [=](const nt::EntryNotification& event) { if (!event.value->IsDouble()) return; - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_P = event.value->GetDouble(); }, NT_NOTIFY_NEW | NT_NOTIFY_UPDATE); @@ -587,7 +594,7 @@ void PIDController::InitTable(std::shared_ptr subtable) { m_iListener = m_iEntry.AddListener( [=](const nt::EntryNotification& event) { if (!event.value->IsDouble()) return; - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_I = event.value->GetDouble(); }, NT_NOTIFY_NEW | NT_NOTIFY_UPDATE); @@ -595,7 +602,7 @@ void PIDController::InitTable(std::shared_ptr subtable) { m_dListener = m_dEntry.AddListener( [=](const nt::EntryNotification& event) { if (!event.value->IsDouble()) return; - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_D = event.value->GetDouble(); }, NT_NOTIFY_NEW | NT_NOTIFY_UPDATE); @@ -603,7 +610,7 @@ void PIDController::InitTable(std::shared_ptr subtable) { m_fListener = m_fEntry.AddListener( [=](const nt::EntryNotification& event) { if (!event.value->IsDouble()) return; - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_F = event.value->GetDouble(); }, NT_NOTIFY_NEW | NT_NOTIFY_UPDATE); diff --git a/wpilibc/src/main/native/cpp/Resource.cpp b/wpilibc/src/main/native/cpp/Resource.cpp index 85c907a89e..7f96ba9793 100644 --- a/wpilibc/src/main/native/cpp/Resource.cpp +++ b/wpilibc/src/main/native/cpp/Resource.cpp @@ -12,7 +12,7 @@ using namespace frc; -hal::priority_recursive_mutex Resource::m_createLock; +std::mutex Resource::m_createMutex; /** * Allocate storage for a new instance of Resource. @@ -22,7 +22,6 @@ hal::priority_recursive_mutex Resource::m_createLock; * elements - 1]. */ Resource::Resource(uint32_t elements) { - std::lock_guard sync(m_createLock); m_isAllocated = std::vector(elements, false); } @@ -37,9 +36,9 @@ Resource::Resource(uint32_t elements) { * track, that is, it will allocate resource numbers in the * range [0 .. elements - 1]. */ -/*static*/ void Resource::CreateResourceObject(std::unique_ptr& r, - uint32_t elements) { - std::lock_guard sync(m_createLock); +void Resource::CreateResourceObject(std::unique_ptr& r, + uint32_t elements) { + std::lock_guard sync(m_createMutex); if (!r) { r = std::make_unique(elements); } @@ -53,7 +52,7 @@ Resource::Resource(uint32_t elements) { * allocated. */ uint32_t Resource::Allocate(const std::string& resourceDesc) { - std::lock_guard sync(m_allocateLock); + std::lock_guard sync(m_allocateMutex); for (uint32_t i = 0; i < m_isAllocated.size(); i++) { if (!m_isAllocated[i]) { m_isAllocated[i] = true; @@ -71,7 +70,7 @@ uint32_t Resource::Allocate(const std::string& resourceDesc) { * verified unallocated, then returned. */ uint32_t Resource::Allocate(uint32_t index, const std::string& resourceDesc) { - std::lock_guard sync(m_allocateLock); + std::lock_guard sync(m_allocateMutex); if (index >= m_isAllocated.size()) { wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, resourceDesc); return std::numeric_limits::max(); @@ -92,7 +91,7 @@ uint32_t Resource::Allocate(uint32_t index, const std::string& resourceDesc) { * be reused somewhere else in the program. */ void Resource::Free(uint32_t index) { - std::unique_lock sync(m_allocateLock); + std::unique_lock sync(m_allocateMutex); if (index == std::numeric_limits::max()) return; if (index >= m_isAllocated.size()) { wpi_setWPIError(NotAllocated); diff --git a/wpilibc/src/main/native/cpp/Timer.cpp b/wpilibc/src/main/native/cpp/Timer.cpp index 4f965b031d..36b040b06a 100644 --- a/wpilibc/src/main/native/cpp/Timer.cpp +++ b/wpilibc/src/main/native/cpp/Timer.cpp @@ -83,7 +83,7 @@ double Timer::Get() const { double result; double currentTime = GetFPGATimestamp(); - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); if (m_running) { // If the current time is before the start time, then the FPGA clock // rolled over. Compensate by adding the ~71 minutes that it takes @@ -107,7 +107,7 @@ double Timer::Get() const { * now. */ void Timer::Reset() { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); m_accumulatedTime = 0; m_startTime = GetFPGATimestamp(); } @@ -119,7 +119,7 @@ void Timer::Reset() { * relative to the system clock. */ void Timer::Start() { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); if (!m_running) { m_startTime = GetFPGATimestamp(); m_running = true; @@ -136,7 +136,7 @@ void Timer::Start() { void Timer::Stop() { double temp = Get(); - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); if (m_running) { m_accumulatedTime = temp; m_running = false; @@ -153,7 +153,7 @@ void Timer::Stop() { */ bool Timer::HasPeriodPassed(double period) { if (Get() > period) { - std::lock_guard sync(m_mutex); + std::lock_guard sync(m_mutex); // Advance the start time by the period. m_startTime += period; // Don't set it to the current time... we want to avoid drift. diff --git a/wpilibc/src/main/native/include/Commands/Scheduler.h b/wpilibc/src/main/native/include/Commands/Scheduler.h index 12c4a7e334..e773c1f2f1 100644 --- a/wpilibc/src/main/native/include/Commands/Scheduler.h +++ b/wpilibc/src/main/native/include/Commands/Scheduler.h @@ -10,12 +10,11 @@ #include #include #include +#include #include #include #include -#include - #include "Commands/Command.h" #include "ErrorBase.h" #include "SmartDashboard/NamedSendable.h" @@ -54,11 +53,11 @@ class Scheduler : public ErrorBase, public NamedSendable { void ProcessCommandAddition(Command* command); Command::SubsystemSet m_subsystems; - hal::priority_mutex m_buttonsLock; + std::mutex m_buttonsLock; typedef std::vector ButtonVector; ButtonVector m_buttons; typedef std::vector CommandVector; - hal::priority_mutex m_additionsLock; + std::mutex m_additionsLock; CommandVector m_additions; typedef std::set CommandSet; CommandSet m_commands; diff --git a/wpilibc/src/main/native/include/DigitalGlitchFilter.h b/wpilibc/src/main/native/include/DigitalGlitchFilter.h index fc024ec440..9819c39a9c 100644 --- a/wpilibc/src/main/native/include/DigitalGlitchFilter.h +++ b/wpilibc/src/main/native/include/DigitalGlitchFilter.h @@ -10,8 +10,7 @@ #include #include - -#include +#include #include "DigitalSource.h" @@ -52,7 +51,7 @@ class DigitalGlitchFilter : public SensorBase { void DoAdd(DigitalSource* input, int requested_index); int m_channelIndex = -1; - static hal::priority_mutex m_mutex; + static std::mutex m_mutex; static std::array m_filterAllocated; }; diff --git a/wpilibc/src/main/native/include/DriverStation.h b/wpilibc/src/main/native/include/DriverStation.h index 7156f28c44..86117fa68b 100644 --- a/wpilibc/src/main/native/include/DriverStation.h +++ b/wpilibc/src/main/native/include/DriverStation.h @@ -9,11 +9,11 @@ #include #include +#include #include #include #include -#include #include #include "RobotState.h" @@ -116,7 +116,7 @@ class DriverStation : public SensorBase, public RobotStateInterface { std::thread m_dsThread; std::atomic m_isRunning{false}; - mutable hal::priority_mutex m_joystickDataMutex; + mutable std::mutex m_joystickDataMutex; // Robot state status variables bool m_userInDisabled = false; @@ -127,7 +127,7 @@ class DriverStation : public SensorBase, public RobotStateInterface { // Control word variables mutable HAL_ControlWord m_controlWordCache; mutable std::chrono::steady_clock::time_point m_lastControlWordUpdate; - mutable hal::priority_mutex m_controlWordMutex; + mutable std::mutex m_controlWordMutex; double m_nextMessageTime = 0; }; diff --git a/wpilibc/src/main/native/include/ErrorBase.h b/wpilibc/src/main/native/include/ErrorBase.h index b6635d393f..5ef5f2c329 100644 --- a/wpilibc/src/main/native/include/ErrorBase.h +++ b/wpilibc/src/main/native/include/ErrorBase.h @@ -7,7 +7,8 @@ #pragma once -#include +#include + #include #include "Base.h" @@ -114,7 +115,7 @@ class ErrorBase { protected: mutable Error m_error; // TODO: Replace globalError with a global list of all errors. - static hal::priority_mutex _globalErrorMutex; + static std::mutex _globalErrorMutex; static Error _globalError; }; diff --git a/wpilibc/src/main/native/include/MotorSafetyHelper.h b/wpilibc/src/main/native/include/MotorSafetyHelper.h index 2d41369e20..dbf4af8149 100644 --- a/wpilibc/src/main/native/include/MotorSafetyHelper.h +++ b/wpilibc/src/main/native/include/MotorSafetyHelper.h @@ -7,10 +7,9 @@ #pragma once +#include #include -#include - #include "ErrorBase.h" namespace frc { @@ -38,13 +37,13 @@ class MotorSafetyHelper : public ErrorBase { // the FPGA clock value when this motor has expired double m_stopTime; // protect accesses to the state for this object - mutable hal::priority_recursive_mutex m_syncMutex; + mutable std::mutex m_syncMutex; // the object that is using the helper MotorSafety* m_safeObject; // List of all existing MotorSafetyHelper objects. static std::set m_helperList; // protect accesses to the list of helpers - static hal::priority_recursive_mutex m_listMutex; + static std::mutex m_listMutex; }; } // namespace frc diff --git a/wpilibc/src/main/native/include/Notifier.h b/wpilibc/src/main/native/include/Notifier.h index 5c3c9351cd..d77246aeee 100644 --- a/wpilibc/src/main/native/include/Notifier.h +++ b/wpilibc/src/main/native/include/Notifier.h @@ -11,10 +11,10 @@ #include #include +#include #include #include -#include #include "ErrorBase.h" @@ -47,9 +47,9 @@ class Notifier : public ErrorBase { static void Notify(uint64_t currentTimeInt, HAL_NotifierHandle handle); // used to constrain execution between destructors and callback - static hal::priority_mutex m_destructorMutex; + static std::mutex m_destructorMutex; // held while updating process information - hal::priority_mutex m_processMutex; + std::mutex m_processMutex; // HAL handle, atomic for proper destruction std::atomic m_notifier{0}; // address of the handler diff --git a/wpilibc/src/main/native/include/PIDController.h b/wpilibc/src/main/native/include/PIDController.h index 04cd795b00..7d657a6fe6 100644 --- a/wpilibc/src/main/native/include/PIDController.h +++ b/wpilibc/src/main/native/include/PIDController.h @@ -9,11 +9,10 @@ #include #include +#include #include #include -#include - #include "Base.h" #include "Controller.h" #include "LiveWindow/LiveWindow.h" @@ -148,7 +147,7 @@ class PIDController : public LiveWindowSendable, public PIDInterface { std::queue m_buf; double m_bufTotal = 0; - mutable hal::priority_recursive_mutex m_mutex; + mutable std::mutex m_mutex; std::unique_ptr m_controlLoop; Timer m_setpointTimer; diff --git a/wpilibc/src/main/native/include/Resource.h b/wpilibc/src/main/native/include/Resource.h index c0e36ef890..057505929b 100644 --- a/wpilibc/src/main/native/include/Resource.h +++ b/wpilibc/src/main/native/include/Resource.h @@ -10,11 +10,10 @@ #include #include +#include #include #include -#include - #include "ErrorBase.h" namespace frc { @@ -44,9 +43,9 @@ class Resource : public ErrorBase { private: std::vector m_isAllocated; - hal::priority_recursive_mutex m_allocateLock; + std::mutex m_allocateMutex; - static hal::priority_recursive_mutex m_createLock; + static std::mutex m_createMutex; }; } // namespace frc diff --git a/wpilibc/src/main/native/include/Timer.h b/wpilibc/src/main/native/include/Timer.h index 26c843138c..feb61e6379 100644 --- a/wpilibc/src/main/native/include/Timer.h +++ b/wpilibc/src/main/native/include/Timer.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include "Base.h" @@ -52,7 +52,7 @@ class Timer { double m_startTime = 0.0; double m_accumulatedTime = 0.0; bool m_running = false; - mutable hal::priority_mutex m_mutex; + mutable std::mutex m_mutex; }; } // namespace frc diff --git a/wpilibcIntegrationTests/src/FRCUserProgram/cpp/ConditionVariableTest.cpp b/wpilibcIntegrationTests/src/FRCUserProgram/cpp/ConditionVariableTest.cpp deleted file mode 100644 index 49dd7069ff..0000000000 --- a/wpilibcIntegrationTests/src/FRCUserProgram/cpp/ConditionVariableTest.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include - -#include -#include - -#include "TestBench.h" -#include "gtest/gtest.h" - -namespace wpilib { -namespace testing { - -// Tests that the condition variable class which we wrote ourselves actually -// does work. -class ConditionVariableTest : public ::testing::Test { - protected: - typedef std::unique_lock priority_lock; - - // Condition variable to test. - hal::priority_condition_variable m_cond; - - // Mutex to pass to condition variable when waiting. - hal::priority_mutex m_mutex; - - // flags for testing when threads are completed. - std::atomic m_done1{false}, m_done2{false}; - // Threads to use for testing. We want multiple threads to ensure that it - // behaves correctly when multiple processes are waiting on a signal. - std::thread m_watcher1, m_watcher2; - - // Information for when running with predicates. - std::atomic m_pred_var{false}; - - void ShortSleep(uint32_t time = 10) { - std::this_thread::sleep_for(std::chrono::milliseconds(time)); - } - - // Start up the given threads with a wait function. The wait function should - // call some version of m_cond.wait and should take as an argument a reference - // to an std::atomic which it will set to true when it is ready to have - // join called on it. - template - void StartThreads(Function wait) { - m_watcher1 = std::thread(wait, std::ref(m_done1)); - m_watcher2 = std::thread(wait, std::ref(m_done2)); - - // Wait briefly to let the lock be unlocked. - ShortSleep(); - bool locked = m_mutex.try_lock(); - if (locked) m_mutex.unlock(); - EXPECT_TRUE(locked) << "The condition variable failed to unlock the lock."; - } - - void NotifyAll() { m_cond.notify_all(); } - void NotifyOne() { m_cond.notify_one(); } - - // Test that all the threads are notified by a notify_all() call. - void NotifyAllTest() { - NotifyAll(); - // Wait briefly to let the lock be re-locked. - ShortSleep(); - EXPECT_TRUE(m_done1) << "watcher1 failed to be notified."; - EXPECT_TRUE(m_done2) << "watcher2 failed to be notified."; - } - - // For use when testing predicates. First tries signalling the threads with - // the predicate set to false (and ensures that they do not activate) and then - // tests with the predicate set to true. - void PredicateTest() { - m_pred_var = false; - NotifyAll(); - ShortSleep(); - EXPECT_FALSE(m_done1) << "watcher1 didn't pay attention to its predicate."; - EXPECT_FALSE(m_done2) << "watcher2 didn't pay attention to its predicate."; - m_pred_var = true; - NotifyAllTest(); - } - - // Used by the WaitFor and WaitUntil tests to test that, without a predicate, - // the timeout works properly. - void WaitTimeTest(bool wait_for) { - std::atomic timed_out{true}; - auto wait_until = [this, &timed_out, wait_for](std::atomic& done) { - priority_lock lock(m_mutex); - done = false; - if (wait_for) { - auto wait_time = std::chrono::milliseconds(100); - timed_out = m_cond.wait_for(lock, wait_time) == std::cv_status::timeout; - } else { - auto wait_time = - std::chrono::system_clock::now() + std::chrono::milliseconds(100); - timed_out = - m_cond.wait_until(lock, wait_time) == std::cv_status::timeout; - } - EXPECT_TRUE(lock.owns_lock()) - << "The condition variable should have reacquired the lock."; - done = true; - }; - - // First, test without timing out. - timed_out = true; - StartThreads(wait_until); - - NotifyAllTest(); - EXPECT_FALSE(timed_out) << "The watcher should not have timed out."; - - TearDown(); - - // Next, test and time out. - timed_out = false; - StartThreads(wait_until); - - ShortSleep(110); - - EXPECT_TRUE(m_done1) << "watcher1 should have timed out."; - EXPECT_TRUE(m_done2) << "watcher2 should have timed out."; - EXPECT_TRUE(timed_out) << "The watcher should have timed out."; - } - - // For use with tests that have a timeout and a predicate. - void WaitTimePredicateTest(bool wait_for) { - // The condition_variable return value from the wait_for or wait_until - // function should in the case of having a predicate, by a boolean. If the - // predicate is true, then the return value will always be true. If the - // condition times out and, at the time of the timeout, the predicate is - // false, the return value will be false. - std::atomic retval{true}; - auto predicate = [this]() -> bool { return m_pred_var; }; - auto wait_until = [this, &retval, predicate, - wait_for](std::atomic& done) { - priority_lock lock(m_mutex); - done = false; - if (wait_for) { - auto wait_time = std::chrono::milliseconds(100); - retval = m_cond.wait_for(lock, wait_time, predicate); - } else { - auto wait_time = - std::chrono::system_clock::now() + std::chrono::milliseconds(100); - retval = m_cond.wait_until(lock, wait_time, predicate); - } - EXPECT_TRUE(lock.owns_lock()) - << "The condition variable should have reacquired the lock."; - done = true; - }; - - // Test without timing out and with the predicate set to true. - retval = true; - m_pred_var = true; - StartThreads(wait_until); - - NotifyAllTest(); - EXPECT_TRUE(retval) << "The watcher should not have timed out."; - - TearDown(); - - // Test with timing out and with the predicate set to true. - retval = false; - m_pred_var = false; - StartThreads(wait_until); - - ShortSleep(110); - - EXPECT_TRUE(m_done1) << "watcher1 should have finished."; - EXPECT_TRUE(m_done2) << "watcher2 should have finished."; - EXPECT_FALSE(retval) << "The watcher should have timed out."; - - TearDown(); - - // Test without timing out and run the PredicateTest(). - retval = false; - StartThreads(wait_until); - - PredicateTest(); - EXPECT_TRUE(retval) << "The return value should have been true."; - - TearDown(); - - // Test with timing out and the predicate set to true while we are waiting - // for the condition variable to time out. - retval = true; - StartThreads(wait_until); - ShortSleep(); - m_pred_var = true; - ShortSleep(110); - EXPECT_TRUE(retval) << "The return value should have been true."; - } - - virtual void TearDown() { - // If a thread has not completed, then continuing will cause the tests to - // hang forever and could cause issues. If we don't call detach, then - // std::terminate is called and all threads are terminated. - // Detaching is non-optimal, but should allow the rest of the tests to run - // before anything drastic occurs. - if (m_done1) - m_watcher1.join(); - else - m_watcher1.detach(); - if (m_done2) - m_watcher2.join(); - else - m_watcher2.detach(); - } -}; - -TEST_F(ConditionVariableTest, NotifyAll) { - auto wait = [this](std::atomic& done) { - priority_lock lock(m_mutex); - done = false; - m_cond.wait(lock); - EXPECT_TRUE(lock.owns_lock()) - << "The condition variable should have reacquired the lock."; - done = true; - }; - - StartThreads(wait); - - NotifyAllTest(); -} - -TEST_F(ConditionVariableTest, NotifyOne) { - auto wait = [this](std::atomic& done) { - priority_lock lock(m_mutex); - done = false; - m_cond.wait(lock); - EXPECT_TRUE(lock.owns_lock()) - << "The condition variable should have reacquired the lock."; - done = true; - }; - - StartThreads(wait); - - NotifyOne(); - // Wait briefly to let things settle. - ShortSleep(); - EXPECT_TRUE(m_done1 ^ m_done2) << "Only one thread should've been notified."; - NotifyOne(); - ShortSleep(); - EXPECT_TRUE(m_done2 && m_done2) << "Both threads should've been notified."; -} - -TEST_F(ConditionVariableTest, WaitWithPredicate) { - auto predicate = [this]() -> bool { return m_pred_var; }; - auto wait_predicate = [this, predicate](std::atomic& done) { - priority_lock lock(m_mutex); - done = false; - m_cond.wait(lock, predicate); - EXPECT_TRUE(lock.owns_lock()) - << "The condition variable should have reacquired the lock."; - done = true; - }; - - StartThreads(wait_predicate); - - PredicateTest(); -} - -TEST_F(ConditionVariableTest, WaitUntil) { WaitTimeTest(false); } - -TEST_F(ConditionVariableTest, WaitUntilWithPredicate) { - WaitTimePredicateTest(false); -} - -TEST_F(ConditionVariableTest, WaitFor) { WaitTimeTest(true); } - -TEST_F(ConditionVariableTest, WaitForWithPredicate) { - WaitTimePredicateTest(true); -} - -TEST_F(ConditionVariableTest, NativeHandle) { - auto wait = [this](std::atomic& done) { - priority_lock lock(m_mutex); - done = false; - m_cond.wait(lock); - EXPECT_TRUE(lock.owns_lock()) - << "The condition variable should have reacquired the lock."; - done = true; - }; - - StartThreads(wait); - - pthread_cond_t* native_handle = m_cond.native_handle(); - pthread_cond_broadcast(native_handle); - ShortSleep(); - EXPECT_TRUE(m_done1) << "watcher1 failed to be notified."; - EXPECT_TRUE(m_done2) << "watcher2 failed to be notified."; -} - -} // namespace testing -} // namespace wpilib