QP/C++  8.0.0
Real-Time Embedded Framework
Loading...
Searching...
No Matches
QP::QEQueue Class Reference

Native QP event queue. More...

#include "qequeue.hpp"

Public Member Functions

 QEQueue () noexcept
 
void init (QEvt const *qSto[], std::uint_fast16_t const qLen) noexcept
 
bool post (QEvt const *const e, std::uint_fast16_t const margin, std::uint_fast8_t const qsId) noexcept
 
void postLIFO (QEvt const *const e, std::uint_fast8_t const qsId) noexcept
 
QEvt const * get (std::uint_fast8_t const qsId) noexcept
 
QEQueueCtr getNFree () const noexcept
 
QEQueueCtr getNMin () const noexcept
 
bool isEmpty () const noexcept
 

Private Member Functions

 QEQueue (QEQueue const &other)=delete
 
QEQueueoperator= (QEQueue const &other)=delete
 

Private Attributes

QEvt const *volatile m_frontEvt
 
QEvt const ** m_ring
 
QEQueueCtr m_end
 
QEQueueCtr volatile m_head
 
QEQueueCtr volatile m_tail
 
QEQueueCtr volatile m_nFree
 
std::uintptr_t m_frontEvt_dis
 
QEQueueCtr m_head_dis
 
QEQueueCtr m_tail_dis
 
QEQueueCtr m_nFree_dis
 
QEQueueCtr m_nMin
 

Friends

class QActive
 
class QTicker
 
class QXMutex
 
class QXThread
 

Detailed Description

Native QP event queue.

This class describes the native QP event queue, which can be used as the event queue for active objects, or as a simple "raw" event queue for thread-safe event passing among non-framework entities, such as ISRs, device drivers, or other third-party components.

The native QF event queue is configured by defining the macro QACTIVE_EQUEUE_TYPE as QP::QEQueue in the specific QF port header file.

The QP::QEQueue structure contains only data members for managing an event queue, but does not contain the storage for the queue buffer, which must be provided externally during the queue initialization.

The event queue can store only event pointers, not the whole events. The internal implementation uses the standard ring-buffer plus one external location that optimizes the queue operation for the most frequent case of empty queue.

The QP::QEQueue structure is used with two sets of functions. One set is for the active object event queue, which might need to block the active object task when the event queue is empty and might need to unblock it when events are posted to the queue. The interface for the native active object event queue consists of the following functions: QActive_post(), QActive_postLIFO(), and QActive_get_(). Additionally the function QEQueue_init() is used to initialize the queue.

The other set of functions, uses QP::QEQueue as a simple "raw" event queue to pass events between entities other than active objects, such as ISRs. The "raw" event queue is not capable of blocking on the get() operation, but is still thread-safe because it uses QF critical section to protect its integrity. The interface for the "raw" thread-safe queue consists of the following functions: QEQueue_post(), QEQueue_postLIFO(), and QEQueue_get(). Additionally the function QEQueue_init() is used to initialize the queue.

Most event queue operations (both the active object queues and the "raw" queues) internally use the QF critical section. You should be careful not to invoke those operations from other critical sections when nesting of critical sections is not supported.

Definition at line 60 of file qequeue.hpp.

Constructor & Destructor Documentation

◆ QEQueue() [1/2]

QP::QEQueue::QEQueue ( )
inlinenoexcept

Default constructor of QP::QEQueue

Definition at line 93 of file qequeue.hpp.

◆ QEQueue() [2/2]

QP::QEQueue::QEQueue ( QEQueue const & other)
privatedelete

Member Function Documentation

◆ init()

void QP::QEQueue::init ( QEvt const * qSto[],
std::uint_fast16_t const qLen )
noexcept

Initialize the native QF event queue.

Initialize the event queue by giving it the storage for the ring buffer.

Parameters
[in]qStoan array of pointers to QP::QEvt to sereve as the ring buffer for the event queue
[in]qLenthe length of the qSto buffer (in QP::QEvt pointers)
Note
The actual capacity of the queue is qLen + 1, because of the extra location m_forntEvt.
This function is also used to initialize the event queues of active objects in the built-int QV and QK kernels, as well as other QP ports to OSes/RTOSes that do provide a suitable message queue.

Definition at line 63 of file qf_qeq.cpp.

◆ post()

bool QP::QEQueue::post ( QEvt const *const e,
std::uint_fast16_t const margin,
std::uint_fast8_t const qsId )
noexcept

Post an event to the "raw" thread-safe event queue (FIFO).

Post an event to the "raw" thread-safe event queue using the First-In-First-Out (FIFO) order.

Parameters
[in]epointer to the event to be posted to the queue
[in]marginnumber of required free slots in the queue after posting the event. The special value QF_NO_MARGIN means that this function will assert if posting
[in]qsIdQS-id of this state machine (for QS local filter)
Returns
'true' (success) when the posting succeeded with the provided margin and 'false' (failure) when the posting fails.
Precondition qf_qeq:200
  • event must be valid
Note
The QF_NO_MARGIN value of the margin parameter is special and denotes situation when the post() operation is assumed to succeed (event delivery guarantee). An assertion fires, when the event cannot be delivered in this case.
This function can be called from any task context or ISR context.

Definition at line 97 of file qf_qeq.cpp.

◆ postLIFO()

void QP::QEQueue::postLIFO ( QEvt const *const e,
std::uint_fast8_t const qsId )
noexcept

