QP/C++ 8.1.2
Real-Time Event Framework
Loading...
Searching...
No Matches

Blocking Mutex of the QXK preemptive kernel. More...

#include <qxk.hpp>

Public Member Functions

 QXMutex ()
void init (QPrioSpec const prioSpec) noexcept
 Initialize the QXK priority-ceiling mutex QP::QXMutex.
bool lock (QTimeEvtCtr const nTicks=QXTHREAD_NO_TIMEOUT) noexcept
 Lock the QXK priority-ceiling mutex ::QXMutex.
bool tryLock () noexcept
 Try to lock the QXK priority-ceiling mutex QP::QXMutex.
void unlock () noexcept
 Unlock the QXK priority-ceiling mutex QP::QXMutex.

Private Member Functions

bool tryAcq_ (QXThread *const curr) noexcept
void relOneThr_ () noexcept

Private Attributes

QActive m_ao
 Active object used as a placeholder AO for this mutex in QActive_registry_[].
QPSet m_waitSet
 Set of extended-threads waiting on this mutex.

Friends

class QS

Detailed Description

Blocking Mutex of the QXK preemptive kernel.

Details
QP::QXMutex is a blocking mutual exclusion mechanism that can also apply the priority-ceiling protocol to avoid unbounded priority inversion (if initialized with a non-zero ceiling priority, see QXMutex::init()). In that case, QP::QXMutex requires its own unique QP priority level, which cannot be used by any thread or any other QP::QXMutex.

If initialized with preemption-ceiling of zero, QP::QXMutex does not use the priority-ceiling protocol and does not require a unique QP priority (see QXMutex::init()).

QP::QXMutex is recursive (re-entrant), which means that it can be locked multiple times (up to 255 levels) by the same thread without causing deadlock.

QP::QXMutex is primarily intended for the extended (blocking) threads, but can also be used by the basic threads through the non-blocking QXMutex_tryLock() API.

Note
QP::QXMutex should be used in situations when at least one of the extended threads contending for the mutex blocks while holding the mutex (between the QXMutex_lock() and QXMutex_unlock() operations). If no blocking is needed while holding the mutex, the more efficient non-blocking mechanism of selective QXK scheduler locking should be used instead. Selective scheduler locking is available for both basic threads and extended threads, so it is applicable to situations where resources are shared among all these threads.

Usage
The following example illustrates how to instantiate and use the mutex to protect a shared resource (random seed of a pseudo-random number generator).

QP::QXMutex TH_mutex; // <===
. . .
void XThread2::run(QP::QXThread * const thr) {
TH_mutex.init(APP::N_PHILO + 6U); // priority-ceiling mutex
for (;;) {
. . .
TH_mutex.lock(QP::QXTHREAD_NO_TIMEOUT); // lock the mutex
QP::QXThread::delay(5U); // wait more (BLOCK)
TH_mutex.unlock();
}
}
Blocking Mutex of the QXK preemptive kernel.
Definition qxk.hpp:158
void unlock() noexcept
Unlock the QXK priority-ceiling mutex QP::QXMutex.
void init(QPrioSpec const prioSpec) noexcept
Initialize the QXK priority-ceiling mutex QP::QXMutex.
Definition qxk_mutex.cpp:57
bool lock(QTimeEvtCtr const nTicks=QXTHREAD_NO_TIMEOUT) noexcept
Lock the QXK priority-ceiling mutex QXMutex.
eXtended (blocking) thread of the QXK preemptive kernel
Definition qxk.hpp:79
static bool delay(QTimeEvtCtr const nTicks) noexcept
Delay (block) the current extended thread for a specified # ticks.
Definition qxk_xthr.cpp:79
constexpr QTimeEvtCtr QXTHREAD_NO_TIMEOUT
No-timeout when blocking on semaphores/mutextes/event-queues.
Definition qxk.hpp:37

Definition at line 158 of file qxk.hpp.

Constructor & Destructor Documentation

◆ QXMutex()

QP::QXMutex::QXMutex ( )

Definition at line 52 of file qxk_mutex.cpp.

Member Function Documentation

◆ init()

void QP::QXMutex::init ( QPrioSpec const prioSpec)
noexcept

Initialize the QXK priority-ceiling mutex QP::QXMutex.

Details
Initialize the QXK priority ceiling mutex.

Parameters
[in]prioSpecthe priority specification for the mutex (See also QP::QPrioSpec). This value might also be zero.
Note
prioSpec == 0 means that the priority-ceiling protocol shall not be used by this mutex. Such mutex will not change (boost) the priority of the holding threads.

