From bfecbfbd80a9f64f84b55246b742c07bf1beccf9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 7 Aug 2020 20:36:37 +0200 Subject: [PATCH] implemented new mutex interface --- datapoolglob/GlobalDataPool.cpp | 3 ++- datapoollocal/LocalDataSet.cpp | 2 +- ipc/MutexHelper.h | 3 ++- ipc/MutexIF.h | 37 ++++++++++++++++++--------------- osal/FreeRTOS/Mutex.cpp | 15 +++++++------ osal/FreeRTOS/Mutex.h | 3 ++- osal/linux/Mutex.cpp | 12 ++++++++--- osal/linux/Mutex.h | 2 +- subsystem/SubsystemBase.cpp | 5 +++-- 9 files changed, 47 insertions(+), 35 deletions(-) diff --git a/datapoolglob/GlobalDataPool.cpp b/datapoolglob/GlobalDataPool.cpp index 25acaab3..9dedb4b8 100644 --- a/datapoolglob/GlobalDataPool.cpp +++ b/datapoolglob/GlobalDataPool.cpp @@ -54,7 +54,8 @@ ReturnValue_t GlobalDataPool::unlockDataPool() { } ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) { - ReturnValue_t status = mutex->lockMutex(timeoutMs); + ReturnValue_t status = mutex->lockMutex(MutexIF::TimeoutType::WAITING, + timeoutMs); if(status != RETURN_OK) { sif::error << "DataPool::DataPool: lock of mutex failed " "with error code: " << status << std::endl; diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 2a42cd38..8725f697 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -38,7 +38,7 @@ LocalDataSet::~LocalDataSet() { ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) { MutexIF* mutex = hkManager->getMutexHandle(); - return mutex->lockMutex(timeoutMs); + return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs); } ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer, diff --git a/ipc/MutexHelper.h b/ipc/MutexHelper.h index c9579e9b..fc6e38bf 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexHelper.h @@ -8,7 +8,8 @@ class MutexHelper { public: MutexHelper(MutexIF* mutex, uint32_t timeoutMs) : internalMutex(mutex) { - ReturnValue_t status = mutex->lockMutex(timeoutMs); + ReturnValue_t status = mutex->lockMutex(MutexIF::TimeoutType::WAITING, + timeoutMs); if(status == MutexIF::MUTEX_TIMEOUT) { sif::error << "MutexHelper: Lock of mutex failed with timeout of " << timeoutMs << " milliseconds!" << std::endl; diff --git a/ipc/MutexIF.h b/ipc/MutexIF.h index 29e59e58..b174fe0d 100644 --- a/ipc/MutexIF.h +++ b/ipc/MutexIF.h @@ -12,20 +12,25 @@ */ class MutexIF { public: - /** - * @brief Timeout value used for polling lock attempt. - * @details - * If the lock is not successfull, MUTEX_TIMEOUT will be returned - * immediately. Value needs to be defined in implementation. - */ - static const uint32_t POLLING; - /** - * @brief Timeout value used for permanent blocking lock attempt. - * @details - * The task will be blocked (indefinitely) until the mutex is unlocked. - * Value needs to be defined in implementation. - */ - static const uint32_t BLOCKING; + /** + * Different types of timeout for the mutex lock. + */ + enum TimeoutType { + POLLING, //!< If mutex is not available, return immediately + WAITING, //!< Wait a specified time for the mutex to become available + BLOCKING //!< Block indefinitely until the mutex becomes available. + }; + + /** + * Lock the mutex. + * @param timeoutType + * @param timeoutMs + * This value will only be used for TimeoutType::WAIT + * @return + */ + virtual ReturnValue_t lockMutex(TimeoutType timeoutType = + TimeoutType::BLOCKING, uint32_t timeoutMs = 0) = 0; + virtual ReturnValue_t unlockMutex() = 0; static const uint8_t INTERFACE_ID = CLASS_ID::MUTEX_IF; /** @@ -77,9 +82,7 @@ public: */ static const ReturnValue_t MUTEX_DESTROYED_WHILE_WAITING = MAKE_RETURN_CODE(12); - virtual ~MutexIF() {} - virtual ReturnValue_t lockMutex(uint32_t timeoutMs) = 0; - virtual ReturnValue_t unlockMutex() = 0; + virtual ~MutexIF() {} }; diff --git a/osal/FreeRTOS/Mutex.cpp b/osal/FreeRTOS/Mutex.cpp index 8a5c444d..764b0ae0 100644 --- a/osal/FreeRTOS/Mutex.cpp +++ b/osal/FreeRTOS/Mutex.cpp @@ -2,9 +2,6 @@ #include -const uint32_t MutexIF::POLLING = 0; -const uint32_t MutexIF::BLOCKING = portMAX_DELAY; - Mutex::Mutex() { handle = xSemaphoreCreateMutex(); if(handle == nullptr) { @@ -19,15 +16,17 @@ Mutex::~Mutex() { } -ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { +ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, + uint32_t timeoutMs) { if (handle == nullptr) { return MutexIF::MUTEX_NOT_FOUND; } - TickType_t timeout = MutexIF::POLLING; - if(timeoutMs == MutexIF::BLOCKING) { - timeout = MutexIF::BLOCKING; + // If the timeout type is BLOCKING, this will be the correct value. + uint32_t timeout = portMAX_DELAY; + if(timeoutType == TimeoutType::POLLING) { + timeout = 0; } - else if(timeoutMs > MutexIF::POLLING){ + else if(timeoutType == TimeoutType::WAITING){ timeout = pdMS_TO_TICKS(timeoutMs); } diff --git a/osal/FreeRTOS/Mutex.h b/osal/FreeRTOS/Mutex.h index 37f1791c..2a4fae26 100644 --- a/osal/FreeRTOS/Mutex.h +++ b/osal/FreeRTOS/Mutex.h @@ -18,7 +18,8 @@ class Mutex : public MutexIF { public: Mutex(); ~Mutex(); - ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::BLOCKING) override; + ReturnValue_t lockMutex(TimeoutType timeoutType, + uint32_t timeoutMs) override; ReturnValue_t unlockMutex() override; private: diff --git a/osal/linux/Mutex.cpp b/osal/linux/Mutex.cpp index bdcf3439..c99fe531 100644 --- a/osal/linux/Mutex.cpp +++ b/osal/linux/Mutex.cpp @@ -40,9 +40,13 @@ Mutex::~Mutex() { pthread_mutex_destroy(&mutex); } -ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { +ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) { int status = 0; - if (timeoutMs != MutexIF::BLOCKING) { + + if(timeoutType == TimeoutType::POLLING) { + status = pthread_mutex_trylock(&mutex); + } + else if (timeoutType == TimeoutType::WAITING) { timespec timeOut; clock_gettime(CLOCK_REALTIME, &timeOut); uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec; @@ -50,9 +54,11 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { timeOut.tv_sec = nseconds / 1000000000; timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000; status = pthread_mutex_timedlock(&mutex, &timeOut); - } else { + } + else if(timeoutType == TimeoutType::BLOCKING) { status = pthread_mutex_lock(&mutex); } + switch (status) { case EINVAL: //The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling. diff --git a/osal/linux/Mutex.h b/osal/linux/Mutex.h index 607337ae..26420c2e 100644 --- a/osal/linux/Mutex.h +++ b/osal/linux/Mutex.h @@ -12,7 +12,7 @@ class Mutex : public MutexIF { public: Mutex(); virtual ~Mutex(); - virtual ReturnValue_t lockMutex(uint32_t timeoutMs); + virtual ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs); virtual ReturnValue_t unlockMutex(); private: pthread_mutex_t mutex; diff --git a/subsystem/SubsystemBase.cpp b/subsystem/SubsystemBase.cpp index 51c35f1f..71fa81b7 100644 --- a/subsystem/SubsystemBase.cpp +++ b/subsystem/SubsystemBase.cpp @@ -76,14 +76,15 @@ ReturnValue_t SubsystemBase::checkStateAgainstTable( return RETURN_OK; } -void SubsystemBase::executeTable(HybridIterator tableIter, Submode_t targetSubmode) { +void SubsystemBase::executeTable(HybridIterator tableIter, + Submode_t targetSubmode) { CommandMessage command; std::map::iterator iter; commandsOutstanding = 0; - for (; tableIter.value != NULL; ++tableIter) { + for (; tableIter.value != nullptr; ++tableIter) { object_id_t object = tableIter.value->getObject(); if ((iter = childrenMap.find(object)) == childrenMap.end()) { //illegal table entry, should only happen due to misconfigured mode table