Remove priority mutex (#644)

* Removed hal::priority_condition_variable

* Replaced uses of priority mutexes with std::mutex and std::recursive_mutex

This allowed replacing a use of std::condition_variable_any with
std::condition_variable.

* Replaced all uses of std::recursive_mutex with std::mutex equivalents
This commit is contained in:
Tyler Veness
2017-09-28 23:32:35 -07:00
committed by Peter Johnson
parent 19addb04cf
commit dd66b23845
44 changed files with 390 additions and 746 deletions

View File

@@ -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<priority_recursive_mutex> sync(analogRegisterWindowMutex);
std::lock_guard<std::mutex> sync(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
return static_cast<int16_t>(analogInputSystem->readOutput(status));
@@ -262,7 +261,7 @@ int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
readSelect.Channel = port->channel;
readSelect.Averaged = true;
std::lock_guard<priority_recursive_mutex> sync(analogRegisterWindowMutex);
std::lock_guard<std::mutex> sync(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
return static_cast<int32_t>(analogInputSystem->readOutput(status));

View File

@@ -8,15 +8,15 @@
#include "AnalogInternal.h"
#include <atomic>
#include <mutex>
#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<tAI> analogInputSystem;
std::unique_ptr<tAO> analogOutputSystem;
@@ -35,7 +35,7 @@ bool analogSampleRateSet = false;
*/
void initializeAnalog(int32_t* status) {
if (analogSystemInitialized) return;
std::lock_guard<priority_recursive_mutex> sync(analogRegisterWindowMutex);
std::lock_guard<std::mutex> sync(analogRegisterWindowMutex);
if (analogSystemInitialized) return;
analogInputSystem.reset(tAI::create(status));
analogOutputSystem.reset(tAO::create(status));

View File

@@ -10,10 +10,10 @@
#include <stdint.h>
#include <memory>
#include <mutex>
#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<tAI> analogInputSystem;
extern std::unique_ptr<tAO> analogOutputSystem;
extern priority_recursive_mutex analogRegisterWindowMutex;
extern std::mutex analogRegisterWindowMutex;
extern bool analogSampleRateSet;
struct AnalogPort {

View File

@@ -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<HAL_DigitalPWMHandle, uint8_t,
kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>
@@ -54,7 +54,7 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
port->channel = static_cast<uint8_t>(channel);
std::lock_guard<priority_recursive_mutex> sync(digitalDIOMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(digitalDIOMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(digitalPwmMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(digitalDIOMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(digitalDIOMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(digitalDIOMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(digitalDIOMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(digitalDIOMutex);
std::lock_guard<std::mutex> sync(digitalDIOMutex);
hdrPeriod = digitalSystem->readFilterPeriodHdr(filterIndex, status);
if (*status == 0) {
mxpPeriod = digitalSystem->readFilterPeriodMXP(filterIndex, status);

View File

@@ -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<tDIO> digitalSystem;
std::unique_ptr<tRelay> relaySystem;
@@ -32,7 +31,7 @@ std::unique_ptr<tPWM> pwmSystem;
std::unique_ptr<tSPI> spiSystem;
static std::atomic<bool> digitalSystemsInitialized{false};
static hal::priority_mutex initializeMutex;
static std::mutex initializeMutex;
DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>
@@ -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<hal::priority_mutex> lock(initializeMutex);
std::lock_guard<std::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (digitalSystemsInitialized) return;

View File

@@ -10,6 +10,7 @@
#include <stdint.h>
#include <memory>
#include <mutex>
#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<tDIO> digitalSystem;
extern std::unique_ptr<tRelay> relaySystem;

View File

@@ -7,16 +7,16 @@
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <mutex>
#include <FRC_NetworkCommunication/FRCComm.h>
#include <llvm/raw_ostream.h>
#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<hal::priority_mutex> lock(msgMutex);
std::lock_guard<std::mutex> lock(msgMutex);
static std::string prevMsg[KEEP_MSGS];
static std::chrono::time_point<std::chrono::steady_clock>
prevMsgTime[KEEP_MSGS];
@@ -258,7 +258,7 @@ bool HAL_IsNewControlData(void) {
thread_local int lastCount{-1};
int currentCount = 0;
{
std::unique_lock<hal::priority_mutex> lock(newDSDataAvailableMutex);
std::unique_lock<std::mutex> 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<double>(timeout);
std::unique_lock<hal::priority_mutex> lock(newDSDataAvailableMutex);
std::unique_lock<std::mutex> 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<hal::priority_mutex> lock(newDSDataAvailableMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(initializeMutex);
std::lock_guard<std::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (initialized) return;

View File

@@ -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<tGlobal> global;
static std::unique_ptr<tSysWatchdog> 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<hal::priority_mutex> lock(timeMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(initializeMutex);
std::lock_guard<std::mutex> 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

View File

@@ -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<priority_recursive_mutex> sync(lock);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(lock);
std::lock_guard<std::mutex> sync(lock);
return i2clib_writeread(
handle, deviceAddress, reinterpret_cast<const char*>(dataToSend),
static_cast<int32_t>(sendSize), reinterpret_cast<char*>(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<priority_recursive_mutex> sync(lock);
std::lock_guard<std::mutex> sync(lock);
return i2clib_write(handle, deviceAddress,
reinterpret_cast<const char*>(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<priority_recursive_mutex> sync(lock);
std::lock_guard<std::mutex> sync(lock);
return i2clib_read(handle, deviceAddress, reinterpret_cast<char*>(buffer),
static_cast<int32_t>(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<priority_recursive_mutex> sync(lock);
std::lock_guard<std::mutex> sync(lock);
if ((port == 0 ? i2COnboardObjCount-- : i2CMXPObjCount--) == 0) {
int32_t handle = port == 0 ? i2COnBoardHandle : i2CMXPHandle;
i2clib_close(handle);

View File

@@ -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<tAlarm> notifierAlarm;
static std::unique_ptr<tInterruptManager> notifierManager;
static uint64_t closestTrigger = UINT64_MAX;
@@ -101,12 +100,11 @@ static UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
HAL_HandleEnum::Notifier>
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<Notifier> notifierPointer,
uint64_t triggerTime, int32_t* status) {
std::lock_guard<priority_recursive_mutex> 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<Notifier> notifierPointer,
}
static void alarmCallback(uint32_t, void*) {
std::unique_lock<priority_recursive_mutex> sync(notifierMutex);
std::unique_lock<std::mutex> 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<hal::priority_mutex> sync(notifierInterruptMutex);
std::lock_guard<std::mutex> sync(notifierInterruptMutex);
// create manager and alarm if not already created
if (!notifierManager) {
notifierManager = std::make_unique<tInterruptManager>(
@@ -196,7 +194,7 @@ HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
if (!notifierAlarm) notifierAlarm.reset(tAlarm::create(status));
}
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
std::lock_guard<std::mutex> sync(notifierMutex);
std::shared_ptr<Notifier> notifier = std::make_shared<Notifier>();
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<priority_recursive_mutex> sync(notifierMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(notifierInterruptMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(notifierMutex);
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(notifierMutex);
std::lock_guard<std::mutex> sync(notifierMutex);
auto notifier = notifierHandles.Get(notifierHandle);
if (!notifier) return;
notifier->triggerTime = UINT64_MAX;

View File

@@ -27,7 +27,7 @@ static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
relayHandles;
// Create a mutex to protect changes to the relay values
static priority_recursive_mutex digitalRelayMutex;
static std::mutex digitalRelayMutex;
extern "C" {
@@ -92,7 +92,7 @@ void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
*status = HAL_HANDLE_ERROR;
return;
}
std::lock_guard<priority_recursive_mutex> sync(digitalRelayMutex);
std::lock_guard<std::mutex> sync(digitalRelayMutex);
uint8_t relays = 0;
if (port->fwd) {
relays = relaySystem->readValue_Forward(status);

View File

@@ -7,7 +7,9 @@
#include "HAL/SPI.h"
#include <array>
#include <atomic>
#include <mutex>
#include <llvm/raw_ostream.h>
#include <spilib/spi-lib.h>
@@ -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<std::mutex, kSpiMaxHandles> spiHandleMutexes;
static std::array<std::mutex, kSpiMaxHandles> spiApiMutexes;
static std::array<std::mutex, kSpiMaxHandles> spiAccumulatorMutexes;
// MXP SPI does not count towards this
std::atomic<int32_t> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
return -1;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
return spilib_writeread(
HAL_GetSPIHandle(port), reinterpret_cast<const char*>(dataToSend),
reinterpret_cast<char*>(dataReceived), static_cast<int32_t>(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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
return -1;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
return spilib_write(HAL_GetSPIHandle(port),
reinterpret_cast<const char*>(dataToSend),
static_cast<int32_t>(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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
return -1;
}
std::lock_guard<std::mutex> sync(spiApiMutexes[port]);
return spilib_read(HAL_GetSPIHandle(port), reinterpret_cast<char*>(buffer),
static_cast<int32_t>(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<priority_recursive_mutex> 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<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
return 0;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(accum->port));
spilib_writeread(
HAL_GetSPIHandle(accum->port), reinterpret_cast<const char*>(accum->cmd),
reinterpret_cast<char*>(resp_b), static_cast<int32_t>(accum->xferSize));
{
std::lock_guard<std::mutex> sync(spiApiMutexes[accum->port]);
spilib_writeread(HAL_GetSPIHandle(accum->port),
reinterpret_cast<const char*>(accum->cmd),
reinterpret_cast<char*>(resp_b),
static_cast<int32_t>(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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port > 4) return;
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
if (!spiAccumulators[port])
spiAccumulators[port] = std::make_unique<SPIAccumulator>();
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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return 0;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return 0;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return 0;
}
std::lock_guard<std::mutex> 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<priority_recursive_mutex> sync(spiGetMutex(port));
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
return;
}
std::lock_guard<std::mutex> sync(spiAccumulatorMutexes[port]);
SPIAccumulator* accum = spiAccumulators[port].get();
if (!accum) {
*status = NULL_PARAMETER;

View File

@@ -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<ViSession*>(&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<hal::priority_mutex> lock(m_nameMutex);
std::lock_guard<std::mutex> lock(m_nameMutex);
std::string portString = m_usbNames[port - 2];

View File

@@ -9,6 +9,7 @@
#include <stdint.h>
#include <mutex>
#include <string>
#include <vector>
@@ -16,7 +17,6 @@
#include <llvm/SmallVector.h>
#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

View File

@@ -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 <condition_variable>
#include <memory>
#include <utility>
#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<std::mutex>()) {}
~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<std::mutex> lock(*m_mutex);
m_cond.notify_one();
}
void notify_all() noexcept {
std::lock_guard<std::mutex> lock(*m_mutex);
m_cond.notify_all();
}
template <typename Lock>
void wait(Lock& _lock) {
std::shared_ptr<std::mutex> _mutex = m_mutex;
std::unique_lock<std::mutex> my_lock(*_mutex);
Unlock<Lock> 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<std::mutex> my_lock2(std::move(my_lock));
m_cond.wait(my_lock2);
}
template <typename Lock, typename Predicate>
void wait(Lock& lock, Predicate p) {
while (!p()) {
wait(lock);
}
}
template <typename Lock, typename Clock, typename Duration>
std::cv_status wait_until(
Lock& _lock, const std::chrono::time_point<Clock, Duration>& atime) {
std::shared_ptr<std::mutex> _mutex = m_mutex;
std::unique_lock<std::mutex> my_lock(*_mutex);
Unlock<Lock> 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<std::mutex> my_lock2(std::move(my_lock));
return m_cond.wait_until(my_lock2, atime);
}
template <typename Lock, typename Clock, typename Duration,
typename Predicate>
bool wait_until(Lock& lock,
const std::chrono::time_point<Clock, Duration>& atime,
Predicate p) {
while (!p()) {
if (wait_until(lock, atime) == std::cv_status::timeout) {
return p();
}
}
return true;
}
template <typename Lock, typename Rep, typename Period>
std::cv_status wait_for(Lock& lock,
const std::chrono::duration<Rep, Period>& rtime) {
return wait_until(lock, clock::now() + rtime);
}
template <typename Lock, typename Rep, typename Period, typename Predicate>
bool wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& 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<std::mutex> m_mutex;
// scoped unlock - unlocks in ctor, re-locks in dtor
template <typename Lock>
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

View File

@@ -11,11 +11,11 @@
#include <array>
#include <memory>
#include <mutex>
#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<std::shared_ptr<TStruct>, size> m_structures;
std::array<hal::priority_mutex, size> m_handleMutexes;
std::array<std::mutex, size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size>
@@ -59,7 +59,7 @@ THandle DigitalHandleResource<THandle, TStruct, size>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<TStruct> DigitalHandleResource<THandle, TStruct, size>::Get(
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<THandle, TStruct, size>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
m_structures[index].reset();
}
template <typename THandle, typename TStruct, int16_t size>
void DigitalHandleResource<THandle, TStruct, size>::ResetHandles() {
for (int i = 0; i < size; i++) {
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[i]);
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -51,7 +51,7 @@ class IndexedClassedHandleResource : public HandleBase {
private:
std::array<std::shared_ptr<TStruct>[], size> m_structures;
std::array<hal::priority_mutex[], size> m_handleMutexes;
std::array<std::mutex[], size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size,
@@ -59,7 +59,7 @@ template <typename THandle, typename TStruct, int16_t size,
IndexedClassedHandleResource<THandle, TStruct, size,
enumValue>::IndexedClassedHandleResource() {
m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
m_handleMutexes = std::make_unique<hal::priority_mutex[]>(size);
m_handleMutexes = std::make_unique<std::mutex[]>(size);
}
template <typename THandle, typename TStruct, int16_t size,
@@ -72,7 +72,7 @@ IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<TStruct> IndexedClassedHandleResource<
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -114,7 +114,7 @@ template <typename THandle, typename TStruct, int16_t size,
void IndexedClassedHandleResource<THandle, TStruct, size,
enumValue>::ResetHandles() {
for (int i = 0; i < size; i++) {
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[i]);
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -11,11 +11,11 @@
#include <array>
#include <memory>
#include <mutex>
#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<std::shared_ptr<TStruct>, size> m_structures;
std::array<hal::priority_mutex, size> m_handleMutexes;
std::array<std::mutex, size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size,
@@ -61,7 +61,7 @@ THandle IndexedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<THandle, TStruct, size, enumValue>::Get(THandle handle) {
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> sync(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -102,7 +102,7 @@ template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
void IndexedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
for (int i = 0; i < size; i++) {
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[i]);
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
HandleBase::ResetHandles();

View File

@@ -11,10 +11,10 @@
#include <array>
#include <memory>
#include <mutex>
#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<std::shared_ptr<TStruct>, size> m_structures;
std::array<hal::priority_mutex, size> m_handleMutexes;
hal::priority_mutex m_allocateMutex;
std::array<std::mutex, size> m_handleMutexes;
std::mutex m_allocateMutex;
};
template <typename THandle, typename TStruct, int16_t size,
@@ -58,12 +58,12 @@ THandle
LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
std::shared_ptr<TStruct> toSet) {
// globally lock to loop through indices
std::lock_guard<hal::priority_mutex> sync(m_allocateMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_handleMutexes[i]);
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
m_structures[i] = toSet;
return static_cast<THandle>(createHandle(i, enumValue, m_version));
}
@@ -80,7 +80,7 @@ std::shared_ptr<TStruct> LimitedClassedHandleResource<
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<hal::priority_mutex> sync(m_allocateMutex);
std::lock_guard<hal::priority_mutex> lock(m_handleMutexes[index]);
std::lock_guard<std::mutex> sync(m_allocateMutex);
std::lock_guard<std::mutex> lock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -104,9 +104,9 @@ template <typename THandle, typename TStruct, int16_t size,
void LimitedClassedHandleResource<THandle, TStruct, size,
enumValue>::ResetHandles() {
{
std::lock_guard<hal::priority_mutex> lock(m_allocateMutex);
std::lock_guard<std::mutex> lock(m_allocateMutex);
for (int i = 0; i < size; i++) {
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[i]);
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
}

View File

@@ -11,10 +11,10 @@
#include <array>
#include <memory>
#include <mutex>
#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<std::shared_ptr<TStruct>, size> m_structures;
std::array<hal::priority_mutex, size> m_handleMutexes;
hal::priority_mutex m_allocateMutex;
std::array<std::mutex, size> m_handleMutexes;
std::mutex m_allocateMutex;
};
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
THandle LimitedHandleResource<THandle, TStruct, size, enumValue>::Allocate() {
// globally lock to loop through indices
std::lock_guard<hal::priority_mutex> sync(m_allocateMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_handleMutexes[i]);
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
m_structures[i] = std::make_shared<TStruct>();
return static_cast<THandle>(createHandle(i, enumValue, m_version));
}
@@ -76,7 +76,7 @@ LimitedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
if (index < 0 || index >= size) {
return nullptr;
}
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
std::lock_guard<std::mutex> 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<THandle, TStruct, size, enumValue>::Free(
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
if (index < 0 || index >= size) return;
// lock and deallocated handle
std::lock_guard<hal::priority_mutex> sync(m_allocateMutex);
std::lock_guard<hal::priority_mutex> lock(m_handleMutexes[index]);
std::lock_guard<std::mutex> sync(m_allocateMutex);
std::lock_guard<std::mutex> lock(m_handleMutexes[index]);
m_structures[index].reset();
}
@@ -99,9 +99,9 @@ template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
void LimitedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
{
std::lock_guard<hal::priority_mutex> lock(m_allocateMutex);
std::lock_guard<std::mutex> lock(m_allocateMutex);
for (int i = 0; i < size; i++) {
std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[i]);
std::lock_guard<std::mutex> sync(m_handleMutexes[i]);
m_structures[i].reset();
}
}

View File

@@ -10,10 +10,10 @@
#include <stdint.h>
#include <memory>
#include <mutex>
#include <vector>
#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<std::shared_ptr<TStruct>> m_structures;
hal::priority_mutex m_handleMutex;
std::mutex m_handleMutex;
};
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
THandle UnlimitedHandleResource<THandle, TStruct, enumValue>::Allocate(
std::shared_ptr<TStruct> structure) {
std::lock_guard<hal::priority_mutex> sync(m_handleMutex);
std::lock_guard<std::mutex> sync(m_handleMutex);
size_t i;
for (i = 0; i < m_structures.size(); i++) {
if (m_structures[i] == nullptr) {
@@ -73,7 +73,7 @@ template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
std::shared_ptr<TStruct>
UnlimitedHandleResource<THandle, TStruct, enumValue>::Get(THandle handle) {
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
std::lock_guard<hal::priority_mutex> sync(m_handleMutex);
std::lock_guard<std::mutex> sync(m_handleMutex);
if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
return nullptr;
return m_structures[index];
@@ -83,7 +83,7 @@ template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
THandle handle) {
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
std::lock_guard<hal::priority_mutex> sync(m_handleMutex);
std::lock_guard<std::mutex> sync(m_handleMutex);
if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) return;
m_structures[index].reset();
}
@@ -91,7 +91,7 @@ void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
{
std::lock_guard<hal::priority_mutex> lock(m_handleMutex);
std::lock_guard<std::mutex> lock(m_handleMutex);
for (size_t i = 0; i < m_structures.size(); i++) {
m_structures[i].reset();
}

View File

@@ -8,20 +8,19 @@
#include "HAL/handles/HandlesInternal.h"
#include <algorithm>
#include <mutex>
#include <llvm/SmallVector.h>
#include "HAL/cpp/priority_mutex.h"
namespace hal {
static llvm::SmallVector<HandleBase*, 32> globalHandles;
static priority_mutex& GetGlobalHandleMutex() {
static priority_mutex globalHandleMutex;
static std::mutex& GetGlobalHandleMutex() {
static std::mutex globalHandleMutex;
return globalHandleMutex;
}
HandleBase::HandleBase() {
std::lock_guard<priority_mutex> lock(GetGlobalHandleMutex());
std::lock_guard<std::mutex> 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<priority_mutex> lock(GetGlobalHandleMutex());
std::lock_guard<std::mutex> 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<priority_mutex> lock(GetGlobalHandleMutex());
std::unique_lock<std::mutex> lock(GetGlobalHandleMutex());
for (auto&& i : globalHandles) {
if (i != nullptr) {
lock.unlock();

View File

@@ -8,7 +8,6 @@
#include "AnalogInternal.h"
#include "HAL/AnalogInput.h"
#include "HAL/cpp/priority_mutex.h"
#include "PortsInternal.h"
namespace hal {

View File

@@ -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 {

View File

@@ -11,17 +11,17 @@
#include <pthread.h>
#endif
#include <condition_variable>
#include <cstdio>
#include <cstdlib>
#include <mutex>
#include <string>
#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<hal::priority_mutex> lock(msgMutex);
std::lock_guard<std::mutex> lock(msgMutex);
static std::string prevMsg[KEEP_MSGS];
static std::chrono::time_point<std::chrono::steady_clock>
prevMsgTime[KEEP_MSGS];
@@ -198,7 +198,7 @@ bool HAL_IsNewControlData(void) {
// worth the cycles to check.
int currentCount = 0;
{
std::unique_lock<hal::priority_mutex> lock(newDSDataAvailableMutex);
std::unique_lock<std::mutex> 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<double>(timeout);
std::unique_lock<hal::priority_mutex> lock(newDSDataAvailableMutex);
std::unique_lock<std::mutex> 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<hal::priority_mutex> lock(newDSDataAvailableMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(initializeMutex);
std::lock_guard<std::mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (initialized) return;

View File

@@ -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<hal::priority_mutex> sync(m_additionsLock);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_buttonsLock);
std::lock_guard<std::mutex> sync(m_buttonsLock);
m_buttons.push_back(button);
}
@@ -114,7 +114,7 @@ void Scheduler::Run() {
{
if (!m_enabled) return;
std::lock_guard<hal::priority_mutex> sync(m_buttonsLock);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_additionsLock);
std::lock_guard<std::mutex> sync(m_additionsLock);
for (auto additionsIter = m_additions.begin();
additionsIter != m_additions.end(); additionsIter++) {
ProcessCommandAddition(*additionsIter);

View File

@@ -23,10 +23,10 @@ using namespace frc;
std::array<bool, 3> DigitalGlitchFilter::m_filterAllocated = {
{false, false, false}};
hal::priority_mutex DigitalGlitchFilter::m_mutex;
std::mutex DigitalGlitchFilter::m_mutex;
DigitalGlitchFilter::DigitalGlitchFilter() {
std::lock_guard<hal::priority_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
m_filterAllocated[m_channelIndex] = false;
}
}

View File

@@ -90,7 +90,7 @@ double DriverStation::GetStickAxis(int stick, int axis) {
wpi_setWPIError(BadJoystickIndex);
return 0;
}
std::unique_lock<hal::priority_mutex> lock(m_joystickDataMutex);
std::unique_lock<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::unique_lock<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::unique_lock<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> lock(m_joystickDataMutex);
return static_cast<bool>(m_joystickDescriptor[stick].isXbox);
}
@@ -247,7 +247,7 @@ int DriverStation::GetJoystickType(int stick) const {
wpi_setWPIError(BadJoystickIndex);
return -1;
}
std::lock_guard<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> lock(m_joystickDataMutex);
return static_cast<int>(m_joystickDescriptor[stick].type);
}
@@ -261,7 +261,7 @@ std::string DriverStation::GetJoystickName(int stick) const {
if (stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
}
std::lock_guard<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(m_joystickDataMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(m_controlWordMutex);
std::lock_guard<std::mutex> lock(m_controlWordMutex);
// Update every 50 ms or on force.
if ((now - m_lastControlWordUpdate > std::chrono::milliseconds(50)) ||
force) {

View File

@@ -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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> mutex(_globalErrorMutex);
std::lock_guard<std::mutex> mutex(_globalErrorMutex);
return _globalError;
}

View File

@@ -18,7 +18,7 @@
using namespace frc;
std::set<MotorSafetyHelper*> 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<hal::priority_recursive_mutex> sync(m_listMutex);
std::lock_guard<std::mutex> sync(m_listMutex);
m_helperList.insert(this);
}
MotorSafetyHelper::~MotorSafetyHelper() {
std::lock_guard<hal::priority_recursive_mutex> sync(m_listMutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_syncMutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_syncMutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_syncMutex);
std::lock_guard<std::mutex> sync(m_syncMutex);
return m_expiration;
}
@@ -80,7 +80,7 @@ double MotorSafetyHelper::GetExpiration() const {
* timed out.
*/
bool MotorSafetyHelper::IsAlive() const {
std::lock_guard<hal::priority_recursive_mutex> sync(m_syncMutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_syncMutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_syncMutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_syncMutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_listMutex);
std::lock_guard<std::mutex> sync(m_listMutex);
for (auto elem : m_helperList) {
elem->Check();
}

View File

@@ -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<hal::priority_mutex> lockStatic(Notifier::m_destructorMutex);
std::lock_guard<hal::priority_mutex> lock(m_processMutex);
std::lock_guard<std::mutex> lockStatic(Notifier::m_destructorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lock(Notifier::m_destructorMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_processMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_processMutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> lockStatic(Notifier::m_destructorMutex);
std::lock_guard<hal::priority_mutex> lock(m_processMutex);
std::lock_guard<std::mutex> lockStatic(Notifier::m_destructorMutex);
std::lock_guard<std::mutex> lock(m_processMutex);
}

View File

@@ -91,7 +91,7 @@ void PIDController::Calculate() {
PIDOutput* pidOutput;
{
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
double feedForward = CalculateFeedForward();
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
return m_P;
}
@@ -250,7 +252,7 @@ double PIDController::GetP() const {
* @return integral coefficient
*/
double PIDController::GetI() const {
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
return m_I;
}
@@ -260,7 +262,7 @@ double PIDController::GetI() const {
* @return differential coefficient
*/
double PIDController::GetD() const {
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
if (m_buf.size() == 0) return false;
{
std::lock_guard<std::mutex> sync(m_mutex);
if (m_buf.size() == 0) return false;
}
double error = GetAvgError();
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
m_enabled = true;
}
@@ -528,7 +535,7 @@ void PIDController::Enable() {
*/
void PIDController::Disable() {
{
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
return m_enabled;
}
@@ -550,7 +557,7 @@ bool PIDController::IsEnabled() const {
void PIDController::Reset() {
Disable();
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
m_prevError = 0;
m_totalError = 0;
m_result = 0;
@@ -579,7 +586,7 @@ void PIDController::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
m_pListener = m_pEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
m_P = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
@@ -587,7 +594,7 @@ void PIDController::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
m_iListener = m_iEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
m_I = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
@@ -595,7 +602,7 @@ void PIDController::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
m_dListener = m_dEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
m_D = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
@@ -603,7 +610,7 @@ void PIDController::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
m_fListener = m_fEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<hal::priority_recursive_mutex> sync(m_mutex);
std::lock_guard<std::mutex> sync(m_mutex);
m_F = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);

View File

@@ -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<hal::priority_recursive_mutex> sync(m_createLock);
m_isAllocated = std::vector<bool>(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<Resource>& r,
uint32_t elements) {
std::lock_guard<hal::priority_recursive_mutex> sync(m_createLock);
void Resource::CreateResourceObject(std::unique_ptr<Resource>& r,
uint32_t elements) {
std::lock_guard<std::mutex> sync(m_createMutex);
if (!r) {
r = std::make_unique<Resource>(elements);
}
@@ -53,7 +52,7 @@ Resource::Resource(uint32_t elements) {
* allocated.
*/
uint32_t Resource::Allocate(const std::string& resourceDesc) {
std::lock_guard<hal::priority_recursive_mutex> sync(m_allocateLock);
std::lock_guard<std::mutex> 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<hal::priority_recursive_mutex> sync(m_allocateLock);
std::lock_guard<std::mutex> sync(m_allocateMutex);
if (index >= m_isAllocated.size()) {
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, resourceDesc);
return std::numeric_limits<uint32_t>::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<hal::priority_recursive_mutex> sync(m_allocateLock);
std::unique_lock<std::mutex> sync(m_allocateMutex);
if (index == std::numeric_limits<uint32_t>::max()) return;
if (index >= m_isAllocated.size()) {
wpi_setWPIError(NotAllocated);

View File

@@ -83,7 +83,7 @@ double Timer::Get() const {
double result;
double currentTime = GetFPGATimestamp();
std::lock_guard<hal::priority_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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<hal::priority_mutex> sync(m_mutex);
std::lock_guard<std::mutex> 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.

View File

@@ -10,12 +10,11 @@
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <vector>
#include <HAL/cpp/priority_mutex.h>
#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<ButtonScheduler*> ButtonVector;
ButtonVector m_buttons;
typedef std::vector<Command*> CommandVector;
hal::priority_mutex m_additionsLock;
std::mutex m_additionsLock;
CommandVector m_additions;
typedef std::set<Command*> CommandSet;
CommandSet m_commands;

View File

@@ -10,8 +10,7 @@
#include <stdint.h>
#include <array>
#include <HAL/cpp/priority_mutex.h>
#include <mutex>
#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<bool, 3> m_filterAllocated;
};

View File

@@ -9,11 +9,11 @@
#include <atomic>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <HAL/DriverStation.h>
#include <HAL/cpp/priority_mutex.h>
#include <llvm/StringRef.h>
#include "RobotState.h"
@@ -116,7 +116,7 @@ class DriverStation : public SensorBase, public RobotStateInterface {
std::thread m_dsThread;
std::atomic<bool> 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;
};

View File

@@ -7,7 +7,8 @@
#pragma once
#include <HAL/cpp/priority_mutex.h>
#include <mutex>
#include <llvm/StringRef.h>
#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;
};

View File

@@ -7,10 +7,9 @@
#pragma once
#include <mutex>
#include <set>
#include <HAL/cpp/priority_mutex.h>
#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<MotorSafetyHelper*> m_helperList;
// protect accesses to the list of helpers
static hal::priority_recursive_mutex m_listMutex;
static std::mutex m_listMutex;
};
} // namespace frc

View File

@@ -11,10 +11,10 @@
#include <atomic>
#include <functional>
#include <mutex>
#include <utility>
#include <HAL/Notifier.h>
#include <HAL/cpp/priority_mutex.h>
#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<HAL_NotifierHandle> m_notifier{0};
// address of the handler

View File

@@ -9,11 +9,10 @@
#include <atomic>
#include <memory>
#include <mutex>
#include <queue>
#include <string>
#include <HAL/cpp/priority_mutex.h>
#include "Base.h"
#include "Controller.h"
#include "LiveWindow/LiveWindow.h"
@@ -148,7 +147,7 @@ class PIDController : public LiveWindowSendable, public PIDInterface {
std::queue<double> m_buf;
double m_bufTotal = 0;
mutable hal::priority_recursive_mutex m_mutex;
mutable std::mutex m_mutex;
std::unique_ptr<Notifier> m_controlLoop;
Timer m_setpointTimer;

View File

@@ -10,11 +10,10 @@
#include <stdint.h>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include <HAL/cpp/priority_mutex.h>
#include "ErrorBase.h"
namespace frc {
@@ -44,9 +43,9 @@ class Resource : public ErrorBase {
private:
std::vector<bool> 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

View File

@@ -7,7 +7,7 @@
#pragma once
#include <HAL/cpp/priority_mutex.h>
#include <mutex>
#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

View File

@@ -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 <atomic>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <HAL/cpp/priority_condition_variable.h>
#include <HAL/cpp/priority_mutex.h>
#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<hal::priority_mutex> 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<bool> 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<bool> 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<bool> which it will set to true when it is ready to have
// join called on it.
template <class Function>
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<bool> timed_out{true};
auto wait_until = [this, &timed_out, wait_for](std::atomic<bool>& 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<bool> retval{true};
auto predicate = [this]() -> bool { return m_pred_var; };
auto wait_until = [this, &retval, predicate,
wait_for](std::atomic<bool>& 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<bool>& 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<bool>& 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<bool>& 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<bool>& 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