| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title Os/Mutex.hpp | ||
| 3 | // \brief common definitions for Os::Mutex | ||
| 4 | // ====================================================================== | ||
| 5 | #ifndef Os_Mutex_hpp | ||
| 6 | #define Os_Mutex_hpp | ||
| 7 | |||
| 8 | #include <Fw/FPrimeBasicTypes.hpp> | ||
| 9 | #include <Os/Os.hpp> | ||
| 10 | |||
| 11 | namespace Os { | ||
| 12 | |||
| 13 | struct MutexHandle {}; | ||
| 14 | |||
| 15 | class MutexInterface { | ||
| 16 | public: | ||
| 17 | enum Status { | ||
| 18 | OP_OK, //!< Operation was successful | ||
| 19 | ERROR_BUSY, //!< Mutex is busy | ||
| 20 | ERROR_DEADLOCK, //!< Deadlock condition detected | ||
| 21 | NOT_SUPPORTED, //!< Mutex does not support operation | ||
| 22 | ERROR_OTHER //!< All other errors | ||
| 23 | }; | ||
| 24 | |||
| 25 | //! \brief default constructor | ||
| 26 | 150 | MutexInterface() = default; | |
| 27 | |||
| 28 | //! \brief default virtual destructor | ||
| 29 | 300 | virtual ~MutexInterface() = default; | |
| 30 | |||
| 31 | //! \brief copy constructor is forbidden | ||
| 32 | MutexInterface(const MutexInterface& other) = delete; | ||
| 33 | |||
| 34 | //! \brief copy constructor is forbidden | ||
| 35 | MutexInterface(const MutexInterface* other) = delete; | ||
| 36 | |||
| 37 | //! \brief assignment operator is forbidden | ||
| 38 | MutexInterface& operator=(const MutexInterface& other) = delete; | ||
| 39 | |||
| 40 | //! \brief return the underlying mutex handle (implementation specific) | ||
| 41 | //! \return internal mutex handle representation | ||
| 42 | virtual MutexHandle* getHandle() = 0; | ||
| 43 | |||
| 44 | //! \brief provide a pointer to a Mutex delegate object | ||
| 45 | static MutexInterface* getDelegate(MutexHandleStorage& aligned_new_memory); | ||
| 46 | |||
| 47 | virtual Status take() = 0; //!< lock the mutex return status | ||
| 48 | virtual Status release() = 0; //!< unlock the mutex return status | ||
| 49 | }; | ||
| 50 | |||
| 51 | class Mutex final : public MutexInterface { | ||
| 52 | public: | ||
| 53 | Mutex(); //!< Constructor. Mutex is unlocked when created | ||
| 54 | ~Mutex() final; //!< Destructor | ||
| 55 | |||
| 56 | //! \brief return the underlying mutex handle (implementation specific) | ||
| 57 | //! \return internal mutex handle representation | ||
| 58 | MutexHandle* getHandle() override; | ||
| 59 | |||
| 60 | Status take() override; //!< lock the mutex and get return status | ||
| 61 | Status release() override; //!< unlock the mutex and get return status | ||
| 62 | void lock(); //!< lock the mutex and assert success | ||
| 63 | void unLock(); //!< unlock the mutex and assert success | ||
| 64 | 1007 | void unlock() { this->unLock(); } //!< alias for unLock to meet BasicLockable requirements | |
| 65 | |||
| 66 | private: | ||
| 67 | // This section is used to store the implementation-defined mutex handle. To Os::Mutex and fprime, this type is | ||
| 68 | // opaque and thus normal allocation cannot be done. Instead, we allow the implementor to store then handle in | ||
| 69 | // the byte-array here and set `handle` to that address for storage. | ||
| 70 | // | ||
| 71 | alignas(FW_HANDLE_ALIGNMENT) MutexHandleStorage m_handle_storage; //!< Mutex handle storage | ||
| 72 | MutexInterface& m_delegate; //!< Delegate for the real implementation | ||
| 73 | }; | ||
| 74 | //! \brief locks a mutex within the current scope | ||
| 75 | //! | ||
| 76 | //! The scope lock will lock the associated mutex immediately and will ensure the mutex is unlock when the scope lock | ||
| 77 | //! is destroyed. | ||
| 78 | //! | ||
| 79 | //! \warning it is unadvisable to dynamically allocate ScopeLock as this violates the implied usage. | ||
| 80 | class ScopeLock { | ||
| 81 | public: | ||
| 82 | //! \brief construct the scope lock | ||
| 83 | //! | ||
| 84 | //! Will lock the supplied mutex and will unlock the mutex when this object goes out of scope. | ||
| 85 | //! \param mutex | ||
| 86 | explicit ScopeLock(Mutex& mutex); | ||
| 87 | |||
| 88 | //!\brief unlock the scoped mutex | ||
| 89 | ~ScopeLock(); | ||
| 90 | |||
| 91 | //! \brief copy constructor is forbidden | ||
| 92 | ScopeLock(const ScopeLock& other) = delete; | ||
| 93 | |||
| 94 | //! \brief copy constructor is forbidden | ||
| 95 | ScopeLock(const ScopeLock* other) = delete; | ||
| 96 | |||
| 97 | //! \brief assignment operator is forbidden | ||
| 98 | ScopeLock& operator=(const ScopeLock& other) = delete; | ||
| 99 | |||
| 100 | private: | ||
| 101 | Mutex& m_mutex; //!< Stores the mutex reference | ||
| 102 | }; | ||
| 103 | } // namespace Os | ||
| 104 | |||
| 105 | #endif | ||
| 106 |