aboutsummaryrefslogtreecommitdiffstats
path: root/include/distortos/internal/synchronization/MutexControlBlock.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/distortos/internal/synchronization/MutexControlBlock.hpp')
-rw-r--r--include/distortos/internal/synchronization/MutexControlBlock.hpp184
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_