From e5ab7ada682fb80db4daa3ba7b4f5f20b364fedd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 14 Jul 2020 15:45:03 +0200 Subject: [PATCH] added new interfaces for datasets --- datapool/DataSetIF.h | 22 +--- .../{DataSetBase.cpp => PoolDataSetBase.cpp} | 34 ++--- datapool/{DataSetBase.h => PoolDataSetBase.h} | 15 ++- datapool/PoolDataSetIF.h | 28 ++++ datapool/PoolVariableIF.h | 4 +- datapool/SharedDataSetIF.h | 15 +++ datapoolglob/GlobalDataSet.cpp | 8 +- datapoolglob/GlobalDataSet.h | 6 +- datapoollocal/LocalDataPoolManager.cpp | 8 +- datapoollocal/LocalDataPoolManager.h | 8 +- datapoollocal/LocalDataSet.cpp | 113 +--------------- datapoollocal/LocalDataSet.h | 112 ++-------------- datapoollocal/LocalDataSetBase.cpp | 107 ++++++++++++++++ datapoollocal/LocalPoolDataSetBase.h | 121 ++++++++++++++++++ datapoollocal/SharedLocalDataSet.cpp | 16 +++ datapoollocal/SharedLocalDataSet.h | 25 ++++ datapoollocal/StaticLocalDataSet.cpp | 6 - datapoollocal/StaticLocalDataSet.h | 22 +++- 18 files changed, 396 insertions(+), 274 deletions(-) rename datapool/{DataSetBase.cpp => PoolDataSetBase.cpp} (80%) rename datapool/{DataSetBase.h => PoolDataSetBase.h} (93%) create mode 100644 datapool/PoolDataSetIF.h create mode 100644 datapool/SharedDataSetIF.h create mode 100644 datapoollocal/LocalDataSetBase.cpp create mode 100644 datapoollocal/LocalPoolDataSetBase.h create mode 100644 datapoollocal/SharedLocalDataSet.cpp create mode 100644 datapoollocal/SharedLocalDataSet.h delete mode 100644 datapoollocal/StaticLocalDataSet.cpp diff --git a/datapool/DataSetIF.h b/datapool/DataSetIF.h index 437f324f..bcc1cd21 100644 --- a/datapool/DataSetIF.h +++ b/datapool/DataSetIF.h @@ -1,5 +1,5 @@ -#ifndef DATASETIF_H_ -#define DATASETIF_H_ +#ifndef FRAMEWORK_DATAPOOL_DATASETIF_H_ +#define FRAMEWORK_DATAPOOL_DATASETIF_H_ #include #include @@ -34,8 +34,7 @@ public: */ virtual ~DataSetIF() {} - virtual ReturnValue_t read(uint32_t lockTimeout) = 0; - virtual ReturnValue_t commit(uint32_t lockTimeout) = 0; + /** * @brief This operation provides a method to register local data pool * variables to register in a data set by passing itself @@ -44,19 +43,6 @@ public: virtual ReturnValue_t registerVariable(PoolVariableIF* variable) = 0; virtual uint16_t getFillCount() const = 0; -private: - /** - * @brief Most underlying data structures will have a pool like structure - * and will require a lock and unlock mechanism to ensure - * thread-safety - * @return Lock operation result - */ - virtual ReturnValue_t lockDataPool(uint32_t timeoutMs) = 0; - /** - * @brief Unlock call corresponding to the lock call. - * @return Unlock operation result - */ - virtual ReturnValue_t unlockDataPool() = 0; }; -#endif /* DATASETIF_H_ */ +#endif /* FRAMEWORK_DATAPOOL_DATASETIF_H_ */ diff --git a/datapool/DataSetBase.cpp b/datapool/PoolDataSetBase.cpp similarity index 80% rename from datapool/DataSetBase.cpp rename to datapool/PoolDataSetBase.cpp index cb7a7899..63820732 100644 --- a/datapool/DataSetBase.cpp +++ b/datapool/PoolDataSetBase.cpp @@ -1,7 +1,7 @@ -#include +#include #include -DataSetBase::DataSetBase(PoolVariableIF** registeredVariablesArray, +PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxFillCount): registeredVariables(registeredVariablesArray), maxFillCount(maxFillCount) { @@ -10,9 +10,9 @@ DataSetBase::DataSetBase(PoolVariableIF** registeredVariablesArray, } } -DataSetBase::~DataSetBase() {} +PoolDataSetBase::~PoolDataSetBase() {} -ReturnValue_t DataSetBase::registerVariable( +ReturnValue_t PoolDataSetBase::registerVariable( PoolVariableIF *variable) { if (state != States::DATA_SET_UNINITIALISED) { sif::error << "DataSet::registerVariable: " @@ -34,7 +34,7 @@ ReturnValue_t DataSetBase::registerVariable( return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t DataSetBase::read(uint32_t lockTimeout) { +ReturnValue_t PoolDataSetBase::read(uint32_t lockTimeout) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if (state == States::DATA_SET_UNINITIALISED) { lockDataPool(lockTimeout); @@ -56,11 +56,11 @@ ReturnValue_t DataSetBase::read(uint32_t lockTimeout) { return result; } -uint16_t DataSetBase::getFillCount() const { +uint16_t PoolDataSetBase::getFillCount() const { return fillCount; } -ReturnValue_t DataSetBase::readVariable(uint16_t count) { +ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; // These checks are often performed by the respective // variable implementation too, but I guess a double check does not hurt. @@ -77,7 +77,7 @@ ReturnValue_t DataSetBase::readVariable(uint16_t count) { return result; } -ReturnValue_t DataSetBase::commit(uint32_t lockTimeout) { +ReturnValue_t PoolDataSetBase::commit(uint32_t lockTimeout) { if (state == States::DATA_SET_WAS_READ) { handleAlreadyReadDatasetCommit(lockTimeout); return HasReturnvaluesIF::RETURN_OK; @@ -87,7 +87,7 @@ ReturnValue_t DataSetBase::commit(uint32_t lockTimeout) { } } -void DataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) { +void PoolDataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) { lockDataPool(lockTimeout); for (uint16_t count = 0; count < fillCount; count++) { if (registeredVariables[count]->getReadWriteMode() @@ -101,7 +101,7 @@ void DataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) { unlockDataPool(); } -ReturnValue_t DataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) { +ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; lockDataPool(lockTimeout); for (uint16_t count = 0; count < fillCount; count++) { @@ -125,15 +125,15 @@ ReturnValue_t DataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) { } -ReturnValue_t DataSetBase::lockDataPool(uint32_t timeoutMs) { +ReturnValue_t PoolDataSetBase::lockDataPool(uint32_t timeoutMs) { return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t DataSetBase::unlockDataPool() { +ReturnValue_t PoolDataSetBase::unlockDataPool() { return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t DataSetBase::serialize(uint8_t** buffer, size_t* size, +ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size, const size_t maxSize, SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; for (uint16_t count = 0; count < fillCount; count++) { @@ -146,7 +146,7 @@ ReturnValue_t DataSetBase::serialize(uint8_t** buffer, size_t* size, return result; } -ReturnValue_t DataSetBase::deSerialize(const uint8_t** buffer, size_t* size, +ReturnValue_t PoolDataSetBase::deSerialize(const uint8_t** buffer, size_t* size, SerializeIF::Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; for (uint16_t count = 0; count < fillCount; count++) { @@ -159,10 +159,14 @@ ReturnValue_t DataSetBase::deSerialize(const uint8_t** buffer, size_t* size, return result; } -size_t DataSetBase::getSerializedSize() const { +size_t PoolDataSetBase::getSerializedSize() const { uint32_t size = 0; for (uint16_t count = 0; count < fillCount; count++) { size += registeredVariables[count]->getSerializedSize(); } return size; } + +void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) { + this->registeredVariables = variablesContainer; +} diff --git a/datapool/DataSetBase.h b/datapool/PoolDataSetBase.h similarity index 93% rename from datapool/DataSetBase.h rename to datapool/PoolDataSetBase.h index cc16aa9e..112808dd 100644 --- a/datapool/DataSetBase.h +++ b/datapool/PoolDataSetBase.h @@ -1,6 +1,7 @@ -#ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_ -#define FRAMEWORK_DATAPOOL_DATASETBASE_H_ +#ifndef FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ +#define FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ #include +#include #include #include @@ -27,7 +28,7 @@ * @author Bastian Baetz * @ingroup data_pool */ -class DataSetBase: public DataSetIF, +class PoolDataSetBase: public PoolDataSetIF, public SerializeIF, public HasReturnvaluesIF { public: @@ -37,9 +38,9 @@ public: * supply a pointer to this dataset to PoolVariable * initializations to register pool variables. */ - DataSetBase(PoolVariableIF** registeredVariablesArray, + PoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxFillCount); - virtual~ DataSetBase(); + virtual~ PoolDataSetBase(); /** * @brief The read call initializes reading out all registered variables. @@ -140,10 +141,12 @@ protected: PoolVariableIF** registeredVariables = nullptr; const size_t maxFillCount = 0; + void setContainer(PoolVariableIF** variablesContainer); + private: ReturnValue_t readVariable(uint16_t count); void handleAlreadyReadDatasetCommit(uint32_t lockTimeout); ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout); }; -#endif /* FRAMEWORK_DATAPOOL_DATASETBASE_H_ */ +#endif /* FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ */ diff --git a/datapool/PoolDataSetIF.h b/datapool/PoolDataSetIF.h new file mode 100644 index 00000000..a33d4bd0 --- /dev/null +++ b/datapool/PoolDataSetIF.h @@ -0,0 +1,28 @@ +#ifndef FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ +#define FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ +#include + +class PoolDataSetIF: public DataSetIF { +public: + virtual~ PoolDataSetIF() {}; + + virtual ReturnValue_t read(dur_millis_t lockTimeout) = 0; + virtual ReturnValue_t commit(dur_millis_t lockTimeout) = 0; + + /** + * @brief Most underlying data structures will have a pool like structure + * and will require a lock and unlock mechanism to ensure + * thread-safety + * @return Lock operation result + */ + virtual ReturnValue_t lockDataPool(dur_millis_t timeoutMs) = 0; + /** + * @brief Unlock call corresponding to the lock call. + * @return Unlock operation result + */ + virtual ReturnValue_t unlockDataPool() = 0; + + virtual bool isValid() const = 0; +}; + +#endif /* FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ */ diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 30b87839..6b0dd7fb 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -18,9 +18,9 @@ * @ingroup data_pool */ class PoolVariableIF : public SerializeIF { - friend class DataSetBase; + friend class PoolDataSetBase; friend class GlobDataSet; - friend class LocalDataSet; + friend class LocalDataSetBase; public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF; static constexpr ReturnValue_t INVALID_READ_WRITE_MODE = MAKE_RETURN_CODE(0xA0); diff --git a/datapool/SharedDataSetIF.h b/datapool/SharedDataSetIF.h new file mode 100644 index 00000000..3d9cc302 --- /dev/null +++ b/datapool/SharedDataSetIF.h @@ -0,0 +1,15 @@ +#ifndef FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ +#define FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ +#include +#include + +class SharedDataSetIF: public PoolDataSetIF { +public: + virtual ~SharedDataSetIF() {}; + +private: + virtual ReturnValue_t lockDataset(dur_millis_t mutexTimeout) = 0; + virtual ReturnValue_t unlockDataset() = 0; +}; + +#endif /* FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_ */ diff --git a/datapoolglob/GlobalDataSet.cpp b/datapoolglob/GlobalDataSet.cpp index 883f6157..3e6e3e52 100644 --- a/datapoolglob/GlobalDataSet.cpp +++ b/datapoolglob/GlobalDataSet.cpp @@ -2,7 +2,7 @@ #include #include -GlobDataSet::GlobDataSet(): DataSetBase( +GlobDataSet::GlobDataSet(): PoolDataSetBase( reinterpret_cast(®isteredVariables), DATA_SET_MAX_SIZE) {} @@ -17,7 +17,11 @@ ReturnValue_t GlobDataSet::commit(bool valid, uint32_t lockTimeout) { } ReturnValue_t GlobDataSet::commit(uint32_t lockTimeout) { - return DataSetBase::commit(lockTimeout); + return PoolDataSetBase::commit(lockTimeout); +} + +bool GlobDataSet::isValid() const { + return this->valid; } ReturnValue_t GlobDataSet::unlockDataPool() { diff --git a/datapoolglob/GlobalDataSet.h b/datapoolglob/GlobalDataSet.h index d237cc1b..3ebe7235 100644 --- a/datapoolglob/GlobalDataSet.h +++ b/datapoolglob/GlobalDataSet.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_ #define FRAMEWORK_DATAPOOLGLOB_DATASET_H_ -#include +#include /** * @brief The DataSet class manages a set of locally checked out variables @@ -17,7 +17,7 @@ * @author Bastian Baetz * @ingroup data_pool */ -class GlobDataSet: public DataSetBase { +class GlobDataSet: public PoolDataSetBase { public: /** @@ -53,6 +53,8 @@ public: */ void setSetValid(bool valid); + bool isValid() const override; + /** * Set the valid information of all variables contained in the set which * are not read-only diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 02016abf..afce330f 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -116,7 +116,7 @@ const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const { ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, MessageQueueId_t sendTo) { - LocalDataSet* dataSetToSerialize = dynamic_cast( + LocalDataSetBase* dataSetToSerialize = dynamic_cast( owner->getDataSetHandle(sid)); if(dataSetToSerialize == nullptr) { sif::warning << "HousekeepingManager::generateHousekeepingPacket:" @@ -155,7 +155,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, } ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) { - LocalDataSet* dataSet = dynamic_cast( + LocalDataSetBase* dataSet = dynamic_cast( owner->getDataSetHandle(sid)); if(dataSet == nullptr) { sif::warning << "HousekeepingManager::generateHousekeepingPacket:" @@ -186,7 +186,7 @@ void LocalDataPoolManager::setMinimalSamplingFrequency(float frequencySeconds) { } ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( - store_address_t *storeId, LocalDataSet* dataSet) { + store_address_t *storeId, LocalDataSetBase* dataSet) { size_t hkSize = dataSet->getSerializedSize(); uint8_t* storePtr = nullptr; ReturnValue_t result = ipcStore->getFreeElement(storeId, hkSize,&storePtr); diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index df7b9ff4..5a840303 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -14,7 +14,7 @@ #include -class LocalDataSet; +class LocalDataSetBase; /** * @brief This class is the managing instance for local data pool. @@ -38,7 +38,7 @@ class LocalDataPoolManager { friend class LocalPoolVar; template friend class LocalPoolVector; - friend class LocalDataSet; + friend class LocalDataSetBase; public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER; @@ -135,7 +135,7 @@ private: * The data pool manager will keep an internal map of HK receivers. */ struct HkReceiver { - LocalDataSet* dataSet = nullptr; + LocalDataSetBase* dataSet = nullptr; MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE; ReportingType reportingType = ReportingType::PERIODIC; bool reportingStatus = true; @@ -202,7 +202,7 @@ private: void setMinimalSamplingFrequency(float frequencySeconds); ReturnValue_t serializeHkPacketIntoStore(store_address_t* storeId, - LocalDataSet* dataSet); + LocalDataSetBase* dataSet); }; diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 2a42cd38..b6508ada 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -1,106 +1,7 @@ -#include -#include -#include - -#include -#include - -LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, - const size_t maxNumberOfVariables): - DataSetBase(poolVarList.data(), maxNumberOfVariables) { - poolVarList.reserve(maxNumberOfVariables); - poolVarList.resize(maxNumberOfVariables); - if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; - return; - } - hkManager = hkOwner->getHkManagerHandle(); -} - -LocalDataSet::LocalDataSet(object_id_t ownerId, - const size_t maxNumberOfVariables): - DataSetBase(poolVarList.data(), maxNumberOfVariables) { - poolVarList.reserve(maxNumberOfVariables); - poolVarList.resize(maxNumberOfVariables); - HasLocalDataPoolIF* hkOwner = objectManager->get( - ownerId); - if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; - return; - } - hkManager = hkOwner->getHkManagerHandle(); -} - -LocalDataSet::~LocalDataSet() { -} - -ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) { - MutexIF* mutex = hkManager->getMutexHandle(); - return mutex->lockMutex(timeoutMs); -} - -ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer, - size_t *size, size_t maxSize, - SerializeIF::Endianness streamEndianness) const { - ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; - uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); - uint8_t validityMask[validityMaskSize]; - uint8_t validBufferIndex = 0; - uint8_t validBufferIndexBit = 0; - for (uint16_t count = 0; count < fillCount; count++) { - if(registeredVariables[count]->isValid()) { - // set validity buffer here. - this->bitSetter(validityMask + validBufferIndex, - validBufferIndexBit); - if(validBufferIndexBit == 7) { - validBufferIndex ++; - validBufferIndexBit = 0; - } - else { - validBufferIndexBit ++; - } - } - result = registeredVariables[count]->serialize(buffer, size, maxSize, - streamEndianness); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - } - // copy validity buffer to end - std::memcpy(*buffer, validityMask, validityMaskSize); - *size += validityMaskSize; - return result; -} - -ReturnValue_t LocalDataSet::unlockDataPool() { - MutexIF* mutex = hkManager->getMutexHandle(); - return mutex->unlockMutex(); -} - -ReturnValue_t LocalDataSet::serializeLocalPoolIds(uint8_t** buffer, - size_t* size, size_t maxSize, - SerializeIF::Endianness streamEndianness) const { - for (uint16_t count = 0; count < fillCount; count++) { - lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId(); - auto result = SerializeAdapter::serialize(¤tPoolId, buffer, - size, maxSize, streamEndianness); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization" - " error!" << std::endl; - return result; - } - } - return HasReturnvaluesIF::RETURN_OK; -} - -void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position) const { - if(position > 7) { - sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl; - return; - } - uint8_t shiftNumber = position + (7 - 2 * position); - *byte |= 1 << shiftNumber; -} - +#include + +LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, const size_t maxSize): + LocalDataSetBase(hkOwner, nullptr, maxSize), poolVarList(maxSize) { + this->setContainer(poolVarList.data()); +} + diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 2c70de82..c26d540c 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -1,115 +1,19 @@ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ -#include -#include -#include -#include - +#include #include -class LocalDataPoolManager; - -/** - * @brief The LocalDataSet class manages a set of locally checked out variables - * for local data pools - * @details - * This class manages a list, where a set of local variables (or pool variables) - * are registered. They are checked-out (i.e. their values are looked - * up and copied) with the read call. After the user finishes working with the - * pool variables, he can write back all variable values to the pool with - * the commit call. The data set manages locking and freeing the local data pools, - * to ensure thread-safety. - * - * An internal state manages usage of this class. Variables may only be - * registered before the read call is made, and the commit call only - * after the read call. - * - * If pool variables are writable and not committed until destruction - * of the set, the DataSet class automatically sets the valid flag in the - * data pool to invalid (without) changing the variable's value. - * - * @ingroup data_pool - */ -class LocalDataSet: public DataSetBase { +class LocalDataSet: public LocalDataSetBase { public: - /** - * @brief Constructor for the creator of local pool data. - * The constructor simply sets the fill_count to zero and sets - * the state to "uninitialized". - */ - LocalDataSet(HasLocalDataPoolIF *hkOwner, - const size_t maxNumberOfVariables); + LocalDataSet(HasLocalDataPoolIF* hkOwner, const size_t maxSize); - /** - * @brief Constructor for users of local pool data. The passed pool - * owner should implement the HasHkPoolParametersIF. - * The constructor simply sets the fill_count to zero and sets - * the state to "uninitialized". - */ - LocalDataSet(object_id_t ownerId, - const size_t maxNumberOfVariables); + virtual~ LocalDataSet() {}; - /** - * @brief The destructor automatically manages writing the valid - * information of variables. - * @details - * In case the data set was read out, but not committed(indicated by state), - * the destructor parses all variables that are still registered to the set. - * For each, the valid flag in the data pool is set to "invalid". - */ - ~LocalDataSet(); - - /** - * Special version of the serilization function which appends a - * validity buffer at the end. Each bit of this validity buffer - * denotes whether the container data set entries are valid from left - * to right, MSB first. - * @param buffer - * @param size - * @param maxSize - * @param bigEndian - * @param withValidityBuffer - * @return - */ - ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer, - size_t* size, size_t maxSize, - SerializeIF::Endianness streamEndianness) const; - - ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, - size_t* size, size_t maxSize, - SerializeIF::Endianness streamEndianness) const; -protected: + //! Copying forbidden for now. + LocalDataSet(const LocalDataSet&) = delete; + LocalDataSet& operator=(const LocalDataSet&) = delete; private: - /** - * If the valid state of a dataset is always relevant to the whole - * data set we can use this flag. - */ - bool valid = false; - - /** - * @brief This is a small helper function to facilitate locking - * the global data pool. - * @details - * It makes use of the lockDataPool method offered by the DataPool class. - */ - ReturnValue_t lockDataPool(uint32_t timeoutMs) override; - /** - * @brief This is a small helper function to facilitate - * unlocking the global data pool - * @details - * It makes use of the freeDataPoolLock method offered by the DataPool class. - */ - ReturnValue_t unlockDataPool() override; - - LocalDataPoolManager* hkManager; - - /** - * Set n-th bit of a byte, with n being the position from 0 - * (most significant bit) to 7 (least significant bit) - */ - void bitSetter(uint8_t* byte, uint8_t position) const; - - std::vector poolVarList; + std::vector poolVarList; }; #endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ diff --git a/datapoollocal/LocalDataSetBase.cpp b/datapoollocal/LocalDataSetBase.cpp new file mode 100644 index 00000000..f490ff67 --- /dev/null +++ b/datapoollocal/LocalDataSetBase.cpp @@ -0,0 +1,107 @@ +#include +#include +#include + +#include +#include + +LocalDataSetBase::LocalDataSetBase(HasLocalDataPoolIF *hkOwner, + PoolVariableIF** registeredVariablesArray, + const size_t maxNumberOfVariables): + PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { + if(hkOwner == nullptr) { + sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" + << std::endl; + return; + } + hkManager = hkOwner->getHkManagerHandle(); +} + +LocalDataSetBase::LocalDataSetBase(object_id_t ownerId, + PoolVariableIF** registeredVariablesArray, + const size_t maxNumberOfVariables): + PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { + HasLocalDataPoolIF* hkOwner = objectManager->get( + ownerId); + if(hkOwner == nullptr) { + sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" + << std::endl; + return; + } + hkManager = hkOwner->getHkManagerHandle(); +} + +LocalDataSetBase::~LocalDataSetBase() { +} + +ReturnValue_t LocalDataSetBase::lockDataPool(uint32_t timeoutMs) { + MutexIF* mutex = hkManager->getMutexHandle(); + return mutex->lockMutex(timeoutMs); +} + +ReturnValue_t LocalDataSetBase::serializeWithValidityBuffer(uint8_t **buffer, + size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); + uint8_t validityMask[validityMaskSize]; + uint8_t validBufferIndex = 0; + uint8_t validBufferIndexBit = 0; + for (uint16_t count = 0; count < fillCount; count++) { + if(registeredVariables[count]->isValid()) { + // set validity buffer here. + this->bitSetter(validityMask + validBufferIndex, + validBufferIndexBit); + if(validBufferIndexBit == 7) { + validBufferIndex ++; + validBufferIndexBit = 0; + } + else { + validBufferIndexBit ++; + } + } + result = registeredVariables[count]->serialize(buffer, size, maxSize, + streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + // copy validity buffer to end + std::memcpy(*buffer, validityMask, validityMaskSize); + *size += validityMaskSize; + return result; +} + +ReturnValue_t LocalDataSetBase::unlockDataPool() { + MutexIF* mutex = hkManager->getMutexHandle(); + return mutex->unlockMutex(); +} + +ReturnValue_t LocalDataSetBase::serializeLocalPoolIds(uint8_t** buffer, + size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { + for (uint16_t count = 0; count < fillCount; count++) { + lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId(); + auto result = SerializeAdapter::serialize(¤tPoolId, buffer, + size, maxSize, streamEndianness); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization" + " error!" << std::endl; + return result; + } + } + return HasReturnvaluesIF::RETURN_OK; +} + +void LocalDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const { + if(position > 7) { + sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl; + return; + } + uint8_t shiftNumber = position + (7 - 2 * position); + *byte |= 1 << shiftNumber; +} + +bool LocalDataSetBase::isValid() const { + return this->valid; +} diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h new file mode 100644 index 00000000..5ef8f3d4 --- /dev/null +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -0,0 +1,121 @@ +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ +#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ +#include +#include +#include +#include + +#include + +class LocalDataPoolManager; + +/** + * @brief The LocalDataSet class manages a set of locally checked out + * variables for local data pools + * @details + * This class manages a list, where a set of local variables (or pool variables) + * are registered. They are checked-out (i.e. their values are looked + * up and copied) with the read call. After the user finishes working with the + * pool variables, he can write back all variable values to the pool with + * the commit call. The data set manages locking and freeing the local data pools, + * to ensure thread-safety. + * + * An internal state manages usage of this class. Variables may only be + * registered before the read call is made, and the commit call only + * after the read call. + * + * If pool variables are writable and not committed until destruction + * of the set, the DataSet class automatically sets the valid flag in the + * data pool to invalid (without) changing the variable's value. + * + * @ingroup data_pool + */ +class LocalDataSetBase: public PoolDataSetBase { +public: + /** + * @brief Constructor for the creator of local pool data. + * The constructor simply sets the fill_count to zero and sets + * the state to "uninitialized". + */ + LocalDataSetBase(HasLocalDataPoolIF *hkOwner, + PoolVariableIF** registeredVariablesArray, + const size_t maxNumberOfVariables); + + /** + * @brief Constructor for users of local pool data. The passed pool + * owner should implement the HasHkPoolParametersIF. + * The constructor simply sets the fill_count to zero and sets + * the state to "uninitialized". + */ + LocalDataSetBase(object_id_t ownerId, + PoolVariableIF** registeredVariablesArray, + const size_t maxNumberOfVariables); + + /** + * @brief The destructor automatically manages writing the valid + * information of variables. + * @details + * In case the data set was read out, but not committed(indicated by state), + * the destructor parses all variables that are still registered to the set. + * For each, the valid flag in the data pool is set to "invalid". + */ + ~LocalDataSetBase(); + + /** + * Special version of the serilization function which appends a + * validity buffer at the end. Each bit of this validity buffer + * denotes whether the container data set entries are valid from left + * to right, MSB first. + * @param buffer + * @param size + * @param maxSize + * @param bigEndian + * @param withValidityBuffer + * @return + */ + ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer, + size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const; + + ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, + size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const; + + bool isValid() const override; + +protected: + /** + * If the valid state of a dataset is always relevant to the whole + * data set we can use this flag. + */ + bool valid = false; + + /** + * @brief This is a small helper function to facilitate locking + * the global data pool. + * @details + * It makes use of the lockDataPool method offered by the DataPool class. + */ + ReturnValue_t lockDataPool(uint32_t timeoutMs) override; + /** + * @brief This is a small helper function to facilitate + * unlocking the global data pool + * @details + * It makes use of the freeDataPoolLock method offered by the DataPool class. + */ + ReturnValue_t unlockDataPool() override; + + LocalDataPoolManager* hkManager; + + /** + * Set n-th bit of a byte, with n being the position from 0 + * (most significant bit) to 7 (least significant bit) + */ + void bitSetter(uint8_t* byte, uint8_t position) const; + +private: + + +}; + +#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ */ diff --git a/datapoollocal/SharedLocalDataSet.cpp b/datapoollocal/SharedLocalDataSet.cpp new file mode 100644 index 00000000..6f355a8a --- /dev/null +++ b/datapoollocal/SharedLocalDataSet.cpp @@ -0,0 +1,16 @@ +#include + +SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, object_id_t owner, + const size_t maxSize): SystemObject(objectId), + LocalDataSetBase(owner, nullptr, maxSize) { + this->setContainer(poolVarVector.data()); + datasetLock = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t SharedLocalDataSet::lockDataset(dur_millis_t mutexTimeout) { + return datasetLock->lockMutex(mutexTimeout); +} + +ReturnValue_t SharedLocalDataSet::unlockDataset() { + return datasetLock->unlockMutex(); +} diff --git a/datapoollocal/SharedLocalDataSet.h b/datapoollocal/SharedLocalDataSet.h new file mode 100644 index 00000000..8fe613ba --- /dev/null +++ b/datapoollocal/SharedLocalDataSet.h @@ -0,0 +1,25 @@ +#ifndef FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ +#define FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ +#include +#include +#include +#include + +class SharedLocalDataSet: public SystemObject, + public LocalDataSetBase, + public SharedDataSetIF { +public: + SharedLocalDataSet(object_id_t objectId, object_id_t owner, + const size_t maxSize); + ReturnValue_t lockDataset(dur_millis_t mutexTimeout) override; + ReturnValue_t unlockDataset() override; +private: + + + MutexIF* datasetLock = nullptr; + std::vector poolVarVector; +}; + + + +#endif /* FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ */ diff --git a/datapoollocal/StaticLocalDataSet.cpp b/datapoollocal/StaticLocalDataSet.cpp deleted file mode 100644 index 15d4251a..00000000 --- a/datapoollocal/StaticLocalDataSet.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - - - - - diff --git a/datapoollocal/StaticLocalDataSet.h b/datapoollocal/StaticLocalDataSet.h index 15a79aae..f31018af 100644 --- a/datapoollocal/StaticLocalDataSet.h +++ b/datapoollocal/StaticLocalDataSet.h @@ -1,11 +1,23 @@ #ifndef FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ #define FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ -#include - - -class StaticLocalDataSet: public DataSetBase { +#include +#include +/** + * @brief This local dataset type is created on the stack. + * @details + * Size of data set specified as a constructor argument. It is recommended + * to use the default LocalDataSet of the dataset is constructed on the heap + * and the SharedLocalDataSet if it created on the heap and used by multiple + * other software objects. + * @tparam capacity + */ +template +class StaticLocalDataSet: public PoolDataSetBase { + StaticLocalDataSet(): PoolDataSetBase(poolVarList.data(), capacity) {} + virtual~ StaticLocalDataSet(); +private: + std::array poolVarList; }; - #endif /* FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */