mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-01 02:41:48 +00:00
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:
committed by
Peter Johnson
parent
19addb04cf
commit
dd66b23845
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "AnalogInternal.h"
|
||||
|
||||
#include "HAL/AnalogInput.h"
|
||||
#include "HAL/cpp/priority_mutex.h"
|
||||
#include "PortsInternal.h"
|
||||
|
||||
namespace hal {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user