forked from nasa/fprime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor OS::Mutex in CMake selection (nasa#2790)
- Loading branch information
Showing
32 changed files
with
1,105 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# ====================================================================== | ||
# \title Os/Models/Mutex.fpp | ||
# \brief FPP type definitions for Os/Mutex.hpp concepts | ||
# ====================================================================== | ||
|
||
module Os { | ||
@ FPP shadow-enum representing Os::Mutex::Status | ||
enum MutexStatus { | ||
OP_OK, @< Operation was successful | ||
ERROR_BUSY, @< Mutex is busy | ||
ERROR_DEADLOCK, @< Deadlock condition detected | ||
ERROR_OTHER @< All other errors | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// ====================================================================== | ||
// \title Os/Mutex.cpp | ||
// \brief common function implementation for Os::Mutex | ||
// ====================================================================== | ||
#include <Fw/Types/Assert.hpp> | ||
#include <Os/Mutex.hpp> | ||
|
||
namespace Os { | ||
|
||
Mutex::Mutex() : m_handle_storage(), m_delegate(*MutexInterface::getDelegate(m_handle_storage)) { | ||
FW_ASSERT(&this->m_delegate == reinterpret_cast<MutexInterface*>(&this->m_handle_storage[0])); | ||
} | ||
|
||
Mutex::~Mutex() { | ||
FW_ASSERT(&this->m_delegate == reinterpret_cast<MutexInterface*>(&this->m_handle_storage[0])); | ||
m_delegate.~MutexInterface(); | ||
} | ||
|
||
MutexHandle* Mutex::getHandle() { | ||
FW_ASSERT(&this->m_delegate == reinterpret_cast<MutexInterface*>(&this->m_handle_storage[0])); | ||
return this->m_delegate.getHandle(); | ||
} | ||
|
||
Mutex::Status Mutex::take() { | ||
FW_ASSERT(&this->m_delegate == reinterpret_cast<MutexInterface*>(&this->m_handle_storage[0])); | ||
return this->m_delegate.take(); | ||
} | ||
|
||
Mutex::Status Mutex::release() { | ||
FW_ASSERT(&this->m_delegate == reinterpret_cast<MutexInterface*>(&this->m_handle_storage[0])); | ||
return this->m_delegate.release(); | ||
} | ||
|
||
void Mutex::lock() { | ||
FW_ASSERT(&this->m_delegate == reinterpret_cast<MutexInterface*>(&this->m_handle_storage[0])); | ||
Mutex::Status status = this->take(); | ||
FW_ASSERT(status == Mutex::Status::OP_OK, status); | ||
} | ||
|
||
void Mutex::unLock() { | ||
FW_ASSERT(&this->m_delegate == reinterpret_cast<MutexInterface*>(&this->m_handle_storage[0])); | ||
Mutex::Status status = this->release(); | ||
FW_ASSERT(status == Mutex::Status::OP_OK, status); | ||
} | ||
} // namespace Os |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,73 @@ | ||
#ifndef _Mutex_hpp_ | ||
#define _Mutex_hpp_ | ||
// ====================================================================== | ||
// \title Os/Mutex.hpp | ||
// \brief common definitions for Os::Mutex | ||
// ====================================================================== | ||
#ifndef Os_Mutex_hpp | ||
#define Os_Mutex_hpp | ||
|
||
#include <FpConfig.hpp> | ||
#include <Os/Os.hpp> | ||
|
||
namespace Os { | ||
|
||
class Mutex { | ||
public: | ||
struct MutexHandle {}; | ||
|
||
Mutex(); //!< Constructor. Mutex is unlocked when created | ||
virtual ~Mutex(); //!< Destructor | ||
class MutexInterface { | ||
// add enum with | ||
public: | ||
enum Status { | ||
OP_OK, //!< Operation was successful | ||
ERROR_BUSY, //!< Mutex is busy | ||
ERROR_DEADLOCK, //!< Deadlock condition detected | ||
ERROR_OTHER //!< All other errors | ||
}; | ||
|
||
void lock(); //!< lock the mutex | ||
void unLock(); //!< unlock the mutex | ||
void unlock() { this->unLock(); } //!< alias for unLock to meet BasicLockable requirements | ||
//! \brief default constructor | ||
MutexInterface() = default; | ||
|
||
private: | ||
//! \brief default virtual destructor | ||
virtual ~MutexInterface() = default; | ||
|
||
POINTER_CAST m_handle; //!< Stored handle to mutex | ||
}; | ||
} | ||
//! \brief copy constructor is forbidden | ||
MutexInterface(const MutexInterface& other) = delete; | ||
|
||
//! \brief assignment operator is forbidden | ||
MutexInterface& operator=(const MutexInterface& other) = delete; | ||
|
||
//! \brief return the underlying mutex handle (implementation specific) | ||
//! \return internal mutex handle representation | ||
virtual MutexHandle* getHandle() = 0; | ||
|
||
//! \brief provide a pointer to a Mutex delegate object | ||
static MutexInterface* getDelegate(HandleStorage& aligned_new_memory); // TODO | ||
|
||
virtual Status take() = 0; //!< lock the mutex return status | ||
virtual Status release() = 0; //!< unlock the mutex return status | ||
}; | ||
|
||
class Mutex final : public MutexInterface { | ||
public: | ||
Mutex(); //!< Constructor. Mutex is unlocked when created | ||
~Mutex() final; //!< Destructor | ||
|
||
//! \brief return the underlying mutex handle (implementation specific) | ||
//! \return internal mutex handle representation | ||
MutexHandle* getHandle() override; | ||
|
||
Status take() override; //!< lock the mutex and get return status | ||
Status release() override; //!< unlock the mutex and get return status | ||
void lock(); //!< lock the mutex and assert success | ||
void unLock(); //!< unlock the mutex and assert success | ||
void unlock() { this->unLock(); } //!< alias for unLock to meet BasicLockable requirements | ||
|
||
private: | ||
// This section is used to store the implementation-defined mutex handle. To Os::Mutex and fprime, this type is | ||
// opaque and thus normal allocation cannot be done. Instead, we allow the implementor to store then handle in | ||
// the byte-array here and set `handle` to that address for storage. | ||
// | ||
alignas(FW_HANDLE_ALIGNMENT) HandleStorage m_handle_storage; //!< Mutex handle storage | ||
MutexInterface& m_delegate; //!< Delegate for the real implementation | ||
}; | ||
} // namespace Os | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// ====================================================================== | ||
// \title Os/Posix/DefaultMutex.cpp | ||
// \brief sets default Os::Mutex Posix implementation via linker | ||
// ====================================================================== | ||
#include "Os/Posix/Mutex.hpp" | ||
#include "Os/Delegate.hpp" | ||
namespace Os { | ||
|
||
//! \brief get a delegate for MutexInterface that intercepts calls for Posix | ||
//! \param aligned_new_memory: aligned memory to fill | ||
//! \return: pointer to delegate | ||
MutexInterface *MutexInterface::getDelegate(HandleStorage& aligned_new_memory) { | ||
return Os::Delegate::makeDelegate<MutexInterface, Os::Posix::Mutex::PosixMutex>( | ||
aligned_new_memory | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,51 @@ | ||
#include <Os/Mutex.hpp> | ||
#include <pthread.h> | ||
// ====================================================================== | ||
// \title Os/Posix/Mutex.cpp | ||
// \brief Posix implementation for Os::Mutex | ||
// ====================================================================== | ||
#include <Os/Posix/Mutex.hpp> | ||
#include <Os/Posix/error.hpp> | ||
#include <Fw/Types/Assert.hpp> | ||
#include <new> | ||
|
||
namespace Os { | ||
namespace Posix { | ||
namespace Mutex { | ||
|
||
Mutex::Mutex() { | ||
pthread_mutex_t* handle = new(std::nothrow) pthread_mutex_t; | ||
FW_ASSERT(handle != nullptr); | ||
PosixMutex::PosixMutex() : Os::MutexInterface(), m_handle() { | ||
// set attributes | ||
pthread_mutexattr_t attribute; | ||
PlatformIntType status = pthread_mutexattr_init(&attribute); | ||
FW_ASSERT(status == 0, status); | ||
|
||
// set attributes | ||
pthread_mutexattr_t attr; | ||
pthread_mutexattr_init(&attr); | ||
// set to normal mutex type | ||
status = pthread_mutexattr_settype(&attribute, PTHREAD_MUTEX_NORMAL); | ||
FW_ASSERT(status == 0, status); | ||
|
||
NATIVE_INT_TYPE stat; | ||
// set to error checking | ||
// stat = pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK); | ||
// FW_ASSERT(stat == 0,stat); | ||
// set to check for priority inheritance | ||
status = pthread_mutexattr_setprotocol(&attribute, PTHREAD_PRIO_INHERIT); | ||
FW_ASSERT(status == 0, status); | ||
|
||
// set to normal mutex type | ||
stat = pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL); | ||
FW_ASSERT(stat == 0,stat); | ||
|
||
// set to check for priority inheritance | ||
stat = pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_INHERIT); | ||
FW_ASSERT(stat == 0,stat); | ||
|
||
stat = pthread_mutex_init(handle,&attr); | ||
FW_ASSERT(stat == 0,stat); | ||
|
||
this->m_handle = reinterpret_cast<POINTER_CAST>(handle); | ||
} | ||
status = pthread_mutex_init(&this->m_handle.m_mutex_descriptor, &attribute); | ||
FW_ASSERT(status == 0, status); | ||
} | ||
|
||
Mutex::~Mutex() { | ||
NATIVE_INT_TYPE stat = pthread_mutex_destroy(reinterpret_cast<pthread_mutex_t*>(this->m_handle)); | ||
FW_ASSERT(stat == 0,stat); | ||
delete reinterpret_cast<pthread_mutex_t*>(this->m_handle); | ||
} | ||
PosixMutex::~PosixMutex() { | ||
PlatformIntType status = pthread_mutex_destroy(&this->m_handle.m_mutex_descriptor); | ||
FW_ASSERT(status == 0, status); | ||
} | ||
|
||
void Mutex::lock() { | ||
NATIVE_INT_TYPE stat = pthread_mutex_lock(reinterpret_cast<pthread_mutex_t*>(this->m_handle)); | ||
FW_ASSERT(stat == 0,stat); | ||
} | ||
PosixMutex::Status PosixMutex::take() { | ||
PlatformIntType status = pthread_mutex_lock(&this->m_handle.m_mutex_descriptor); | ||
return Os::Posix::posix_status_to_mutex_status(status); | ||
} | ||
|
||
void Mutex::unLock() { | ||
NATIVE_INT_TYPE stat = pthread_mutex_unlock(reinterpret_cast<pthread_mutex_t*>(this->m_handle)); | ||
FW_ASSERT(stat == 0,stat); | ||
} | ||
PosixMutex::Status PosixMutex::release() { | ||
PlatformIntType status = pthread_mutex_unlock(&this->m_handle.m_mutex_descriptor); | ||
return Os::Posix::posix_status_to_mutex_status(status); | ||
} | ||
|
||
MutexHandle* PosixMutex::getHandle() { | ||
return &this->m_handle; | ||
} | ||
} // namespace Mutex | ||
} // namespace Posix | ||
} // namespace Os |
Oops, something went wrong.