Conversely, prioSpec != 0 means that the priority-ceiling protocol shall be used by this mutex. Such mutex will temporarily boost the priority and priority-threshold of the holding thread to the priority specification in prioSpec (see QP::QPrioSpec).

Usage
The following example illustrates how to instantiate and use the mutex to protect a shared resource (random seed of a pseudo-random number generator).

QP::QXMutex TH_mutex;
. . .
void XThread2::run(QP::QXThread * const thr) {
TH_mutex.init(APP::N_PHILO + 6U); // <===
for (;;) {
. . .
TH_mutex.lock(QP::QXTHREAD_NO_TIMEOUT); // lock the mutex
QP::QXThread::delay(5U); // wait more (BLOCK)
TH_mutex.unlock();
}
}

Definition at line 57 of file qxk_mutex.cpp.

◆ lock()

bool QP::QXMutex::lock ( QTimeEvtCtr const nTicks = QXTHREAD_NO_TIMEOUT)
noexcept

Lock the QXK priority-ceiling mutex ::QXMutex.

Parameters
[in]nTicksnumber of clock ticks (at the associated rate) to wait for the mutex. The value of QP::QXTHREAD_NO_TIMEOUT indicates that no timeout will occur and the mutex could block indefinitely.
Returns
'true' if the mutex has been acquired and 'false' if a timeout occurred.
Note
The mutex locks are allowed to nest, meaning that the same extended thread can lock the same mutex multiple times (< 255). However, each call to QXMutex_lock() must be balanced by the matching call to QXMutex_unlock().

Usage
The following example illustrates how to instantiate and use the mutex to protect a shared resource (random seed of a pseudo-random number generator).

QP::QXMutex TH_mutex;
. . .
void XThread2::run(QP::QXThread * const thr) {
TH_mutex.init(APP::N_PHILO + 6U);
for (;;) {
. . .
TH_mutex.lock(QP::QXTHREAD_NO_TIMEOUT); // <===
QP::QXThread::delay(5U); // wait more (BLOCK)
TH_mutex.unlock();
}
}

Definition at line 158 of file qxk_mutex.cpp.

◆ tryLock()

bool QP::QXMutex::tryLock ( )
noexcept

Try to lock the QXK priority-ceiling mutex QP::QXMutex.

Returns
'true' if the mutex was successfully locked and 'false' if the mutex was unavailable and was NOT locked.
Note
This function can be called from both basic threads (active objects) and extended threads.
The mutex locks are allowed to nest, meaning that the same extended thread can lock the same mutex multiple times (<= 255). However, each successful call to QXMutex_tryLock() must be balanced by the matching call to QXMutex_unlock().

Definition at line 228 of file qxk_mutex.cpp.

◆ unlock()

void QP::QXMutex::unlock ( )
noexcept

Unlock the QXK priority-ceiling mutex QP::QXMutex.

Note
This function can be called from both basic threads (active objects) and extended threads.
The mutex locks are allowed to nest, meaning that the same extended thread can lock the same mutex multiple times (<= 225). However, each call to QXMutex_lock() or a successful call to QXMutex_tryLock() must be balanced by the matching call to QXMutex_unlock().

Usage
The following example illustrates how to instantiate and use the mutex to protect a shared resource (random seed of a pseudo-random number generator).

QP::QXMutex TH_mutex;
. . .
void XThread2::run(QP::QXThread * const thr) {
TH_mutex.init(APP::N_PHILO + 6U);
for (;;) {
. . .
QP::QXThread::delay(5U); // wait more (BLOCK)
TH_mutex.unlock(); // <===
}
}

Definition at line 260 of file qxk_mutex.cpp.

◆ tryAcq_()

bool QP::QXMutex::tryAcq_ ( QXThread *const curr)
privatenoexcept

Definition at line 75 of file qxk_mutex.cpp.

◆ relOneThr_()

void QP::QXMutex::relOneThr_ ( )
privatenoexcept

Definition at line 338 of file qxk_mutex.cpp.

◆ QS

friend class QS
friend

Definition at line 174 of file qxk.hpp.

Member Data Documentation

◆ m_ao

QActive QP::QXMutex::m_ao
private

Active object used as a placeholder AO for this mutex in QActive_registry_[].

Definition at line 170 of file qxk.hpp.

◆ m_waitSet

QPSet QP::QXMutex::m_waitSet
private

Set of extended-threads waiting on this mutex.

Definition at line 171 of file qxk.hpp.


The documentation for this class was generated from the following files: