datapool updates, fixes, pool read helper

This commit is contained in:
Robin Müller 2020-12-28 17:55:19 +01:00
parent 426514b9a2
commit 91cb061da9
12 changed files with 191 additions and 92 deletions

View File

@ -9,9 +9,10 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
PoolDataSetBase::~PoolDataSetBase() {} PoolDataSetBase::~PoolDataSetBase() {}
ReturnValue_t PoolDataSetBase::registerVariable( ReturnValue_t PoolDataSetBase::registerVariable(
PoolVariableIF *variable) { PoolVariableIF *variable) {
if (state != States::DATA_SET_UNINITIALISED) { if (state != States::STATE_SET_UNINITIALISED) {
sif::error << "DataSet::registerVariable: " sif::error << "DataSet::registerVariable: "
"Call made in wrong position." << std::endl; "Call made in wrong position." << std::endl;
return DataSetIF::DATA_SET_UNINITIALISED; return DataSetIF::DATA_SET_UNINITIALISED;
@ -33,15 +34,16 @@ ReturnValue_t PoolDataSetBase::registerVariable(
ReturnValue_t PoolDataSetBase::read(uint32_t lockTimeout) { ReturnValue_t PoolDataSetBase::read(uint32_t lockTimeout) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if (state == States::DATA_SET_UNINITIALISED) { ReturnValue_t error = result;
if (state == States::STATE_SET_UNINITIALISED) {
lockDataPool(lockTimeout); lockDataPool(lockTimeout);
for (uint16_t count = 0; count < fillCount; count++) { for (uint16_t count = 0; count < fillCount; count++) {
result = readVariable(count); result = readVariable(count);
if(result != RETURN_OK) { if(result != RETURN_OK) {
break; error = result;
} }
} }
state = States::DATA_SET_WAS_READ; state = States::STATE_SET_WAS_READ;
unlockDataPool(); unlockDataPool();
} }
else { else {
@ -50,6 +52,10 @@ ReturnValue_t PoolDataSetBase::read(uint32_t lockTimeout) {
" member datasets!" << std::endl; " member datasets!" << std::endl;
result = SET_WAS_ALREADY_READ; result = SET_WAS_ALREADY_READ;
} }
if(error != HasReturnvaluesIF::RETURN_OK) {
result = error;
}
return result; return result;
} }
@ -71,7 +77,13 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
registeredVariables[count]->getDataPoolId() registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) != PoolVariableIF::NO_PARAMETER)
{ {
if(protectEveryReadCommitCall) {
result = registeredVariables[count]->read(mutexTimeout);
}
else {
result = registeredVariables[count]->readWithoutLock(); result = registeredVariables[count]->readWithoutLock();
}
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
result = INVALID_PARAMETER_DEFINITION; result = INVALID_PARAMETER_DEFINITION;
} }
@ -80,7 +92,7 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
} }
ReturnValue_t PoolDataSetBase::commit(uint32_t lockTimeout) { ReturnValue_t PoolDataSetBase::commit(uint32_t lockTimeout) {
if (state == States::DATA_SET_WAS_READ) { if (state == States::STATE_SET_WAS_READ) {
handleAlreadyReadDatasetCommit(lockTimeout); handleAlreadyReadDatasetCommit(lockTimeout);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -96,10 +108,15 @@ void PoolDataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) {
!= PoolVariableIF::VAR_READ != PoolVariableIF::VAR_READ
&& registeredVariables[count]->getDataPoolId() && registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) { != PoolVariableIF::NO_PARAMETER) {
if(protectEveryReadCommitCall) {
registeredVariables[count]->commit(mutexTimeout);
}
else {
registeredVariables[count]->commitWithoutLock(); registeredVariables[count]->commitWithoutLock();
} }
} }
state = States::DATA_SET_UNINITIALISED; }
state = States::STATE_SET_UNINITIALISED;
unlockDataPool(); unlockDataPool();
} }
@ -111,7 +128,13 @@ ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) {
== PoolVariableIF::VAR_WRITE == PoolVariableIF::VAR_WRITE
&& registeredVariables[count]->getDataPoolId() && registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) { != PoolVariableIF::NO_PARAMETER) {
registeredVariables[count]->commitWithoutLock(); if(protectEveryReadCommitCall) {
result = registeredVariables[count]->commit(mutexTimeout);
}
else {
result = registeredVariables[count]->commitWithoutLock();
}
} else if (registeredVariables[count]->getDataPoolId() } else if (registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) { != PoolVariableIF::NO_PARAMETER) {
if (result != COMMITING_WITHOUT_READING) { if (result != COMMITING_WITHOUT_READING) {
@ -121,7 +144,7 @@ ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) {
} }
} }
} }
state = States::DATA_SET_UNINITIALISED; state = States::STATE_SET_UNINITIALISED;
unlockDataPool(); unlockDataPool();
return result; return result;
} }
@ -172,3 +195,9 @@ size_t PoolDataSetBase::getSerializedSize() const {
void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) { void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
this->registeredVariables = variablesContainer; this->registeredVariables = variablesContainer;
} }
void PoolDataSetBase::setReadCommitProtectionBehaviour(
bool protectEveryReadCommit, uint32_t mutexTimeout) {
this->protectEveryReadCommitCall = protectEveryReadCommit;
this->mutexTimeout = mutexTimeout;
}

