QP/C++ 6.9.3
QXMutex Class Reference

Priority Ceiling Mutex the QXK preemptive kernel. More...

#include <qxthread.hpp>

Collaboration diagram for QXMutex:
Collaboration graph

Public Member Functions

void init (std::uint_fast8_t const ceiling) noexcept
 initialize the QXK priority-ceiling mutex QP::QXMutex More...
 
bool lock (std::uint_fast16_t const nTicks=QXTHREAD_NO_TIMEOUT) noexcept
 lock the QXK priority-ceiling mutex QP::QXMutex More...
 
bool tryLock (void) noexcept
 try to lock the QXK priority-ceiling mutex QP::QXMutex More...
 
void unlock (void) noexcept
 unlock the QXK priority-ceiling mutex QP::QXMutex More...
 

Private Attributes

QPSet m_waitSet
 set of extended-threads waiting on this mutex More...
 
std::uint8_t volatile m_lockNest
 lock-nesting up-down counter More...
 
std::uint8_t volatile m_holderPrio
 prio of the lock holder thread More...
 
std::uint8_t m_ceiling
 prioirty ceiling of this mutex More...
 

Detailed Description

Priority Ceiling Mutex the QXK preemptive kernel.

Description
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 QP::QXMutex::init()). In that case, QP::QXMutex requires its own uinque QP priority level, which cannot be used by any thread or any other QP::QXMutex. If initialzied with zero ceiling priority, QP::QXMutex does not use the priority ceiling protocol and does not require a unique QP priority (see QP::QXMutex::init()). QP::QXMutex is recursive (reentrant), which means that it can be locked mutiliple times (up to 255 levels) by the same thread without causing deadlock. QP::QXMutex is primarily intended for the extened (blocking) threads, but can also be used by the basic threads through the non-blocking QP::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 QP::QXMutex::lock() and QP::QXMutex::unlock() operations). If no blocking is needed while holding the mutex, the more efficient non-blocking mechanism of selective QXKscheduler locking" should be used instead. @ref QP::QXK::schedLock() "Selective scheduler locking" is available for both @ref QP::QActive "basic threads" and @ref QP::QXThread "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 in your application.
QXMutex l_rndMutex; // mutex to protect the random number generator
void BSP::randomSeed(uint32_t seed) {
l_rndMutex.init(N_PHILO + 1); // <== initialize the mutex
l_rnd = seed;
}
uint32_t BSP::random(void) { // a very cheap pseudo-random-number generator
uint32_t rnd;
l_rndMutex.lock(); // <== lock the shared random seed
// "Super-Duper" Linear Congruential Generator (LCG)
rnd = l_rnd * (3U*7U*11U*13U*23U);
l_rnd = rnd; // set for the next time
l_rndMutex.unlock(); // <== unlock the shared random seed
return rnd;
}
unsigned long int uint32_t
exact-width 32-bit unsigned int
Definition: 16bit/stdint.h:31

Definition at line 210 of file qxthread.hpp.

Member Function Documentation

◆ init()

void init ( std::uint_fast8_t const  ceiling)
noexcept

initialize the QXK priority-ceiling mutex QP::QXMutex

Description
Initialize the QXK priority ceiling mutex.
Parameters
[in]ceilingthe ceiling-priotity of this mutex or zero.
Note
ceiling == 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 thread.
ceiling > 0 means that the priority-ceiling protocol shall be used by this mutex. Such mutex will boost the priority of the holding thread to the ceiling level for as long as the thread holds this mutex.
Attention
When the priority-ceiling protocol is used (ceiling > 0), the ceiling priority must be unused by any other thread or mutex. Also, the ceiling priority must be higher than priority of any thread that uses this mutex.
Usage
QXMutex l_rndMutex; // mutex to protect the random number generator
void BSP::randomSeed(uint32_t seed) {
l_rndMutex.init(N_PHILO + 1); // <== initialize the mutex
l_rnd = seed;
}
uint32_t BSP::random(void) { // a very cheap pseudo-random-number generator
uint32_t rnd;
l_rndMutex.lock(); // <== lock the shared random seed
// "Super-Duper" Linear Congruential Generator (LCG)
rnd = l_rnd * (3U*7U*11U*13U*23U);
l_rnd = rnd; // set for the next time
l_rndMutex.unlock(); // <== unlock the shared random seed
return rnd;
}
Precondition
the celiling priority of the mutex must:
  • cannot exceed the maximum QF_MAX_ACTIVE;
  • the ceiling priority of the mutex must not be already in use; (QF requires priority to be unique).