Post an event to the "raw" thread-safe event queue (LIFO).

Post an event to the "raw" thread-safe event queue using the Last-In-First-Out (LIFO) order.

Parameters
[in]epointer to the event to be posted to the queue
[in]qsIdQS-id of this state machine (for QS local filter)
Precondition qf_qeq:300
  • the queue must be able to accept the event (cannot overflow)
Attention
The LIFO policy should be used only with great caution, because it alters the order of events in the queue.
Note
This function can be called from any task context or ISR context.
this function is used for the "raw" thread-safe queues and not for the queues of active objects.

Definition at line 206 of file qf_qeq.cpp.

◆ get()

QEvt const * QP::QEQueue::get ( std::uint_fast8_t const qsId)
noexcept

Obtain an event from the "raw" thread-safe queue.

Retrieves an event from the front of the "raw" thread-safe queue and returns a pointer to this event to the caller.

Parameters
[in]qsIdQS-id of this state machine (for QS local filter)
Returns
pointer to event at the front of the queue, if the queue is not empty and NULL if the queue is empty.
Note
This function is used for the "raw" thread-safe queues and not for the queues of active objects.

Definition at line 288 of file qf_qeq.cpp.

◆ getNFree()

QEQueueCtr QP::QEQueue::getNFree ( ) const
inlinenoexcept

Obtain the number of free entries still available in the queue.

This operation needs to be used with caution because the number of free entries can change unexpectedly. The main intent for using this operation is in conjunction with event deferral. In this case the queue is accessed only from a single thread (by a single AO), so the number of free entries cannot change unexpectedly.

Returns
the current number of free slots in the queue.

Definition at line 119 of file qequeue.hpp.

◆ getNMin()

QEQueueCtr QP::QEQueue::getNMin ( ) const
inlinenoexcept

Obtain the minimum number of free entries ever in the queue (a.k.a. "low-watermark").

This operation needs to be used with caution because the "low-watermark" can change unexpectedly. The main intent for using this operation is to get an idea of queue usage to size the queue adequately.

Returns
the minimum number of free entries ever in the queue since QP::QEQueue::init().

Definition at line 122 of file qequeue.hpp.

◆ isEmpty()

bool QP::QEQueue::isEmpty ( ) const
inlinenoexcept

Find out if the queue is empty.

This operation needs to be used with caution because the queue status can change unexpectedly. The main intent for using this operation is in conjunction with event deferral. In this case the queue is accessed only from a single thread (by a single AO), so no other entity can post events to the queue.

Returns
'true' if the queue is current empty and 'false' otherwise.

Definition at line 129 of file qequeue.hpp.

◆ operator=()

QEQueue & QP::QEQueue::operator= ( QEQueue const & other)
privatedelete

Friends And Related Symbol Documentation

◆ QActive

friend class QActive
friend

Definition at line 87 of file qequeue.hpp.

◆ QTicker

friend class QTicker
friend

Definition at line 88 of file qequeue.hpp.

◆ QXMutex

friend class QXMutex
friend

Definition at line 89 of file qequeue.hpp.

◆ QXThread

friend class QXThread
friend

Definition at line 90 of file qequeue.hpp.

Member Data Documentation

◆ m_frontEvt

QEvt const* volatile QP::QEQueue::m_frontEvt
private

Pointer to event at the front of the queue.

All incoming and outgoing events pass through the frontEvt location. When the queue is empty (which is most of the time), the extra frontEvt location allows to bypass the ring buffer altogether, greatly optimizing the performance of the queue. Only bursts of events engage the ring buffer.

The additional role of this attribute is to indicate the empty status of the queue. The queue is empty when frontEvt is NULL.

Definition at line 62 of file qequeue.hpp.

◆ m_ring

QEvt const* * QP::QEQueue::m_ring
private

Pointer to the start of the ring buffer

Definition at line 63 of file qequeue.hpp.

◆ m_end

QEQueueCtr QP::QEQueue::m_end
private

Offset of the end of the ring buffer from the start of the buffer

Definition at line 64 of file qequeue.hpp.

◆ m_head

QEQueueCtr volatile QP::QEQueue::m_head
private

Offset to where next event will be inserted into the buffer

Definition at line 65 of file qequeue.hpp.

◆ m_tail

QEQueueCtr volatile QP::QEQueue::m_tail
private

Offset of where next event will be extracted from the buffer

Definition at line 66 of file qequeue.hpp.

◆ m_nFree

QEQueueCtr volatile QP::QEQueue::m_nFree
private

Number of free events in the ring buffer

Definition at line 67 of file qequeue.hpp.

◆ m_frontEvt_dis

std::uintptr_t QP::QEQueue::m_frontEvt_dis
private

Definition at line 70 of file qequeue.hpp.

◆ m_head_dis

QEQueueCtr QP::QEQueue::m_head_dis
private

Definition at line 74 of file qequeue.hpp.

◆ m_tail_dis

QEQueueCtr QP::QEQueue::m_tail_dis
private

Definition at line 78 of file qequeue.hpp.

◆ m_nFree_dis

QEQueueCtr QP::QEQueue::m_nFree_dis
private

Definition at line 82 of file qequeue.hpp.

◆ m_nMin

QEQueueCtr QP::QEQueue::m_nMin
private

Minimum number of free events ever in the ring buffer.

This attribute remembers the low-watermark of the ring buffer, which provides a valuable information for sizing event queues.

Definition at line 84 of file qequeue.hpp.


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