diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 9c1475f12..18e46fba9 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -49,7 +49,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress) { const uint8_t* dataPtr = NULL; - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { CommandMessage reply; diff --git a/action/CommandActionHelper.cpp b/action/CommandActionHelper.cpp index 05eb93461..ceb97d3b9 100644 --- a/action/CommandActionHelper.cpp +++ b/action/CommandActionHelper.cpp @@ -113,7 +113,7 @@ uint8_t CommandActionHelper::getCommandCount() const { void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) { const uint8_t * data = NULL; - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getData(storeId, &data, &size); if (result != HasReturnvaluesIF::RETURN_OK) { return; diff --git a/action/SimpleActionHelper.cpp b/action/SimpleActionHelper.cpp index 6de372fbf..6861fc28c 100644 --- a/action/SimpleActionHelper.cpp +++ b/action/SimpleActionHelper.cpp @@ -44,7 +44,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, queueToUse->sendMessage(commandedBy, &reply); } const uint8_t* dataPtr = NULL; - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { ActionMessage::setStepReply(&reply, actionId, 0, result); diff --git a/ipc/MutexHelper.h b/ipc/MutexHelper.h index f76ccec47..27c6c8178 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexHelper.h @@ -6,19 +6,35 @@ class MutexHelper { public: + enum class MutexStates: uint8_t { + LOCKED, + UNLOCKED + }; + MutexHelper(MutexIF* mutex, uint32_t timeoutMs) : internalMutex(mutex) { ReturnValue_t status = mutex->lockMutex(timeoutMs); if(status != HasReturnvaluesIF::RETURN_OK){ sif::error << "MutexHelper: Lock of Mutex failed " << status << std::endl; + result = status; } + internalState = MutexStates::LOCKED; } - ~MutexHelper() { - internalMutex->unlockMutex(); + internalMutex->unlockMutex(); + } + + MutexStates getInternalState() const { + return internalState; + } + + ReturnValue_t getResult() const { + return result; } private: MutexIF* internalMutex; + MutexStates internalState = MutexStates::UNLOCKED; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; }; #endif /* FRAMEWORK_IPC_MUTEXHELPER_H_ */ diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 5104be2ed..bed4cad3d 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -1,14 +1,11 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ -#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ - /** * @file LocalPool - * * @date 02.02.2012 * @author Bastian Baetz - * * @brief This file contains the definition of the LocalPool class. */ +#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ +#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ #include #include @@ -20,7 +17,7 @@ /** * @brief The LocalPool class provides an intermediate data storage with * a fixed pool size policy. - * \details The class implements the StorageManagerIF interface. While the + * @details The class implements the StorageManagerIF interface. While the * total number of pools is fixed, the element sizes in one pool and * the number of pool elements per pool are set on construction. * The full amount of memory is allocated on construction. @@ -31,7 +28,6 @@ * It is possible to store empty packets in the pool. * The local pool is NOT thread-safe. */ - template class LocalPool: public SystemObject, public StorageManagerIF { public: @@ -39,7 +35,66 @@ public: * @brief This definition generally sets the number of different sized pools. * @details This must be less than the maximum number of pools (currently 0xff). */ -// static const uint32_t NUMBER_OF_POOLS; + // static const uint32_t NUMBER_OF_POOLS; + /** + * @brief This is the default constructor for a pool manager instance. + * @details By passing two arrays of size NUMBER_OF_POOLS, the constructor + * allocates memory (with \c new) for store and size_list. These + * regions are all set to zero on start up. + * @param setObjectId The object identifier to be set. This allows for + * multiple instances of LocalPool in the system. + * @param element_sizes An array of size NUMBER_OF_POOLS in which the size + * of a single element in each pool is determined. + * The sizes must be provided in ascending order. + * + * @param n_elements An array of size NUMBER_OF_POOLS in which the + * number of elements for each pool is determined. + * The position of these values correspond to those in + * element_sizes. + * @param registered Register the pool in object manager or not. + * Default is false (local pool). + * @param spillsToHigherPools A variable to determine whether + * higher n pools are used if the store is full. + */ + LocalPool(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS], + bool registered = false, + bool spillsToHigherPools = false); + /** + * @brief In the LocalPool's destructor all allocated memory is freed. + */ + virtual ~LocalPool(void); + + /** + * Documentation: See StorageManagerIF.h + */ + ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, + size_t size, bool ignoreFault = false) override; + ReturnValue_t getFreeElement(store_address_t* storageId,const size_t size, + uint8_t** p_data, bool ignoreFault = false) override; + ReturnValue_t getData(store_address_t packet_id, const uint8_t** packet_ptr, + size_t * size) override; + ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr, + size_t * size) override; + virtual ReturnValue_t deleteData(store_address_t) override; + virtual ReturnValue_t deleteData(uint8_t* ptr, size_t size, + store_address_t* storeId = NULL) override; + virtual ReturnValue_t deleteDataNonLocking(store_address_t) override; + void clearStore() override; + ReturnValue_t initialize() override; +protected: + /** + * With this helper method, a free element of \c size is reserved. + * @param size The minimum packet size that shall be reserved. + * @param[out] address Storage ID of the reserved data. + * @return - #RETURN_OK on success, + * - the return codes of #getPoolIndex or #findEmpty otherwise. + */ + virtual ReturnValue_t reserveSpace(const uint32_t size, + store_address_t* address, bool ignoreFault); + + InternalErrorReporterIF *internalErrorReporter; private: /** * Indicates that this element is free. @@ -60,7 +115,7 @@ private: /** * @brief store represents the actual memory pool. * @details It is an array of pointers to memory, which was allocated with - * a \c new call on construction. + * a @c new call on construction. */ uint8_t* store[NUMBER_OF_POOLS]; /** @@ -68,8 +123,9 @@ private: * @details As the number of elements is determined on construction, the size list * is also dynamically allocated there. */ - uint32_t* size_list[NUMBER_OF_POOLS]; - bool spillsToHigherPools; //!< A variable to determine whether higher n pools are used if the store is full. + size_t* size_list[NUMBER_OF_POOLS]; + //! A variable to determine whether higher n pools are used if the store is full. + bool spillsToHigherPools; /** * @brief This method safely stores the given data in the given packet_id. * @details It also sets the size in size_list. The method does not perform @@ -78,7 +134,7 @@ private: * @param data The data to be stored. * @param size The size of the data to be stored. */ - void write(store_address_t packet_id, const uint8_t* data, uint32_t size); + void write(store_address_t packet_id, const uint8_t* data, size_t size); /** * @brief A helper method to read the element size of a certain pool. * @param pool_index The pool in which to look. @@ -101,7 +157,8 @@ private: * @return - #RETURN_OK on success, * - #DATA_TOO_LARGE otherwise. */ - ReturnValue_t getPoolIndex(uint32_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex = 0); + ReturnValue_t getPoolIndex(size_t packet_size, uint16_t* poolIndex, + uint16_t startAtIndex = 0); /** * @brief This helper method calculates the true array position in store * of a given packet id. @@ -121,310 +178,8 @@ private: * - #DATA_STORAGE_FULL if the store is full */ ReturnValue_t findEmpty(uint16_t pool_index, uint16_t* element); -protected: - /** - * With this helper method, a free element of \c size is reserved. - * @param size The minimum packet size that shall be reserved. - * @param[out] address Storage ID of the reserved data. - * @return - #RETURN_OK on success, - * - the return codes of #getPoolIndex or #findEmpty otherwise. - */ - virtual ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault); - - InternalErrorReporterIF *internalErrorReporter; -public: - /** - * @brief This is the default constructor for a pool manager instance. - * @details By passing two arrays of size NUMBER_OF_POOLS, the constructor - * allocates memory (with \c new) for store and size_list. These - * regions are all set to zero on start up. - * @param setObjectId The object identifier to be set. This allows for - * multiple instances of LocalPool in the system. - * @param element_sizes An array of size NUMBER_OF_POOLS in which the size - * of a single element in each pool is determined. - * The sizes must be provided in ascending order. - * - * @param n_elements An array of size NUMBER_OF_POOLS in which the - * number of elements for each pool is determined. - * The position of these values correspond to those in - * element_sizes. - * @param registered Register the pool in object manager or not. Default is false (local pool). - */ - LocalPool(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS], - bool registered = false, - bool spillsToHigherPools = false); - /** - * @brief In the LocalPool's destructor all allocated memory is freed. - */ - virtual ~LocalPool(void); - ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, - uint32_t size, bool ignoreFault = false); - - /** - * With this helper method, a free element of \c size is reserved. - * - * @param size The minimum packet size that shall be reserved. - * @return Returns the storage identifier within the storage or - * StorageManagerIF::INVALID_ADDRESS (in raw). - */ - ReturnValue_t getFreeElement(store_address_t* storageId, - const uint32_t size, uint8_t** p_data, bool ignoreFault = false); - ReturnValue_t getData(store_address_t packet_id, const uint8_t** packet_ptr, - uint32_t* size); - ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr, - uint32_t* size); - virtual ReturnValue_t deleteData(store_address_t); - virtual ReturnValue_t deleteData(uint8_t* ptr, uint32_t size, - store_address_t* storeId = NULL); - void clearStore(); - ReturnValue_t initialize(); }; -template -inline ReturnValue_t LocalPool::findEmpty(uint16_t pool_index, - uint16_t* element) { - ReturnValue_t status = DATA_STORAGE_FULL; - for (uint16_t foundElement = 0; foundElement < n_elements[pool_index]; - foundElement++) { - if (size_list[pool_index][foundElement] == STORAGE_FREE) { - *element = foundElement; - status = RETURN_OK; - break; - } - } - return status; -} - -template -inline void LocalPool::write(store_address_t packet_id, - const uint8_t* data, uint32_t size) { - uint8_t* ptr; - uint32_t packet_position = getRawPosition(packet_id); - - //check size? -> Not necessary, because size is checked before calling this function. - ptr = &store[packet_id.pool_index][packet_position]; - memcpy(ptr, data, size); - size_list[packet_id.pool_index][packet_id.packet_index] = size; -} - -//Returns page size of 0 in case store_index is illegal -template -inline uint32_t LocalPool::getPageSize(uint16_t pool_index) { - if (pool_index < NUMBER_OF_POOLS) { - return element_sizes[pool_index]; - } else { - return 0; - } -} - -template -inline ReturnValue_t LocalPool::getPoolIndex( - uint32_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex) { - for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) { -// debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << n << ", Element Size: " << element_sizes[n] << std::endl; - if (element_sizes[n] >= packet_size) { - *poolIndex = n; - return RETURN_OK; - } - } - return DATA_TOO_LARGE; -} - -template -inline uint32_t LocalPool::getRawPosition( - store_address_t packet_id) { - return packet_id.packet_index * element_sizes[packet_id.pool_index]; -} - -template -inline ReturnValue_t LocalPool::reserveSpace( - const uint32_t size, store_address_t* address, bool ignoreFault) { - ReturnValue_t status = getPoolIndex(size, &address->pool_index); - if (status != RETURN_OK) { - sif::error << "LocalPool( " << std::hex << getObjectId() << std::dec - << " )::reserveSpace: Packet too large." << std::endl; - return status; - } - status = findEmpty(address->pool_index, &address->packet_index); - while (status != RETURN_OK && spillsToHigherPools) { - status = getPoolIndex(size, &address->pool_index, address->pool_index + 1); - if (status != RETURN_OK) { - //We don't find any fitting pool anymore. - break; - } - status = findEmpty(address->pool_index, &address->packet_index); - } - if (status == RETURN_OK) { -// if (getObjectId() == objects::IPC_STORE && address->pool_index >= 3) { -// debug << "Reserve: Pool: " << std::dec << address->pool_index << " Index: " << address->packet_index << std::endl; -// } - - size_list[address->pool_index][address->packet_index] = size; - } else { - if (!ignoreFault) { - internalErrorReporter->storeFull(); - } -// error << "LocalPool( " << std::hex << getObjectId() << std::dec -// << " )::reserveSpace: Packet store is full." << std::endl; - } - return status; -} - -template -inline LocalPool::LocalPool(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS], bool registered, bool spillsToHigherPools) : - SystemObject(setObjectId, registered), spillsToHigherPools(spillsToHigherPools), internalErrorReporter(NULL) { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - this->element_sizes[n] = element_sizes[n]; - this->n_elements[n] = n_elements[n]; - store[n] = new uint8_t[n_elements[n] * element_sizes[n]]; - size_list[n] = new uint32_t[n_elements[n]]; - memset(store[n], 0x00, (n_elements[n] * element_sizes[n])); - memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); //TODO checkme - } -} - -template -inline LocalPool::~LocalPool(void) { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - delete[] store[n]; - delete[] size_list[n]; - } -} - -template -inline ReturnValue_t LocalPool::addData( - store_address_t* storageId, const uint8_t* data, uint32_t size, bool ignoreFault) { - ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); - if (status == RETURN_OK) { - write(*storageId, data, size); - } - return status; -} - -template -inline ReturnValue_t LocalPool::getFreeElement( - store_address_t* storageId, const uint32_t size, uint8_t** p_data, bool ignoreFault) { - ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); - if (status == RETURN_OK) { - *p_data = &store[storageId->pool_index][getRawPosition(*storageId)]; - } else { - *p_data = NULL; - } - return status; -} - -template -inline ReturnValue_t LocalPool::getData( - store_address_t packet_id, const uint8_t** packet_ptr, uint32_t* size) { - uint8_t* tempData = NULL; - ReturnValue_t status = modifyData(packet_id, &tempData, size); - *packet_ptr = tempData; - return status; -} - -template -inline ReturnValue_t LocalPool::modifyData(store_address_t packet_id, - uint8_t** packet_ptr, uint32_t* size) { - ReturnValue_t status = RETURN_FAILED; - if (packet_id.pool_index >= NUMBER_OF_POOLS) { - return ILLEGAL_STORAGE_ID; - } - if ((packet_id.packet_index >= n_elements[packet_id.pool_index])) { - return ILLEGAL_STORAGE_ID; - } - if (size_list[packet_id.pool_index][packet_id.packet_index] - != STORAGE_FREE) { - uint32_t packet_position = getRawPosition(packet_id); - *packet_ptr = &store[packet_id.pool_index][packet_position]; - *size = size_list[packet_id.pool_index][packet_id.packet_index]; - status = RETURN_OK; - } else { - status = DATA_DOES_NOT_EXIST; - } - return status; -} - -template -inline ReturnValue_t LocalPool::deleteData( - store_address_t packet_id) { - -// if (getObjectId() == objects::IPC_STORE && packet_id.pool_index >= 3) { -// debug << "Delete: Pool: " << std::dec << packet_id.pool_index << " Index: " << packet_id.packet_index << std::endl; -// } - ReturnValue_t status = RETURN_OK; - uint32_t page_size = getPageSize(packet_id.pool_index); - if ((page_size != 0) - && (packet_id.packet_index < n_elements[packet_id.pool_index])) { - uint16_t packet_position = getRawPosition(packet_id); - uint8_t* ptr = &store[packet_id.pool_index][packet_position]; - memset(ptr, 0, page_size); - //Set free list - size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE; - } else { - //pool_index or packet_index is too large - sif::error << "LocalPool:deleteData failed." << std::endl; - status = ILLEGAL_STORAGE_ID; - } - return status; -} - -template -inline void LocalPool::clearStore() { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list)));//TODO checkme - } -} - -template -inline ReturnValue_t LocalPool::deleteData(uint8_t* ptr, - uint32_t size, store_address_t* storeId) { - store_address_t localId; - ReturnValue_t result = ILLEGAL_ADDRESS; - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - //Not sure if new allocates all stores in order. so better be careful. - if ((store[n] <= ptr) && (&store[n][n_elements[n]*element_sizes[n]]) > ptr) { - localId.pool_index = n; - uint32_t deltaAddress = ptr - store[n]; - //Getting any data from the right "block" is ok. This is necessary, as IF's sometimes don't point to the first element of an object. - localId.packet_index = deltaAddress / element_sizes[n]; - result = deleteData(localId); -// if (deltaAddress % element_sizes[n] != 0) { -// error << "Pool::deleteData: address not aligned!" << std::endl; -// } - break; - } - } - if (storeId != NULL) { - *storeId = localId; - } - return result; -} - -template -inline ReturnValue_t LocalPool::initialize() { - ReturnValue_t result = SystemObject::initialize(); - if (result != RETURN_OK) { - return result; - } - internalErrorReporter = objectManager->get(objects::INTERNAL_ERROR_REPORTER); - if (internalErrorReporter == NULL){ - return RETURN_FAILED; - } - - //Check if any pool size is large than the maximum allowed. - for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) { - if (element_sizes[count] >= STORAGE_FREE) { - sif::error - << "LocalPool::initialize: Pool is too large! Max. allowed size is: " - << (STORAGE_FREE - 1) << std::endl; - return RETURN_FAILED; - } - } - return RETURN_OK; -} +#include #endif /* FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ */ diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp new file mode 100644 index 000000000..7e8ac0623 --- /dev/null +++ b/storagemanager/LocalPool.tpp @@ -0,0 +1,266 @@ +#ifndef LOCALPOOL_TPP +#define LOCALPOOL_TPP + +template +inline LocalPool::LocalPool(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS], bool registered, + bool spillsToHigherPools) : + SystemObject(setObjectId, registered), internalErrorReporter(nullptr), + spillsToHigherPools(spillsToHigherPools) +{ + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + this->element_sizes[n] = element_sizes[n]; + this->n_elements[n] = n_elements[n]; + store[n] = new uint8_t[n_elements[n] * element_sizes[n]]; + size_list[n] = new size_t[n_elements[n]]; + memset(store[n], 0x00, (n_elements[n] * element_sizes[n])); + //TODO checkme + memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); + } +} + + +template +inline ReturnValue_t LocalPool::findEmpty(uint16_t pool_index, + uint16_t* element) { + ReturnValue_t status = DATA_STORAGE_FULL; + for (uint16_t foundElement = 0; foundElement < n_elements[pool_index]; + foundElement++) { + if (size_list[pool_index][foundElement] == STORAGE_FREE) { + *element = foundElement; + status = RETURN_OK; + break; + } + } + return status; +} + +template +inline void LocalPool::write(store_address_t packet_id, + const uint8_t* data, size_t size) { + uint8_t* ptr; + uint32_t packet_position = getRawPosition(packet_id); + + //check size? -> Not necessary, because size is checked before calling this function. + ptr = &store[packet_id.pool_index][packet_position]; + memcpy(ptr, data, size); + size_list[packet_id.pool_index][packet_id.packet_index] = size; +} + +//Returns page size of 0 in case store_index is illegal +template +inline uint32_t LocalPool::getPageSize(uint16_t pool_index) { + if (pool_index < NUMBER_OF_POOLS) { + return element_sizes[pool_index]; + } else { + return 0; + } +} + +template +inline ReturnValue_t LocalPool::getPoolIndex( + size_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex) { + for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) { + //debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << + // n << ", Element Size: " << element_sizes[n] << std::endl; + if (element_sizes[n] >= packet_size) { + *poolIndex = n; + return RETURN_OK; + } + } + return DATA_TOO_LARGE; +} + +template +inline uint32_t LocalPool::getRawPosition( + store_address_t packet_id) { + return packet_id.packet_index * element_sizes[packet_id.pool_index]; +} + +template +inline ReturnValue_t LocalPool::reserveSpace( + const uint32_t size, store_address_t* address, bool ignoreFault) { + ReturnValue_t status = getPoolIndex(size, &address->pool_index); + if (status != RETURN_OK) { + sif::error << "LocalPool( " << std::hex << getObjectId() << std::dec + << " )::reserveSpace: Packet too large." << std::endl; + return status; + } + status = findEmpty(address->pool_index, &address->packet_index); + while (status != RETURN_OK && spillsToHigherPools) { + status = getPoolIndex(size, &address->pool_index, address->pool_index + 1); + if (status != RETURN_OK) { + //We don't find any fitting pool anymore. + break; + } + status = findEmpty(address->pool_index, &address->packet_index); + } + if (status == RETURN_OK) { + // if (getObjectId() == objects::IPC_STORE && address->pool_index >= 3) { + // debug << "Reserve: Pool: " << std::dec << address->pool_index << + // " Index: " << address->packet_index << std::endl; + // } + + size_list[address->pool_index][address->packet_index] = size; + } else { + if (!ignoreFault and internalErrorReporter != nullptr) { + internalErrorReporter->storeFull(); + } + // error << "LocalPool( " << std::hex << getObjectId() << std::dec + // << " )::reserveSpace: Packet store is full." << std::endl; + } + return status; +} + +template +inline LocalPool::~LocalPool(void) { + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + delete[] store[n]; + delete[] size_list[n]; + } +} + +template +inline ReturnValue_t LocalPool::addData(store_address_t* storageId, + const uint8_t* data, size_t size, bool ignoreFault) { + ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); + if (status == RETURN_OK) { + write(*storageId, data, size); + } + return status; +} + +template +inline ReturnValue_t LocalPool::getFreeElement( + store_address_t* storageId, const size_t size, + uint8_t** p_data, bool ignoreFault) { + ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); + if (status == RETURN_OK) { + *p_data = &store[storageId->pool_index][getRawPosition(*storageId)]; + } else { + *p_data = NULL; + } + return status; +} + +template +inline ReturnValue_t LocalPool::getData( + store_address_t packet_id, const uint8_t** packet_ptr, size_t* size) { + uint8_t* tempData = NULL; + ReturnValue_t status = modifyData(packet_id, &tempData, size); + *packet_ptr = tempData; + return status; +} + +template +inline ReturnValue_t LocalPool::modifyData( + store_address_t packet_id, uint8_t** packet_ptr, size_t* size) { + ReturnValue_t status = RETURN_FAILED; + if (packet_id.pool_index >= NUMBER_OF_POOLS) { + return ILLEGAL_STORAGE_ID; + } + if ((packet_id.packet_index >= n_elements[packet_id.pool_index])) { + return ILLEGAL_STORAGE_ID; + } + if (size_list[packet_id.pool_index][packet_id.packet_index] + != STORAGE_FREE) { + uint32_t packet_position = getRawPosition(packet_id); + *packet_ptr = &store[packet_id.pool_index][packet_position]; + *size = size_list[packet_id.pool_index][packet_id.packet_index]; + status = RETURN_OK; + } else { + status = DATA_DOES_NOT_EXIST; + } + return status; +} + +template +inline ReturnValue_t LocalPool::deleteData( + store_address_t packet_id) { + //if (getObjectId() == objects::IPC_STORE && packet_id.pool_index >= 3) { + // debug << "Delete: Pool: " << std::dec << packet_id.pool_index << " Index: " + // << packet_id.packet_index << std::endl; + //} + ReturnValue_t status = RETURN_OK; + uint32_t page_size = getPageSize(packet_id.pool_index); + if ((page_size != 0) + && (packet_id.packet_index < n_elements[packet_id.pool_index])) { + uint16_t packet_position = getRawPosition(packet_id); + uint8_t* ptr = &store[packet_id.pool_index][packet_position]; + memset(ptr, 0, page_size); + //Set free list + size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE; + } else { + //pool_index or packet_index is too large + sif::error << "LocalPool:deleteData failed." << std::endl; + status = ILLEGAL_STORAGE_ID; + } + return status; +} + +template +inline void LocalPool::clearStore() { + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + //TODO checkme + memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); + } +} + +template +inline ReturnValue_t LocalPool::deleteData(uint8_t* ptr, + size_t size, store_address_t* storeId) { + store_address_t localId; + ReturnValue_t result = ILLEGAL_ADDRESS; + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + //Not sure if new allocates all stores in order. so better be careful. + if ((store[n] <= ptr) && (&store[n][n_elements[n]*element_sizes[n]]) > ptr) { + localId.pool_index = n; + uint32_t deltaAddress = ptr - store[n]; + // Getting any data from the right "block" is ok. + // This is necessary, as IF's sometimes don't point to the first + // element of an object. + localId.packet_index = deltaAddress / element_sizes[n]; + result = deleteData(localId); + //if (deltaAddress % element_sizes[n] != 0) { + // error << "Pool::deleteData: address not aligned!" << std::endl; + //} + break; + } + } + if (storeId != NULL) { + *storeId = localId; + } + return result; +} + +template +inline ReturnValue_t LocalPool::initialize() { + ReturnValue_t result = SystemObject::initialize(); + if (result != RETURN_OK) { + return result; + } + internalErrorReporter = objectManager->get( + objects::INTERNAL_ERROR_REPORTER); + if (internalErrorReporter == NULL){ + return RETURN_FAILED; + } + + //Check if any pool size is large than the maximum allowed. + for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) { + if (element_sizes[count] >= STORAGE_FREE) { + sif::error << "LocalPool::initialize: Pool is too large! " + "Max. allowed size is: " << (STORAGE_FREE - 1) << std::endl; + return RETURN_FAILED; + } + } + return RETURN_OK; +} + +template +inline ReturnValue_t LocalPool::deleteDataNonLocking( + store_address_t storeId) { + return LocalPool::deleteData(storeId); +} + +#endif diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 68a7addc1..ff61742d7 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -1,86 +1,53 @@ -/** - * @file PoolManager - * - * @date 02.02.2012 - * @author Bastian Baetz - * - * @brief This file contains the definition of the PoolManager class. - */ - #ifndef POOLMANAGER_H_ #define POOLMANAGER_H_ - #include -#include +#include +using AccessorPair = std::pair; +using ConstAccessorPair = std::pair; /** * @brief The PoolManager class provides an intermediate data storage with * a fixed pool size policy for inter-process communication. - * \details Uses local pool, but is thread-safe. + * @details Uses local pool calls but is thread safe by protecting the call + * with a lock. */ - -template +template class PoolManager : public LocalPool { -protected: - /** - * Overwritten for thread safety. - * Locks during execution. - */ - virtual ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault); +public: + PoolManager(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS]); + + //! @brief In the PoolManager's destructor all allocated memory is freed. + virtual ~PoolManager(); /** - * \brief The mutex is created in the constructor and makes access mutual exclusive. - * \details Locking and unlocking is done during searching for free slots and deleting existing slots. + * Documentation will follow + * @param storeAccessor + * @return */ - MutexIF* mutex; -public: - PoolManager( object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], const uint16_t n_elements[NUMBER_OF_POOLS] ); + AccessorPair modifyData(store_address_t storeId); + ConstAccessorPair getData(store_address_t storeId); + + //! @brief LocalPool overrides for thread-safety. Decorator function which + //! wraps LocalPool calls with a mutex protection. + ReturnValue_t deleteData(store_address_t) override; + ReturnValue_t deleteData(uint8_t* buffer, size_t size, + store_address_t* storeId = nullptr) override; +protected: + ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, + bool ignoreFault) override; + /** - * @brief In the PoolManager's destructor all allocated memory is freed. + * @brief The mutex is created in the constructor and makes + * access mutual exclusive. + * @details Locking and unlocking is done during searching for free slots + * and deleting existing slots. */ - virtual ~PoolManager( void ); - /** - * Overwritten for thread safety. - */ - virtual ReturnValue_t deleteData(store_address_t); - virtual ReturnValue_t deleteData(uint8_t* buffer, uint32_t size, store_address_t* storeId = NULL); + MutexIF* mutex; }; -template -inline ReturnValue_t PoolManager::reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault) { - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); - ReturnValue_t status = LocalPool::reserveSpace(size,address,ignoreFault); - return status; -} - -template -inline PoolManager::PoolManager(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS]) : LocalPool(setObjectId, element_sizes, n_elements, true) { - mutex = MutexFactory::instance()->createMutex(); -} - -template -inline PoolManager::~PoolManager(void) { - MutexFactory::instance()->deleteMutex(mutex); -} - -template -inline ReturnValue_t PoolManager::deleteData( - store_address_t packet_id) { - // debug << "PoolManager( " << translateObject(getObjectId()) << " )::deleteData from store " << packet_id.pool_index << ". id is " << packet_id.packet_index << std::endl; - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); - ReturnValue_t status = LocalPool::deleteData(packet_id); - return status; -} - -template -inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, uint32_t size, - store_address_t* storeId) { - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); - ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId); - return status; -} +#include "PoolManager.tpp" #endif /* POOLMANAGER_H_ */ diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp new file mode 100644 index 000000000..5befeeb43 --- /dev/null +++ b/storagemanager/PoolManager.tpp @@ -0,0 +1,88 @@ +#ifndef POOLMANAGER_TPP_ +#define POOLMANAGER_TPP_ + +template +inline PoolManager::PoolManager(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS]) : + LocalPool(setObjectId, element_sizes, n_elements, true) { + mutex = MutexFactory::instance()->createMutex(); +} + +template +inline PoolManager::~PoolManager(void) { + MutexFactory::instance()->deleteMutex(mutex); +} + +template +inline ReturnValue_t PoolManager::reserveSpace( + const uint32_t size, store_address_t* address, bool ignoreFault) { + MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + ReturnValue_t status = LocalPool::reserveSpace(size, + address,ignoreFault); + return status; +} + +template +inline ReturnValue_t PoolManager::deleteData( + store_address_t packet_id) { + // debug << "PoolManager( " << translateObject(getObjectId()) << + // " )::deleteData from store " << packet_id.pool_index << + // ". id is "<< packet_id.packet_i#include ndex << std::endl; + MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + ReturnValue_t status = LocalPool::deleteData(packet_id); + return status; +} + +template +inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, + size_t size, store_address_t* storeId) { + MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + ReturnValue_t status = LocalPool::deleteData(buffer, + size, storeId); + return status; +} + +template +inline AccessorPair PoolManager::modifyData( + store_address_t storeId) { + StorageAccessor storeAccessor(storeId); + ReturnValue_t result = storeAccessor.lock(mutex); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "PoolManager: Error locking mutex with code 0x" + << std::hex << result << std::dec <::modifyData( + storeAccessor.storeId, &storeAccessor.dataPointer, + &storeAccessor.size_); + storeAccessor.assignConstPointer(); + storeAccessor.print(); + // Using move semantics to transfer the store accessor to the caller + return AccessorPair(result, std::move(storeAccessor)); +} + +template +inline ConstAccessorPair PoolManager::getData( + store_address_t storeId) { + ConstStorageAccessor storeAccessor(storeId); + ReturnValue_t result = storeAccessor.lock(mutex); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "PoolManager: Error locking mutex with code 0x" + << std::hex << result << std::dec <::getData( + storeAccessor.storeId, &storeAccessor.constDataPointer, + &storeAccessor.size_); + storeAccessor.print(); + // Using move semantics to transfer the store accessor to the caller + return ConstAccessorPair(result, std::move(storeAccessor)); +} + +#endif + diff --git a/storagemanager/StorageAccessor.cpp b/storagemanager/StorageAccessor.cpp new file mode 100644 index 000000000..a068d1694 --- /dev/null +++ b/storagemanager/StorageAccessor.cpp @@ -0,0 +1,154 @@ +//#include +// +//ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId): storeId(storeId) {} +// +//ConstStorageAccessor::~ConstStorageAccessor() { +// if(deleteData and store != nullptr) { +// sif::debug << "deleting store data" << std::endl; +// store->deleteDataNonLocking(storeId); +// } +// if(mutexLock != nullptr) { +// sif::debug << "unlocking mutex lock" << std::endl; +// mutexLock.reset(); +// } +//} +// +//ConstStorageAccessor& ConstStorageAccessor::operator=( +// ConstStorageAccessor&& other) { +// constDataPointer = other.constDataPointer; +// storeId = other.storeId; +// store = other.store; +// size_ = other.size_; +// deleteData = other.deleteData; +// this->store = other.store; +// // Transfer ownership of the lock. +// mutexLock = std::move(other.mutexLock); +// // This prevents double deletion of the resource +// other.mutexLock = nullptr; +// // This prevent premature deletion +// other.store = nullptr; +// return *this; +//} +// +//StorageAccessor::StorageAccessor(store_address_t storeId): +// ConstStorageAccessor(storeId) { +//} +// +//StorageAccessor& StorageAccessor::operator =( +// StorageAccessor&& other) { +// // Call the parent move assignment and also assign own member. +// dataPointer = other.dataPointer; +// StorageAccessor::operator=(std::move(other)); +// return * this; +//} +// +//// Call the parent move ctor and also transfer own member. +//StorageAccessor::StorageAccessor(StorageAccessor&& other): +// ConstStorageAccessor(std::move(other)), dataPointer(other.dataPointer) { +//} +// +//ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other): +// constDataPointer(other.constDataPointer), storeId(other.storeId), +// size_(other.size_), store(other.store), deleteData(other.deleteData), +// internalState(other.internalState) { +// // Transfer ownership of the lock. +// mutexLock = std::move(other.mutexLock); +// // This prevents double deletion of the resource. Not strictly necessary, +// // from the testing I have conducted so far but I am not familiar enough +// // with move semantics so I will just set the other lock to nullptr for now. +// other.mutexLock = nullptr; +// // This prevent premature deletion +// other.store = nullptr; +//} +// +//const uint8_t* ConstStorageAccessor::data() const { +// return constDataPointer; +//} +// +//size_t ConstStorageAccessor::size() const { +// if(internalState == AccessState::UNINIT) { +// sif::warning << "StorageAccessor: Not initialized!" << std::endl; +// } +// return size_; +//} +// +//void ConstStorageAccessor::getDataCopy(uint8_t *pointer) { +// if(internalState == AccessState::UNINIT) { +// sif::warning << "StorageAccessor: Not initialized!" << std::endl; +// return; +// } +// std::copy(constDataPointer, constDataPointer + size_, pointer); +//} +// +//void ConstStorageAccessor::release() { +// deleteData = false; +//} +// +//ReturnValue_t ConstStorageAccessor::lock(MutexIF* mutex, uint32_t mutexTimeout) { +// if(mutexLock == nullptr) { +// mutexLock = std::unique_ptr(new MutexHelper(mutex, mutexTimeout)); +// return mutexLock.get()->getResult(); +// } +// else { +// sif::warning << "StorageAccessor: Attempted to lock twice. Check code!" << std::endl; +// return HasReturnvaluesIF::RETURN_FAILED; +// } +//} +// +//void ConstStorageAccessor::unlock() { +// if(mutexLock != nullptr) { +// mutexLock.reset(); +// } +//} +// +//store_address_t ConstStorageAccessor::getId() const { +// return storeId; +//} +// +//void ConstStorageAccessor::print() const { +// if(internalState == AccessState::UNINIT) { +// sif::warning << "StorageAccessor: Not initialized!" << std::endl; +// return; +// } +// sif::info << "StorageAccessor: Printing data: ["; +// for(uint16_t iPool = 0; iPool < size_; iPool++) { +// sif::info << std::hex << (int)constDataPointer[iPool]; +// if(iPool < size_ - 1){ +// sif::info << " , "; +// } +// } +// sif::info << " ] " << std::endl; +//} +// +//void ConstStorageAccessor::assignStore(StorageManagerIF* store) { +// internalState = AccessState::READ; +// this->store = store; +//} +// +// +//uint8_t* StorageAccessor::data() { +// if(internalState == AccessState::UNINIT) { +// sif::warning << "StorageAccessor: Not initialized!" << std::endl; +// } +// return dataPointer; +//} +// +//ReturnValue_t StorageAccessor::write(uint8_t *data, size_t size, +// uint16_t offset) { +// if(internalState == AccessState::UNINIT) { +// sif::warning << "StorageAccessor: Not initialized!" << std::endl; +// return HasReturnvaluesIF::RETURN_FAILED; +// } +// if(offset + size > size_) { +// sif::error << "StorageAccessor: Data too large for pool entry!" << std::endl; +// return HasReturnvaluesIF::RETURN_FAILED; +// } +// std::copy(data, data + size, dataPointer); +// return HasReturnvaluesIF::RETURN_OK; +//} +// +//void StorageAccessor::assignConstPointer() { +// constDataPointer = dataPointer; +//} +// +// diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h new file mode 100644 index 000000000..d391c5c26 --- /dev/null +++ b/storagemanager/StorageAccessor.h @@ -0,0 +1,174 @@ +///** +// * @brief Helper classes to facilitate safe access to storages which is also +// * conforming to RAII principles +// * @details These helper can be used together with the +// * StorageManager classes to manage access to a storage. +// * It can take care of thread-safety while also providing +// * mechanisms to automatically clear storage data and unlocking the +// * pool. +// */ +//#ifndef TEST_PROTOTYPES_STORAGEACCESSOR_H_ +//#define TEST_PROTOTYPES_STORAGEACCESSOR_H_ +// +//#include +//#include +//#include +// +// +///** +// * @brief Accessor class which can be returned by pool managers +// * or passed and set by pool managers to have safe access to the pool +// * resources. +// */ +//class ConstStorageAccessor { +// //! StorageManager classes have exclusive access to private variables. +// template +// friend class PoolManager; +// template +// friend class LocalPool; +//public: +// /** +// * @brief Simple constructor which takes the store ID of the storage +// * entry to access. +// * @param storeId +// */ +// ConstStorageAccessor(store_address_t storeId); +// +// /** +// * @brief Move ctor and move assignment allow returning accessors as +// * a returnvalue. They prevent resource being free prematurely. +// * Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ +// * move-constructors-and-move-assignment-operators-cpp.md +// * @param +// * @return +// */ +// ConstStorageAccessor& operator= (ConstStorageAccessor&&); +// ConstStorageAccessor (ConstStorageAccessor&&); +// +// //! The copy ctor and copy assignemnt should be deleted implicitely +// //! according to https://foonathan.net/2019/02/special-member-functions/ +// //! but I still deleted them to make it more explicit. (remember rule of 5). +// ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete; +// ConstStorageAccessor (ConstStorageAccessor&) = delete; +// +// /** +// * @brief The destructor in default configuration takes care of +// * deleting the accessed pool entry and unlocking the mutex +// */ +// virtual ~ConstStorageAccessor(); +// +// /** +// * @brief Returns a pointer to the read-only data +// * @return +// */ +// const uint8_t* data() const; +// +// /** +// * @brief Copies the read-only data to the supplied pointer +// * @param pointer +// */ +// void getDataCopy(uint8_t *pointer); +// +// /** +// * @brief Calling this will prevent the Accessor from deleting the data +// * when the destructor is called. +// */ +// void release(); +// /** +// * @brief Locks the supplied mutex. +// * @details +// * The mutex will be unlocked automatically +// * when this class is destroyed (for example when exiting the scope). +// * Only one mutex can be locked at a time! +// * @param mutex +// * @param mutexTimeout +// * @return +// */ +// ReturnValue_t lock(MutexIF* mutex, +// uint32_t mutexTimeout = MutexIF::NO_TIMEOUT); +// /** +// * @brief Unlocks the mutex (if one has been locked previously). +// * Unless this function is called, the mutex is unlocked +// * when the class exits the scope. +// */ +// void unlock(); +// +// +// /** +// * Get the size of the data +// * @return +// */ +// size_t size() const; +// +// /** +// * Get the storage ID. +// * @return +// */ +// store_address_t getId() const; +// +// void print() const; +//protected: +// const uint8_t* constDataPointer = nullptr; +// store_address_t storeId; +// size_t size_ = 0; +// //! Managing pool, has to assign itself. +// StorageManagerIF* store = nullptr; +// //! Unique pointer to the mutex lock instance. Is initialized by +// //! the pool manager. +// std::unique_ptr mutexLock = nullptr; +// bool deleteData = true; +// +// enum class AccessState { +// UNINIT, +// READ +// }; +// //! Internal state for safety reasons. +// AccessState internalState = AccessState::UNINIT; +// /** +// * Used by the pool manager instances to assign themselves to the +// * accessor. This is necessary to delete the data when the acessor +// * exits the scope ! The internal state will be considered read +// * when this function is called, so take care all data is set properly as +// * well. +// * @param +// */ +// void assignStore(StorageManagerIF*); +// +//}; +// +// +///** +// * @brief Child class for modifyable data. Also has a normal pointer member. +// */ +//class StorageAccessor: public ConstStorageAccessor { +// //! StorageManager classes have exclusive access to private variables. +// template +// friend class PoolManager; +// template +// friend class LocalPool; +//public: +// StorageAccessor(store_address_t storeId); +// /** +// * @brief Move ctor and move assignment allow returning accessors as +// * a returnvalue. They prevent resource being free prematurely. +// * Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ +// * move-constructors-and-move-assignment-operators-cpp.md +// * @param +// * @return +// */ +// StorageAccessor& operator= (StorageAccessor&&); +// StorageAccessor (StorageAccessor&&); +// +// ReturnValue_t write(uint8_t *data, size_t size, +// uint16_t offset); +// uint8_t* data(); +// +//private: +// //! Non-const pointer for modifyable data. +// uint8_t* dataPointer = nullptr; +// //! For modifyable data, the const pointer is assigned to the normal +// //! pointer by the pool manager so both access functions can be used safely +// void assignConstPointer(); +//}; +// +//#endif /* TEST_PROTOTYPES_STORAGEACCESSOR_H_ */ diff --git a/storagemanager/StorageManagerIF.h b/storagemanager/StorageManagerIF.h index 575e9caa4..131b04c13 100644 --- a/storagemanager/StorageManagerIF.h +++ b/storagemanager/StorageManagerIF.h @@ -6,18 +6,19 @@ #include /** - * This union defines the type that identifies where a data packet is stored in the store. - * It comprises of a raw part to read it as raw value and a structured part to use it in - * pool-like stores. + * @brief This union defines the type that identifies where a data packet is + * stored in the store. + * It consists of a raw part to read it as raw value and + * a structured part to use it in pool-like stores. */ union store_address_t { /** * Default Constructor, initializing to INVALID_ADDRESS */ store_address_t():raw(0xFFFFFFFF){} + /** * Constructor to create an address object using the raw address - * * @param rawAddress */ store_address_t(uint32_t rawAddress):raw(rawAddress){} @@ -30,7 +31,8 @@ union store_address_t { * @param packetIndex */ store_address_t(uint16_t poolIndex, uint16_t packetIndex): - pool_index(poolIndex),packet_index(packetIndex){} + pool_index(poolIndex),packet_index(packetIndex) {} + /** * A structure with two elements to access the store address pool-like. */ @@ -94,7 +96,8 @@ public: * @li RETURN_FAILED if data could not be added. * storageId is unchanged then. */ - virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, uint32_t size, bool ignoreFault = false) = 0; + virtual ReturnValue_t addData(store_address_t* storageId, + const uint8_t * data, size_t size, bool ignoreFault = false) = 0; /** * @brief With deleteData, the storageManager frees the memory region * identified by packet_id. @@ -105,14 +108,18 @@ public: */ virtual ReturnValue_t deleteData(store_address_t packet_id) = 0; /** - * @brief Another deleteData which uses the pointer and size of the stored data to delete the content. + * @brief Another deleteData which uses the pointer and size of the + * stored data to delete the content. * @param buffer Pointer to the data. * @param size Size of data to be stored. * @param storeId Store id of the deleted element (optional) * @return @li RETURN_OK on success. * @li failure code if deletion did not work */ - virtual ReturnValue_t deleteData(uint8_t* buffer, uint32_t size, store_address_t* storeId = NULL) = 0; + virtual ReturnValue_t deleteData(uint8_t* buffer, size_t size, + store_address_t* storeId = nullptr) = 0; + + virtual ReturnValue_t deleteDataNonLocking(store_address_t packet_id) = 0; /** * @brief getData returns an address to data and the size of the data * for a given packet_id. @@ -125,12 +132,12 @@ public: * (e.g. an illegal packet_id was passed). */ virtual ReturnValue_t getData(store_address_t packet_id, - const uint8_t** packet_ptr, uint32_t* size) = 0; + const uint8_t** packet_ptr, size_t* size) = 0; /** * Same as above, but not const and therefore modifiable. */ virtual ReturnValue_t modifyData(store_address_t packet_id, - uint8_t** packet_ptr, uint32_t* size) = 0; + uint8_t** packet_ptr, size_t* size) = 0; /** * This method reserves an element of \c size. * @@ -144,13 +151,13 @@ public: * @li RETURN_FAILED if data could not be added. * storageId is unchanged then. */ - virtual ReturnValue_t getFreeElement(store_address_t* storageId, const uint32_t size, uint8_t** p_data, bool ignoreFault = false ) = 0; + virtual ReturnValue_t getFreeElement(store_address_t* storageId, + const size_t size, uint8_t** p_data, bool ignoreFault = false ) = 0; /** * Clears the whole store. * Use with care! */ virtual void clearStore() = 0; - }; #endif /* STORAGEMANAGERIF_H_ */