Definition at line 84 of file qxk_mutex.cpp.

◆ lock()

bool lock ( std::uint_fast16_t const  nTicks = QXTHREAD_NO_TIMEOUT)
noexcept

lock the QXK priority-ceiling mutex QP::QXMutex

Description
Lock the QXK priority ceiling mutex QP::QXMutex.
Parameters
[in]nTicksnumber of clock ticks (at the associated rate) to wait for the semaphore. The value of QXTHREAD_NO_TIMEOUT indicates that no timeout will occur and the semaphore will wait indefinitely.
Returns
'true' if the mutex has been acquired and 'false' if a timeout occured.
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 ballanced by the matching call to QXMutex::unlock().
Usage
QXMutex l_rndMutex; // mutex to protect the random number generator
void BSP::randomSeed(uint32_t seed) {
l_rndMutex.init(N_PHILO + 1); // <== initialize the mutex
l_rnd = seed;
}
uint32_t BSP::random(void) { // a very cheap pseudo-random-number generator
uint32_t rnd;
l_rndMutex.lock(); // <== lock the shared random seed
// "Super-Duper" Linear Congruential Generator (LCG)
rnd = l_rnd * (3U*7U*11U*13U*23U);
l_rnd = rnd; // set for the next time
l_rndMutex.unlock(); // <== unlock the shared random seed
return rnd;
}
Precondition
this function must:
  • NOT be called from an ISR;
  • be called from an extended thread;
  • the ceiling priority must not be used; or if used
    • the thread priority must be below the ceiling of the mutex;
  • the ceiling must be in range
  • the thread must NOT be already blocked on any object.
also: the thread must NOT be holding a scheduler lock.

Definition at line 129 of file qxk_mutex.cpp.

◆ tryLock()

bool tryLock ( void  )
noexcept

try to lock the QXK priority-ceiling mutex QP::QXMutex

Description
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 ballanced by the matching call to QXMutex::unlock().
Precondition
this function must:
  • NOT be called from an ISR;
  • the calling thread must be valid;
  • the ceiling must be not used; or
    • the thread priority must be below the ceiling of the mutex;
  • the ceiling must be in range
also: the thread must NOT be holding a scheduler lock.

Definition at line 257 of file qxk_mutex.cpp.

◆ unlock()

void unlock ( void  )
noexcept

unlock the QXK priority-ceiling mutex QP::QXMutex

Description
Unlock the QXK priority ceiling mutex.
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 call to QXMutex::lock() or a successfull call to QXMutex::tryLock() must be ballanced by the matching call to QXMutex::unlock().
Usage
QXMutex l_rndMutex; // mutex to protect the random number generator
void BSP::randomSeed(uint32_t seed) {
l_rndMutex.init(N_PHILO + 1); // <== initialize the mutex
l_rnd = seed;
}
uint32_t BSP::random(void) { // a very cheap pseudo-random-number generator
uint32_t rnd;
l_rndMutex.lock(); // <== lock the shared random seed
// "Super-Duper" Linear Congruential Generator (LCG)
rnd = l_rnd * (3U*7U*11U*13U*23U);
l_rnd = rnd; // set for the next time
l_rndMutex.unlock(); // <== unlock the shared random seed
return rnd;
}
Precondition
this function must:
  • NOT be called from an ISR;
  • the calling thread must be valid;
  • the ceiling must not be used or
    • the current thread must have priority equal to the mutex ceiling;
  • the ceiling must be in range
also: the mutex must be already locked at least once.
also: the mutex must be held by this thread.

Definition at line 345 of file qxk_mutex.cpp.

Field Documentation

◆ m_waitSet

QPSet m_waitSet
private

set of extended-threads waiting on this mutex

Definition at line 225 of file qxthread.hpp.

◆ m_lockNest

std::uint8_t volatile m_lockNest
private

lock-nesting up-down counter

Definition at line 226 of file qxthread.hpp.

◆ m_holderPrio

std::uint8_t volatile m_holderPrio
private

prio of the lock holder thread

Definition at line 227 of file qxthread.hpp.

◆ m_ceiling

std::uint8_t m_ceiling
private

prioirty ceiling of this mutex

Definition at line 228 of file qxthread.hpp.


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