View File

@ -44,6 +44,7 @@ public:
/** /**
* @brief The read call initializes reading out all registered variables. * @brief The read call initializes reading out all registered variables.
* It is mandatory to call commit after every read call!
* @details * @details
* It iterates through the list of registered variables and calls all read() * It iterates through the list of registered variables and calls all read()
* functions of the registered pool variables (which read out their values * functions of the registered pool variables (which read out their values
@ -52,11 +53,12 @@ public:
* the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned. * the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned.
* *
* The data pool is locked during the whole read operation and * The data pool is locked during the whole read operation and
* freed afterwards.The state changes to "was written" after this operation. * freed afterwards. It is mandatory to call commit after a read call,
* even if the read operation is not successful!
* @return * @return
* - @c RETURN_OK if all variables were read successfully. * - @c RETURN_OK if all variables were read successfully.
* - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the * - @c INVALID_PARAMETER_DEFINITION if a pool entry does not exist or there
* requested variable is invalid. * is a type conflict.
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling * - @c SET_WAS_ALREADY_READ if read() is called twice without calling
* commit() in between * commit() in between
*/ */
@ -75,7 +77,7 @@ public:
* If the set does contain at least one variable which is not write-only * If the set does contain at least one variable which is not write-only
* commit() can only be called after read(). If the set only contains * commit() can only be called after read(). If the set only contains
* variables which are write only, commit() can be called without a * variables which are write only, commit() can be called without a
* preceding read() call. * preceding read() call. Every read call must be followed by a commit call!
* @return - @c RETURN_OK if all variables were read successfully. * @return - @c RETURN_OK if all variables were read successfully.
* - @c COMMITING_WITHOUT_READING if set was not read yet and * - @c COMMITING_WITHOUT_READING if set was not read yet and
* contains non write-only variables * contains non write-only variables
@ -89,6 +91,7 @@ public:
* @return * @return
*/ */
virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override; virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override;
/** /**
* Provides the means to lock the underlying data structure to ensure * Provides the means to lock the underlying data structure to ensure
* thread-safety. Default implementation is empty * thread-safety. Default implementation is empty
@ -114,6 +117,15 @@ public:
SerializeIF::Endianness streamEndianness) override; SerializeIF::Endianness streamEndianness) override;
protected: protected:
/**
* Can be used to individually protect every read and commit call.
* @param protectEveryReadCommit
* @param mutexTimeout
*/
void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
uint32_t mutexTimeout = 20);
/** /**
* @brief The fill_count attribute ensures that the variables * @brief The fill_count attribute ensures that the variables
* register in the correct array position and that the maximum * register in the correct array position and that the maximum
@ -124,14 +136,14 @@ protected:
* States of the seet. * States of the seet.
*/ */
enum class States { enum class States {
DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED STATE_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
DATA_SET_WAS_READ //!< DATA_SET_WAS_READ STATE_SET_WAS_READ //!< DATA_SET_WAS_READ
}; };
/** /**
* @brief state manages the internal state of the data set, * @brief state manages the internal state of the data set,
* which is important e.g. for the behavior on destruction. * which is important e.g. for the behavior on destruction.
*/ */
States state = States::DATA_SET_UNINITIALISED; States state = States::STATE_SET_UNINITIALISED;
/** /**
* @brief This array represents all pool variables registered in this set. * @brief This array represents all pool variables registered in this set.
@ -144,6 +156,9 @@ protected:
void setContainer(PoolVariableIF** variablesContainer); void setContainer(PoolVariableIF** variablesContainer);
private: private:
bool protectEveryReadCommitCall = false;
uint32_t mutexTimeout = 20;
ReturnValue_t readVariable(uint16_t count); ReturnValue_t readVariable(uint16_t count);
void handleAlreadyReadDatasetCommit(uint32_t lockTimeout); void handleAlreadyReadDatasetCommit(uint32_t lockTimeout);
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout); ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);

View File

@ -1,19 +1,17 @@
#ifndef FSFW_DATAPOOL_POOLDATASETIF_H_ #ifndef FSFW_DATAPOOL_POOLDATASETIF_H_
#define FSFW_DATAPOOL_POOLDATASETIF_H_ #define FSFW_DATAPOOL_POOLDATASETIF_H_
#include "ReadCommitIF.h"
#include "DataSetIF.h" #include "DataSetIF.h"
/** /**
* @brief Extendes the DataSetIF by adding abstract functions to lock * @brief Extendes the DataSetIF by adding abstract functions to lock
* and unlock a data pool and read/commit semantics. * and unlock a data pool and read/commit semantics.
*/ */
class PoolDataSetIF: public DataSetIF { class PoolDataSetIF: public DataSetIF, public ReadCommitIF {
public: public:
virtual~ PoolDataSetIF() {}; 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 * @brief Most underlying data structures will have a pool like structure
* and will require a lock and unlock mechanism to ensure * and will require a lock and unlock mechanism to ensure

View File

@ -3,6 +3,7 @@
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../serialize/SerializeIF.h" #include "../serialize/SerializeIF.h"
#include "ReadCommitIF.h"
/** /**
* @brief This interface is used to control data pool * @brief This interface is used to control data pool
@ -17,9 +18,9 @@
* @author Bastian Baetz * @author Bastian Baetz
* @ingroup data_pool * @ingroup data_pool
*/ */
class PoolVariableIF : public SerializeIF { class PoolVariableIF : public SerializeIF,
public ReadCommitIF {
friend class PoolDataSetBase; friend class PoolDataSetBase;
friend class GlobDataSet;
friend class LocalPoolDataSetBase; friend class LocalPoolDataSetBase;
public: public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF; static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF;
@ -57,41 +58,6 @@ public:
*/ */
virtual void setValid(bool validity) = 0; virtual void setValid(bool validity) = 0;
/**
* @brief The commit call shall write back a newly calculated local
* value to the data pool.
* @details
* It is assumed that these calls are implemented in a thread-safe manner!
*/
virtual ReturnValue_t commit(uint32_t lockTimeout) = 0;
/**
* @brief The read call shall read the value of this parameter from
* the data pool and store the content locally.
* @details
* It is assumbed that these calls are implemented in a thread-safe manner!
*/
virtual ReturnValue_t read(uint32_t lockTimeout) = 0;
protected:
/**
* @brief Same as commit with the difference that comitting will be
* performed without a lock
* @return
* This can be used if the lock protection is handled externally
* to avoid the overhead of locking and unlocking consecutively.
* Declared protected to avoid free public usage.
*/
virtual ReturnValue_t readWithoutLock() = 0;
/**
* @brief Same as commit with the difference that comitting will be
* performed without a lock
* @return
* This can be used if the lock protection is handled externally
* to avoid the overhead of locking and unlocking consecutively.
* Declared protected to avoid free public usage.
*/
virtual ReturnValue_t commitWithoutLock() = 0;
}; };
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t; using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;

31
datapool/ReadCommitIF.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef FSFW_DATAPOOL_READCOMMITIF_H_
#define FSFW_DATAPOOL_READCOMMITIF_H_
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
/**
* @brief Common interface for all software objects which employ read-commit
* semantics.
*/
class ReadCommitIF {
public:
virtual ~ReadCommitIF() {}
virtual ReturnValue_t read(uint32_t mutexTimeout) = 0;
virtual ReturnValue_t commit(uint32_t mutexTimeout) = 0;
protected:
//! Optional and protected because this is interesting for classes grouping
//! members with commit and read semantics where the lock is only necessary
//! once.
virtual ReturnValue_t readWithoutLock() {
return read(20);
}
virtual ReturnValue_t commitWithoutLock() {
return commit(20);
}
};
#endif /* FSFW_DATAPOOL_READCOMMITIF_H_ */

View File

@ -44,6 +44,9 @@ public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF; static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID; static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
virtual object_id_t getObjectId() const = 0; virtual object_id_t getObjectId() const = 0;

View File

@ -577,7 +577,7 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry(
if (poolIter == localPoolMap.end()) { if (poolIter == localPoolMap.end()) {
sif::debug << "HousekeepingManager::fechPoolEntry:" sif::debug << "HousekeepingManager::fechPoolEntry:"
<< " Pool entry not found." << std::endl; << " Pool entry not found." << std::endl;
return POOL_ENTRY_NOT_FOUND; return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND;
} }
poolIter->second->print(); poolIter->second->print();
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;

View File

@ -55,14 +55,11 @@ class LocalDataPoolManager {
public: public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER; static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00); static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x0);
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x02); static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x01);
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x02);
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x03); static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x03);
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x04);
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x05);
/** /**
* This constructor is used by a class which wants to implement * This constructor is used by a class which wants to implement
@ -380,14 +377,14 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
if (poolIter == localPoolMap.end()) { if (poolIter == localPoolMap.end()) {
sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry " sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry "
"not found." << std::endl; "not found." << std::endl;
return POOL_ENTRY_NOT_FOUND; return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND;
} }
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second); *poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
if(*poolEntry == nullptr) { if(*poolEntry == nullptr) {
sif::debug << "HousekeepingManager::fetchPoolEntry:" sif::debug << "HousekeepingManager::fetchPoolEntry:"
" Pool entry not found." << std::endl; " Pool entry not found." << std::endl;
return POOL_ENTRY_TYPE_CONFLICT; return HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -8,7 +8,7 @@
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
uint32_t setId, PoolVariableIF** registeredVariablesArray, uint32_t setId, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables, bool noPeriodicHandling): const size_t maxNumberOfVariables, bool periodicHandling):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
if(hkOwner == nullptr) { if(hkOwner == nullptr) {
// Configuration error. // Configuration error.
@ -23,7 +23,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
// Data creators get a periodic helper for periodic HK data generation. // Data creators get a periodic helper for periodic HK data generation.
if(not noPeriodicHandling) { if(periodicHandling) {
periodicHelper = new PeriodicHousekeepingHelper(this); periodicHelper = new PeriodicHousekeepingHelper(this);
} }
} }
@ -34,13 +34,9 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>( HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
sid.objectId); sid.objectId);
if(hkOwner == nullptr) { if(hkOwner != nullptr) {
// Configuration error.
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
<< "invalid!" << std::endl;
return;
}
hkManager = hkOwner->getHkManagerHandle(); hkManager = hkOwner->getHkManagerHandle();
}
this->sid = sid; this->sid = sid;
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
@ -50,9 +46,12 @@ LocalPoolDataSetBase::~LocalPoolDataSetBase() {
} }
ReturnValue_t LocalPoolDataSetBase::lockDataPool(uint32_t timeoutMs) { ReturnValue_t LocalPoolDataSetBase::lockDataPool(uint32_t timeoutMs) {
if(hkManager != nullptr) {
MutexIF* mutex = hkManager->getMutexHandle(); MutexIF* mutex = hkManager->getMutexHandle();
return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs); return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs);
} }
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer, ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer,
size_t *size, size_t maxSize, size_t *size, size_t maxSize,
@ -127,9 +126,12 @@ ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer(
} }
ReturnValue_t LocalPoolDataSetBase::unlockDataPool() { ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
if(hkManager != nullptr) {
MutexIF* mutex = hkManager->getMutexHandle(); MutexIF* mutex = hkManager->getMutexHandle();
return mutex->unlockMutex(); return mutex->unlockMutex();
} }
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer, ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
size_t* size, size_t maxSize,SerializeIF::Endianness streamEndianness, size_t* size, size_t maxSize,SerializeIF::Endianness streamEndianness,
@ -276,3 +278,9 @@ void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
} }
this->valid = valid; this->valid = valid;
} }
void LocalPoolDataSetBase::setReadCommitProtectionBehaviour(
bool protectEveryReadCommit, uint32_t mutexTimeout) {
PoolDataSetBase::setReadCommitProtectionBehaviour(protectEveryReadCommit,
mutexTimeout);
}

View File

@ -54,7 +54,7 @@ public:
*/ */
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
uint32_t setId, PoolVariableIF** registeredVariablesArray, uint32_t setId, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables, bool noPeriodicHandling = false); const size_t maxNumberOfVariables, bool periodicHandling = true);
/** /**
* @brief Constructor for users of local pool data. * @brief Constructor for users of local pool data.
@ -77,6 +77,16 @@ public:
*/ */
~LocalPoolDataSetBase(); ~LocalPoolDataSetBase();
/**
* If the data is pulled from different local data pools, every read and
* commit call should be mutex protected for thread safety.
* This can be specified with the second parameter.
* @param dataCreator
* @param protectEveryReadCommit
*/
void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
uint32_t mutexTimeout = 20);
void setValidityBufferGeneration(bool withValidityBuffer); void setValidityBufferGeneration(bool withValidityBuffer);
sid_t getSid() const; sid_t getSid() const;
@ -128,6 +138,7 @@ public:
protected: protected:
sid_t sid; sid_t sid;
uint32_t mutexTimeout = 20;
MutexIF* mutex = nullptr; MutexIF* mutex = nullptr;
bool diagnostic = false; bool diagnostic = false;
@ -181,7 +192,7 @@ protected:
*/ */
ReturnValue_t unlockDataPool() override; ReturnValue_t unlockDataPool() override;
LocalDataPoolManager* hkManager; LocalDataPoolManager* hkManager = nullptr;
/** /**
* Set n-th bit of a byte, with n being the position from 0 * Set n-th bit of a byte, with n being the position from 0

View File

@ -11,14 +11,14 @@ inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner,
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {} LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template<typename T> template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId, inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner,
DataSetIF *dataSet, pool_rwm_t setReadWriteMode): lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {} LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template<typename T> template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF *dataSet, inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId,
pool_rwm_t setReadWriteMode): DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode){} dataSet, setReadWriteMode){}
@ -40,11 +40,11 @@ inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
PoolEntry<T>* poolEntry = nullptr; PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry); ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
if(result != RETURN_OK and poolEntry != nullptr) { if(result != RETURN_OK or poolEntry == nullptr) {
sif::error << "PoolVector: Read of local pool variable of object " sif::error << "PoolVector: Read of local pool variable of object "
"0x" << std::hex << std::setw(8) << std::setfill('0') << << std::hex << std::setw(8) << std::setfill('0')
hkManager->getOwner() << " and lp ID 0x" << localPoolId << << hkManager->getOwner() << " and lp ID " << localPoolId
std::dec << " failed.\n" << std::flush; << std::dec << " failed." << std::setfill(' ') << std::endl;
return result; return result;
} }
this->value = *(poolEntry->address); this->value = *(poolEntry->address);
@ -62,7 +62,7 @@ inline ReturnValue_t LocalPoolVariable<T>::commit(dur_millis_t lockTimeout) {
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() { inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_READ) { if(readWriteMode == pool_rwm_t::VAR_READ) {
sif::debug << "LocalPoolVar: Invalid read write " sif::debug << "LocalPoolVariable: Invalid read write "
"mode for commit() call." << std::endl; "mode for commit() call." << std::endl;
return PoolVariableIF::INVALID_READ_WRITE_MODE; return PoolVariableIF::INVALID_READ_WRITE_MODE;
} }

View File

@ -0,0 +1,41 @@
#ifndef FSFW_DATAPOOLLOCAL_POOLREADHELPER_H_
#define FSFW_DATAPOOLLOCAL_POOLREADHELPER_H_
#include <fsfw/datapoollocal/LocalPoolDataSetBase.h>
#include <FSFWConfig.h>
/**
* @brief Helper class to read data sets or pool variables
*/
class PoolReadHelper {
public:
PoolReadHelper(ReadCommitIF* readObject, uint32_t mutexTimeout = 20):
readObject(readObject), mutexTimeout(mutexTimeout) {
if(readObject != nullptr) {
readResult = readObject->read(mutexTimeout);
#if FSFW_PRINT_VERBOSITY_LEVEL == 1
sif::error << "PoolReadHelper: Read failed!" << std::endl;
#endif
}
}
ReturnValue_t getReadResult() const {
return readResult;
}
~PoolReadHelper() {
if(readObject != nullptr) {
readObject->commit(mutexTimeout);
}
}
private:
ReadCommitIF* readObject = nullptr;
ReturnValue_t readResult = HasReturnvaluesIF::RETURN_OK;
uint32_t mutexTimeout = 20;
};
#endif /* FSFW_DATAPOOLLOCAL_POOLREADHELPER_H_ */