diff options
Diffstat (limited to 'include/distortos/Mutex.hpp')
-rw-r--r-- | include/distortos/Mutex.hpp | 280 |
1 files changed, 0 insertions, 280 deletions
diff --git a/include/distortos/Mutex.hpp b/include/distortos/Mutex.hpp deleted file mode 100644 index 481700d..0000000 --- a/include/distortos/Mutex.hpp +++ /dev/null @@ -1,280 +0,0 @@ -/** - * \file - * \brief Mutex 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_MUTEX_HPP_ -#define INCLUDE_DISTORTOS_MUTEX_HPP_ - -#include "distortos/internal/synchronization/MutexControlBlock.hpp" - -namespace distortos -{ - -/** - * \brief Mutex is the basic synchronization primitive - * - * Similar to std::mutex - http://en.cppreference.com/w/cpp/thread/mutex - * Similar to POSIX pthread_mutex_t - - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09 -> 2.9.3 Thread Mutexes - * - * \ingroup synchronization - */ - -class Mutex -{ -public: - - /// mutex protocols - using Protocol = internal::MutexControlBlock::Protocol; - - /// type used for counting recursive locks - using RecursiveLocksCount = uint16_t; - - /// type of mutex - enum class Type : uint8_t - { - /// normal mutex, similar to PTHREAD_MUTEX_NORMAL - normal, - /// mutex with additional error checking, similar to PTHREAD_MUTEX_ERRORCHECK - errorChecking, - /// recursive mutex, similar to PTHREAD_MUTEX_RECURSIVE - recursive - }; - - /** - * \brief Gets the maximum number of recursive locks possible before returning EAGAIN - * - * \note Actual number of lock() operations possible is getMaxRecursiveLocks() + 1. - * - * \return maximum number of recursive locks possible before returning EAGAIN - */ - - constexpr static RecursiveLocksCount getMaxRecursiveLocks() - { - return std::numeric_limits<RecursiveLocksCount>::max(); - } - - /** - * \brief Mutex constructor - * - * Similar to std::mutex::mutex() - http://en.cppreference.com/w/cpp/thread/mutex/mutex - * Similar to pthread_mutex_init() - - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_init.html - * - * \param [in] type is the type of mutex, default - Type::normal - * \param [in] protocol is the mutex protocol, default - Protocol::none - * \param [in] priorityCeiling is the priority ceiling of mutex, ignored when protocol != Protocol::priorityProtect, - * default - 0 - */ - - constexpr explicit Mutex(const Type type = Type::normal, const Protocol protocol = Protocol::none, - const uint8_t priorityCeiling = {}) : - controlBlock_{protocol, priorityCeiling}, - recursiveLocksCount_{}, - type_{type} - { - - } - - /** - * \brief Locks the mutex. - * - * Similar to std::mutex::lock() - http://en.cppreference.com/w/cpp/thread/mutex/lock - * Similar to pthread_mutex_lock() - - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html# - * - * If the mutex is already locked by another thread, the calling thread shall block until the mutex becomes - * available. This function shall return with the mutex in the locked state with the calling thread as its owner. If - * a thread attempts to relock a mutex that it has already locked, deadlock occurs. - * - * \return zero if the caller successfully locked the mutex, error code otherwise: - * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been - * exceeded; - * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex; - * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling - * thread's priority is higher than the mutex's current priority ceiling; - */ - - int lock(); - - /** - * \brief Tries to lock the mutex. - * - * Similar to std::mutex::try_lock() - http://en.cppreference.com/w/cpp/thread/mutex/try_lock - * Similar to pthread_mutex_trylock() - - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html# - * - * This function shall be equivalent to lock(), except that if the mutex is currently locked (by any thread, - * including the current thread), the call shall return immediately. - * - * \return zero if the caller successfully locked the mutex, error code otherwise: - * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been - * exceeded; - * - EBUSY - the mutex could not be acquired because it was already locked; - * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling - * thread's priority is higher than the mutex's current priority ceiling; - */ - - int tryLock(); - - /** - * \brief Tries to lock the mutex for given duration of time. - * - * Similar to std::timed_mutex::try_lock_for() - http://en.cppreference.com/w/cpp/thread/timed_mutex/try_lock_for - * Similar to pthread_mutex_timedlock() - - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_timedlock.html# - * - * If the mutex is already locked, the calling thread shall block until the mutex becomes available as in lock() - * function. If the mutex cannot be locked without waiting for another thread to unlock the mutex, this wait shall - * be terminated when the specified timeout expires. - * - * Under no circumstance shall the function fail with a timeout if the mutex can be locked immediately. The validity - * of the duration parameter need not be checked if the mutex can be locked immediately. - * - * \param [in] duration is the duration after which the wait will be terminated without locking the mutex - * - * \return zero if the caller successfully locked the mutex, error code otherwise: - * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been - * exceeded; - * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex; - * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling - * thread's priority is higher than the mutex's current priority ceiling; - * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired; - */ - - int tryLockFor(TickClock::duration duration); - - /** - * Tries to lock the mutex for given duration of time. - * - * Template variant of tryLockFor(TickClock::duration duration). - * - * \tparam Rep is type of tick counter - * \tparam Period is std::ratio type representing the tick period of the clock, in seconds - * - * \param [in] duration is the duration after which the wait will be terminated without locking the mutex - * - * \return zero if the caller successfully locked the mutex, error code otherwise: - * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been - * exceeded; - * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex; - * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling - * thread's priority is higher than the mutex's current priority ceiling; - * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired; - */ - - template<typename Rep, typename Period> - int tryLockFor(const std::chrono::duration<Rep, Period> duration) - { - return tryLockFor(std::chrono::duration_cast<TickClock::duration>(duration)); - } - - /** - * \brief Tries to lock the mutex until given time point. - * - * Similar to std::timed_mutex::try_lock_until() - - * http://en.cppreference.com/w/cpp/thread/timed_mutex/try_lock_until - * Similar to pthread_mutex_timedlock() - - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_timedlock.html# - * - * If the mutex is already locked, the calling thread shall block until the mutex becomes available as in lock() - * function. If the mutex cannot be locked without waiting for another thread to unlock the mutex, this wait shall - * be terminated when the specified timeout expires. - * - * Under no circumstance shall the function fail with a timeout if the mutex can be locked immediately. The validity - * of the timePoint parameter need not be checked if the mutex can be locked immediately. - * - * \param [in] timePoint is the time point at which the wait will be terminated without locking the mutex - * - * \return zero if the caller successfully locked the mutex, error code otherwise: - * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been - * exceeded; - * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex; - * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling - * thread's priority is higher than the mutex's current priority ceiling; - * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired; - */ - - int tryLockUntil(TickClock::time_point timePoint); - - /** - * \brief Tries to lock the mutex until given time point. - * - * Template variant of tryLockUntil(TickClock::time_point timePoint). - * - * \tparam Duration is a std::chrono::duration type used to measure duration - * - * \param [in] timePoint is the time point at which the wait will be terminated without locking the mutex - * - * \return zero if the caller successfully locked the mutex, error code otherwise: - * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been - * exceeded; - * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex; - * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling - * thread's priority is higher than the mutex's current priority ceiling; - * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired; - */ - - template<typename Duration> - int tryLockUntil(const std::chrono::time_point<TickClock, Duration> timePoint) - { - return tryLockUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint)); - } - - /** - * \brief Unlocks the mutex. - * - * Similar to std::mutex::unlock() - http://en.cppreference.com/w/cpp/thread/mutex/unlock - * Similar to pthread_mutex_unlock() - - * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html# - * - * The mutex must be locked by the current thread, otherwise, the behavior is undefined. If there are threads - * blocked on this mutex, the highest priority waiting thread shall be unblocked, and if there is more than one - * highest priority thread blocked waiting, then the highest priority thread that has been waiting the longest shall - * be unblocked. - * - * \return zero if the caller successfully unlocked the mutex, error code otherwise: - * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex; - */ - - int unlock(); - -private: - - /** - * \brief Internal version of tryLock(). - * - * Internal version with no interrupt masking and additional code for ErrorChecking type (which is not required for - * tryLock()). - * - * \return zero if the caller successfully locked the mutex, error code otherwise: - * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been - * exceeded; - * - EBUSY - the mutex could not be acquired because it was already locked; - * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex; - * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling - * thread's priority is higher than the mutex's current priority ceiling; - */ - - int tryLockInternal(); - - /// instance of control block - internal::MutexControlBlock controlBlock_; - - /// number of recursive locks, used when mutex type is Recursive - RecursiveLocksCount recursiveLocksCount_; - - /// type of mutex - Type type_; -}; - -} // namespace distortos - -#endif // INCLUDE_DISTORTOS_MUTEX_HPP_ |