diff options
Diffstat (limited to 'include/distortos/internal/synchronization/MutexControlBlock.hpp')
-rw-r--r-- | include/distortos/internal/synchronization/MutexControlBlock.hpp | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/include/distortos/internal/synchronization/MutexControlBlock.hpp b/include/distortos/internal/synchronization/MutexControlBlock.hpp new file mode 100644 index 0000000..93c3ee6 --- /dev/null +++ b/include/distortos/internal/synchronization/MutexControlBlock.hpp @@ -0,0 +1,184 @@ +/** + * \file + * \brief MutexControlBlock class header + * + * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info + * + * \par License + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not + * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXCONTROLBLOCK_HPP_ +#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXCONTROLBLOCK_HPP_ + +#include "distortos/internal/scheduler/ThreadList.hpp" + +#include "distortos/internal/synchronization/MutexListNode.hpp" + +#include "distortos/TickClock.hpp" + +namespace distortos +{ + +namespace internal +{ + +/// MutexControlBlock class is a control block for Mutex +class MutexControlBlock : public MutexListNode +{ +public: + + /// mutex protocols + enum class Protocol : uint8_t + { + /// no protocol, similar to PTHREAD_PRIO_NONE + none, + /// priority inheritance protocol, similar to PTHREAD_PRIO_INHERIT + priorityInheritance, + /// priority protection protocol (Immediate Ceiling Priority Protocol), similar to PTHREAD_PRIO_PROTECT + priorityProtect, + }; + + /** + * \brief MutexControlBlock constructor + * + * \param [in] protocol is the mutex protocol + * \param [in] priorityCeiling is the priority ceiling of mutex, ignored when protocol != Protocol::priorityProtect + */ + + constexpr MutexControlBlock(const Protocol protocol, const uint8_t priorityCeiling) : + MutexListNode{}, + blockedList_{}, + owner_{}, + protocol_{protocol}, + priorityCeiling_{priorityCeiling} + { + + } + + /** + * \brief Blocks current thread, transferring it to blockedList_. + * + * \return 0 on success, error code otherwise: + * - values returned by Scheduler::block(); + */ + + int block(); + + /** + * \brief Blocks current thread with timeout, transferring it to blockedList_. + * + * \param [in] timePoint is the time point at which the thread will be unblocked (if not already unblocked) + * + * \return 0 on success, error code otherwise: + * - values returned by Scheduler::blockUntil(); + */ + + int blockUntil(TickClock::time_point timePoint); + + /** + * \brief Gets "boosted priority" of the mutex. + * + * "Boosted priority" of the mutex depends on the selected priority protocol: + * - None - 0, + * - PriorityInheritance - effective priority of the highest priority thread blocked on this mutex or 0 if no + * threads are blocked, + * - PriorityProtect - priority ceiling. + * + * \return "boosted priority" of the mutex + */ + + uint8_t getBoostedPriority() const; + + /** + * \return owner of the mutex, nullptr if mutex is currently unlocked + */ + + ThreadControlBlock* getOwner() const + { + return owner_; + } + + /** + * \return priority ceiling of mutex, valid only when protocol_ == Protocol::priorityProtect + */ + + uint8_t getPriorityCeiling() const + { + return priorityCeiling_; + } + + /** + * \return mutex protocol + */ + + Protocol getProtocol() const + { + return protocol_; + } + + /** + * \brief Performs actual locking of previously unlocked mutex. + * + * \attention mutex must be unlocked + */ + + void lock(); + + /** + * \brief Performs unlocking or transfer of lock from current owner to next thread on the list. + * + * Mutex is unlocked if blockedList_ is empty, otherwise the ownership is transfered to the next thread. + * + * \attention mutex must be locked + */ + + void unlockOrTransferLock(); + +private: + + /** + * \brief Performs action required for priority inheritance before actually blocking on the mutex. + * + * This must be called in block() and blockUntil() before actually blocking of the calling thread. + * + * \attantion mutex's protocol must be PriorityInheritance + */ + + void priorityInheritanceBeforeBlock() const; + + /** + * \brief Performs transfer of lock from current owner to next thread on the list. + * + * \attention mutex must be locked and blockedList_ must not be empty + */ + + void transferLock(); + + /** + * \brief Performs actual unlocking of previously locked mutex. + * + * \attention mutex must be locked and blockedList_ must be empty + */ + + void unlock(); + + /// ThreadControlBlock objects blocked on mutex + ThreadList blockedList_; + + /// owner of the mutex + ThreadControlBlock* owner_; + + /// mutex protocol + Protocol protocol_; + + /// priority ceiling of mutex, valid only when protocol_ == Protocol::priorityProtect + uint8_t priorityCeiling_; +}; + +} // namespace internal + +} // namespace distortos + +#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXCONTROLBLOCK_HPP_ |