added new interfaces for datasets

This commit is contained in:
Robin Müller 2020-07-14 15:45:03 +02:00
parent e204bd77c6
commit e5ab7ada68
18 changed files with 396 additions and 274 deletions

View File

@ -1,5 +1,5 @@
#ifndef DATASETIF_H_
#define DATASETIF_H_
#ifndef FRAMEWORK_DATAPOOL_DATASETIF_H_
#define FRAMEWORK_DATAPOOL_DATASETIF_H_
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <framework/timemanager/Clock.h>
@ -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_ */

View File

@ -1,7 +1,7 @@
#include <framework/datapool/DataSetBase.h>
#include <framework/datapool/PoolDataSetBase.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
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;
}

View File

@ -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 <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolDataSetIF.h>
#include <framework/datapool/PoolVariableIF.h>
#include <framework/ipc/MutexIF.h>
@ -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_ */

28
datapool/PoolDataSetIF.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
#define FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
#include <framework/datapool/DataSetIF.h>
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_ */

View File

@ -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);

View File

@ -0,0 +1,15 @@
#ifndef FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
#define FRAMEWORK_DATAPOOL_SHAREDDATASETIF_H_
#include <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolDataSetIF.h>
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_ */

View File

@ -2,7 +2,7 @@
#include <framework/datapoolglob/GlobalDataSet.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
GlobDataSet::GlobDataSet(): DataSetBase(
GlobDataSet::GlobDataSet(): PoolDataSetBase(
reinterpret_cast<PoolVariableIF**>(&registeredVariables),
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() {

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_
#define FRAMEWORK_DATAPOOLGLOB_DATASET_H_
#include <framework/datapool/DataSetBase.h>
#include <framework/datapool/PoolDataSetBase.h>
/**
* @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

View File

@ -1,5 +1,5 @@
#include <framework/datapoollocal/LocalDataPoolManager.h>
#include <framework/datapoollocal/LocalDataSet.h>
#include <framework/datapoollocal/LocalPoolDataSetBase.h>
#include <framework/housekeeping/AcceptsHkPacketsIF.h>
#include <framework/ipc/MutexFactory.h>
#include <framework/ipc/MutexHelper.h>
@ -116,7 +116,7 @@ const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
MessageQueueId_t sendTo) {
LocalDataSet* dataSetToSerialize = dynamic_cast<LocalDataSet*>(
LocalDataSetBase* dataSetToSerialize = dynamic_cast<LocalDataSetBase*>(
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<LocalDataSet*>(
LocalDataSetBase* dataSet = dynamic_cast<LocalDataSetBase*>(
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);

View File

@ -14,7 +14,7 @@
#include <map>
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<typename T, uint16_t vecSize>
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);
};

View File

@ -1,106 +1,7 @@
#include <framework/datapoollocal/LocalDataPoolManager.h>
#include <framework/datapoollocal/LocalDataSet.h>
#include <framework/serialize/SerializeAdapter.h>
#include <cmath>
#include <cstring>
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<HasLocalDataPoolIF>(
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<float>(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(&currentPoolId, 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 <framework/datapoollocal/LocalDataSet.h>
LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, const size_t maxSize):
LocalDataSetBase(hkOwner, nullptr, maxSize), poolVarList(maxSize) {
this->setContainer(poolVarList.data());
}

View File

@ -1,115 +1,19 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_
#include <framework/datapool/DataSetBase.h>
#include <framework/datapool/DataSetIF.h>
#include <framework/datapoollocal/HasLocalDataPoolIF.h>
#include <framework/serialize/SerializeIF.h>
#include <framework/datapoollocal/LocalPoolDataSetBase.h>
#include <vector>
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<PoolVariableIF*> poolVarList;
std::vector<PoolVariableIF*> poolVarList;
};
#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */

View File

@ -0,0 +1,107 @@
#include <framework/datapoollocal/LocalDataPoolManager.h>
#include <framework/datapoollocal/LocalPoolDataSetBase.h>
#include <framework/serialize/SerializeAdapter.h>
#include <cmath>
#include <cstring>
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<HasLocalDataPoolIF>(
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<float>(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(&currentPoolId, 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;
}

View File

@ -0,0 +1,121 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
#include <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolDataSetBase.h>
#include <framework/datapoollocal/HasLocalDataPoolIF.h>
#include <framework/serialize/SerializeIF.h>
#include <vector>
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_ */

View File

@ -0,0 +1,16 @@
#include <framework/datapoollocal/SharedLocalDataSet.h>
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();
}

View File

@ -0,0 +1,25 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
#define FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
#include <framework/datapool/SharedDataSetIF.h>
#include <framework/datapoollocal/LocalPoolDataSetBase.h>
#include <framework/objectmanager/SystemObject.h>
#include <vector>
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<PoolVariableIF*> poolVarVector;
};
#endif /* FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ */

View File

@ -1,6 +0,0 @@
#include <framework/datapoollocal/StaticLocalDataSet.h>

View File

@ -1,11 +1,23 @@
#ifndef FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_
#define FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_
#include <framework/datapool/DataSetBase.h>
class StaticLocalDataSet: public DataSetBase {
#include <framework/datapool/PoolDataSetBase.h>
#include <array>
/**
* @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 <uint8_t capacity>
class StaticLocalDataSet: public PoolDataSetBase {
StaticLocalDataSet(): PoolDataSetBase(poolVarList.data(), capacity) {}
virtual~ StaticLocalDataSet();
private:
std::array<PoolVariableIF*, capacity> poolVarList;
};
#endif /* FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */