implemented new mutex interface

This commit is contained in:
Robin Müller 2020-08-07 20:36:37 +02:00
parent 1a118fe215
commit bfecbfbd80
9 changed files with 47 additions and 35 deletions

View File

@ -54,7 +54,8 @@ ReturnValue_t GlobalDataPool::unlockDataPool() {
} }
ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) { 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) { if(status != RETURN_OK) {
sif::error << "DataPool::DataPool: lock of mutex failed " sif::error << "DataPool::DataPool: lock of mutex failed "
"with error code: " << status << std::endl; "with error code: " << status << std::endl;

View File

@ -38,7 +38,7 @@ LocalDataSet::~LocalDataSet() {
ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) { ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) {
MutexIF* mutex = hkManager->getMutexHandle(); MutexIF* mutex = hkManager->getMutexHandle();
return mutex->lockMutex(timeoutMs); return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs);
} }
ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer, ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer,

View File

@ -8,7 +8,8 @@ class MutexHelper {
public: public:
MutexHelper(MutexIF* mutex, uint32_t timeoutMs) : MutexHelper(MutexIF* mutex, uint32_t timeoutMs) :
internalMutex(mutex) { internalMutex(mutex) {
ReturnValue_t status = mutex->lockMutex(timeoutMs); ReturnValue_t status = mutex->lockMutex(MutexIF::TimeoutType::WAITING,
timeoutMs);
if(status == MutexIF::MUTEX_TIMEOUT) { if(status == MutexIF::MUTEX_TIMEOUT) {
sif::error << "MutexHelper: Lock of mutex failed with timeout of " sif::error << "MutexHelper: Lock of mutex failed with timeout of "
<< timeoutMs << " milliseconds!" << std::endl; << timeoutMs << " milliseconds!" << std::endl;

View File

@ -12,20 +12,25 @@
*/ */
class MutexIF { class MutexIF {
public: public:
/** /**
* @brief Timeout value used for polling lock attempt. * Different types of timeout for the mutex lock.
* @details */
* If the lock is not successfull, MUTEX_TIMEOUT will be returned enum TimeoutType {
* immediately. Value needs to be defined in implementation. POLLING, //!< If mutex is not available, return immediately
*/ WAITING, //!< Wait a specified time for the mutex to become available
static const uint32_t POLLING; BLOCKING //!< Block indefinitely until the mutex becomes available.
/** };
* @brief Timeout value used for permanent blocking lock attempt.
* @details /**
* The task will be blocked (indefinitely) until the mutex is unlocked. * Lock the mutex.
* Value needs to be defined in implementation. * @param timeoutType
*/ * @param timeoutMs
static const uint32_t BLOCKING; * 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; 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); static const ReturnValue_t MUTEX_DESTROYED_WHILE_WAITING = MAKE_RETURN_CODE(12);
virtual ~MutexIF() {} virtual ~MutexIF() {}
virtual ReturnValue_t lockMutex(uint32_t timeoutMs) = 0;
virtual ReturnValue_t unlockMutex() = 0;
}; };

View File

@ -2,9 +2,6 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
const uint32_t MutexIF::POLLING = 0;
const uint32_t MutexIF::BLOCKING = portMAX_DELAY;
Mutex::Mutex() { Mutex::Mutex() {
handle = xSemaphoreCreateMutex(); handle = xSemaphoreCreateMutex();
if(handle == nullptr) { 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) { if (handle == nullptr) {
return MutexIF::MUTEX_NOT_FOUND; return MutexIF::MUTEX_NOT_FOUND;
} }
TickType_t timeout = MutexIF::POLLING; // If the timeout type is BLOCKING, this will be the correct value.
if(timeoutMs == MutexIF::BLOCKING) { uint32_t timeout = portMAX_DELAY;
timeout = MutexIF::BLOCKING; if(timeoutType == TimeoutType::POLLING) {
timeout = 0;
} }
else if(timeoutMs > MutexIF::POLLING){ else if(timeoutType == TimeoutType::WAITING){
timeout = pdMS_TO_TICKS(timeoutMs); timeout = pdMS_TO_TICKS(timeoutMs);
} }

View File

@ -18,7 +18,8 @@ class Mutex : public MutexIF {
public: public:
Mutex(); Mutex();
~Mutex(); ~Mutex();
ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::BLOCKING) override; ReturnValue_t lockMutex(TimeoutType timeoutType,
uint32_t timeoutMs) override;
ReturnValue_t unlockMutex() override; ReturnValue_t unlockMutex() override;
private: private:

View File

@ -40,9 +40,13 @@ Mutex::~Mutex() {
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
} }
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
int status = 0; int status = 0;
if (timeoutMs != MutexIF::BLOCKING) {
if(timeoutType == TimeoutType::POLLING) {
status = pthread_mutex_trylock(&mutex);
}
else if (timeoutType == TimeoutType::WAITING) {
timespec timeOut; timespec timeOut;
clock_gettime(CLOCK_REALTIME, &timeOut); clock_gettime(CLOCK_REALTIME, &timeOut);
uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec; 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_sec = nseconds / 1000000000;
timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000; timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000;
status = pthread_mutex_timedlock(&mutex, &timeOut); status = pthread_mutex_timedlock(&mutex, &timeOut);
} else { }
else if(timeoutType == TimeoutType::BLOCKING) {
status = pthread_mutex_lock(&mutex); status = pthread_mutex_lock(&mutex);
} }
switch (status) { switch (status) {
case EINVAL: 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. //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.

View File

@ -12,7 +12,7 @@ class Mutex : public MutexIF {
public: public:
Mutex(); Mutex();
virtual ~Mutex(); virtual ~Mutex();
virtual ReturnValue_t lockMutex(uint32_t timeoutMs); virtual ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs);
virtual ReturnValue_t unlockMutex(); virtual ReturnValue_t unlockMutex();
private: private:
pthread_mutex_t mutex; pthread_mutex_t mutex;

View File

@ -76,14 +76,15 @@ ReturnValue_t SubsystemBase::checkStateAgainstTable(
return RETURN_OK; return RETURN_OK;
} }
void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submode_t targetSubmode) { void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter,
Submode_t targetSubmode) {
CommandMessage command; CommandMessage command;
std::map<object_id_t, ChildInfo>::iterator iter; std::map<object_id_t, ChildInfo>::iterator iter;
commandsOutstanding = 0; commandsOutstanding = 0;
for (; tableIter.value != NULL; ++tableIter) { for (; tableIter.value != nullptr; ++tableIter) {
object_id_t object = tableIter.value->getObject(); object_id_t object = tableIter.value->getObject();
if ((iter = childrenMap.find(object)) == childrenMap.end()) { if ((iter = childrenMap.find(object)) == childrenMap.end()) {
//illegal table entry, should only happen due to misconfigured mode table //illegal table entry, should only happen due to misconfigured mode table