Change hal sim to use spinlocks (#1291)

This makes callback registration completely thread safe.

This patch also uses templates and macros to dramatically reduce the amount of
manual boilerplate.
This commit is contained in:
Peter Johnson
2018-09-03 16:08:07 -07:00
committed by GitHub
parent 67b1c85315
commit c0ff6198b3
65 changed files with 1305 additions and 7639 deletions

View File

@@ -7,94 +7,47 @@
#pragma once
#include <atomic>
#include <memory>
#include <wpi/mutex.h>
#include "../PortsInternal.h"
#include "mockdata/NotifyListenerVector.h"
#include "mockdata/PCMData.h"
#include "mockdata/SimDataValue.h"
namespace hal {
class PCMData {
HAL_SIMDATAVALUE_DEFINE_NAME(SolenoidInitialized)
HAL_SIMDATAVALUE_DEFINE_NAME(SolenoidOutput)
HAL_SIMDATAVALUE_DEFINE_NAME(CompressorInitialized)
HAL_SIMDATAVALUE_DEFINE_NAME(CompressorOn)
HAL_SIMDATAVALUE_DEFINE_NAME(ClosedLoopEnabled)
HAL_SIMDATAVALUE_DEFINE_NAME(PressureSwitch)
HAL_SIMDATAVALUE_DEFINE_NAME(CompressorCurrent)
static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr HAL_Bool
GetSolenoidInitializedDefault() {
return false;
}
static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr HAL_Bool
GetSolenoidOutputDefault() {
return false;
}
public:
int32_t RegisterSolenoidInitializedCallback(int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void CancelSolenoidInitializedCallback(int32_t channel, int32_t uid);
void InvokeSolenoidInitializedCallback(int32_t channel, HAL_Value value);
HAL_Bool GetSolenoidInitialized(int32_t channel);
void SetSolenoidInitialized(int32_t channel, HAL_Bool solenoidInitialized);
int32_t RegisterSolenoidOutputCallback(int32_t channel,
HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
void CancelSolenoidOutputCallback(int32_t channel, int32_t uid);
void InvokeSolenoidOutputCallback(int32_t channel, HAL_Value value);
HAL_Bool GetSolenoidOutput(int32_t channel);
void SetSolenoidOutput(int32_t channel, HAL_Bool solenoidOutput);
int32_t RegisterCompressorInitializedCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void CancelCompressorInitializedCallback(int32_t uid);
void InvokeCompressorInitializedCallback(HAL_Value value);
HAL_Bool GetCompressorInitialized();
void SetCompressorInitialized(HAL_Bool compressorInitialized);
int32_t RegisterCompressorOnCallback(HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void CancelCompressorOnCallback(int32_t uid);
void InvokeCompressorOnCallback(HAL_Value value);
HAL_Bool GetCompressorOn();
void SetCompressorOn(HAL_Bool compressorOn);
int32_t RegisterClosedLoopEnabledCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void CancelClosedLoopEnabledCallback(int32_t uid);
void InvokeClosedLoopEnabledCallback(HAL_Value value);
HAL_Bool GetClosedLoopEnabled();
void SetClosedLoopEnabled(HAL_Bool closedLoopEnabled);
int32_t RegisterPressureSwitchCallback(HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
void CancelPressureSwitchCallback(int32_t uid);
void InvokePressureSwitchCallback(HAL_Value value);
HAL_Bool GetPressureSwitch();
void SetPressureSwitch(HAL_Bool pressureSwitch);
int32_t RegisterCompressorCurrentCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void CancelCompressorCurrentCallback(int32_t uid);
void InvokeCompressorCurrentCallback(HAL_Value value);
double GetCompressorCurrent();
void SetCompressorCurrent(double compressorCurrent);
SimDataValue<HAL_Bool, MakeBoolean, GetSolenoidInitializedName,
GetSolenoidInitializedDefault>
solenoidInitialized[kNumSolenoidChannels];
SimDataValue<HAL_Bool, MakeBoolean, GetSolenoidOutputName,
GetSolenoidOutputDefault>
solenoidOutput[kNumSolenoidChannels];
SimDataValue<HAL_Bool, MakeBoolean, GetCompressorInitializedName>
compressorInitialized{false};
SimDataValue<HAL_Bool, MakeBoolean, GetCompressorOnName> compressorOn{false};
SimDataValue<HAL_Bool, MakeBoolean, GetClosedLoopEnabledName>
closedLoopEnabled{true};
SimDataValue<HAL_Bool, MakeBoolean, GetPressureSwitchName> pressureSwitch{
false};
SimDataValue<double, MakeDouble, GetCompressorCurrentName> compressorCurrent{
0.0};
virtual void ResetData();
private:
wpi::mutex m_registerMutex;
std::atomic<HAL_Bool> m_solenoidInitialized[kNumSolenoidChannels];
std::shared_ptr<NotifyListenerVector>
m_solenoidInitializedCallbacks[kNumSolenoidChannels];
std::atomic<HAL_Bool> m_solenoidOutput[kNumSolenoidChannels];
std::shared_ptr<NotifyListenerVector>
m_solenoidOutputCallbacks[kNumSolenoidChannels];
std::atomic<HAL_Bool> m_compressorInitialized{false};
std::shared_ptr<NotifyListenerVector> m_compressorInitializedCallbacks =
nullptr;
std::atomic<HAL_Bool> m_compressorOn{false};
std::shared_ptr<NotifyListenerVector> m_compressorOnCallbacks = nullptr;
std::atomic<HAL_Bool> m_closedLoopEnabled{true};
std::shared_ptr<NotifyListenerVector> m_closedLoopEnabledCallbacks = nullptr;
std::atomic<HAL_Bool> m_pressureSwitch{false};
std::shared_ptr<NotifyListenerVector> m_pressureSwitchCallbacks = nullptr;
std::atomic<double> m_compressorCurrent{0.0};
std::shared_ptr<NotifyListenerVector> m_compressorCurrentCallbacks = nullptr;
};
extern PCMData* SimPCMData;
} // namespace hal