QP/C  5.9.5
qequeue.h File Reference

QP natvie, platform-independent, thread-safe event queue interface. More...

Go to the source code of this file.

Data Structures

struct  QEQueue
 Native QF Event Queue. More...
 

Macros

#define QF_EQUEUE_CTR_SIZE   1
 The size (in bytes) of the ring-buffer counters used in the native QF event queue implementation. More...
 
#define QEQueue_getNFree(me_)   ((me_)->nFree)
 "raw" thread-safe QF event queue operation for obtaining the number of free entries still available in the queue. More...
 
#define QEQueue_getNMin(me_)   ((me_)->nMin)
 "raw" thread-safe QF event queue operation for obtaining the minimum number of free entries ever in the queue (a.k.a. More...
 
#define QEQueue_isEmpty(me_)   ((me_)->frontEvt == (QEvt const *)0)
 "raw" thread-safe QF event queue operation to find out if the queue is empty. More...
 

Typedefs

typedef uint_fast8_t QEQueueCtr
 The data type to store the ring-buffer counters based on the macro QF_EQUEUE_CTR_SIZE. More...
 

Functions

void QEQueue_init (QEQueue *const me, QEvt const *qSto[], uint_fast16_t const qLen)
 Initialize the native QF event queue. More...
 
bool QEQueue_post (QEQueue *const me, QEvt const *const e, uint_fast16_t const margin)
 Post an event to the "raw" thread-safe event queue (FIFO). More...
 
void QEQueue_postLIFO (QEQueue *const me, QEvt const *const e)
 Post an event to the "raw" thread-safe event queue (LIFO). More...
 
QEvt const * QEQueue_get (QEQueue *const me)
 Obtain an event from the "raw" thread-safe queue. More...
 

Detailed Description

QP natvie, platform-independent, thread-safe event queue interface.

Definition in file qequeue.h.


Data Structure Documentation

◆ QEQueue

struct QEQueue

Native QF Event Queue.

Description
This class describes the native QF 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 QF_EQUEUE_TYPE as QEQueue in the specific QF port header file.

The 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 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 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.
Note
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.
See also
QEQueue for the description of the data members

Definition at line 130 of file qequeue.h.

Data Fields
QEQueueCtr end offset of the end of the ring buffer from the start of the buffer.
QEvt const *volatile frontEvt pointer to event at the front of the queue.
Description
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.
Note
The additional role of this attribute is to indicate the empty status of the queue. The queue is empty when frontEvt is NULL.
QEQueueCtr volatile head offset to where next event will be inserted into the buffer.
QEQueueCtr volatile nFree number of free events in the ring buffer.
QEQueueCtr nMin minimum number of free events ever in the ring buffer.
Description
this attribute remembers the low-watermark of the ring buffer, which provides a valuable information for sizing event queues.
See also
QF_getQueueMargin().
QEvt const ** ring pointer to the start of the ring buffer.
QEQueueCtr volatile tail offset of where next event will be extracted from the buffer.

Macro Definition Documentation

◆ QEQueue_getNFree

#define QEQueue_getNFree (   me_)    ((me_)->nFree)

"raw" thread-safe QF event queue operation for obtaining the number of free entries still available in the queue.

Description
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.
Parameters
[in]me_pointer (see Object Orientation)
Returns
the current number of free slots in the queue.

Definition at line 200 of file qequeue.h.

◆ QEQueue_getNMin

#define QEQueue_getNMin (   me_)    ((me_)->nMin)

"raw" thread-safe QF event queue operation for obtaining the minimum number of free entries ever in the queue (a.k.a.

"low-watermark").

Description
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.
Parameters
[in]me_pointer (see Object Orientation)
Returns
the minimum number of free entries ever in the queue since init.

Definition at line 214 of file qequeue.h.

◆ QEQueue_isEmpty

#define QEQueue_isEmpty (   me_)    ((me_)->frontEvt == (QEvt const *)0)

"raw" thread-safe QF event queue operation to find out if the queue is empty.

Description
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.
Parameters
[in]me_pointer (see Object Orientation)
Returns
'true' if the queue is current empty and 'false' otherwise.

Definition at line 230 of file qequeue.h.

◆ QF_EQUEUE_CTR_SIZE

#define QF_EQUEUE_CTR_SIZE   1

The size (in bytes) of the ring-buffer counters used in the native QF event queue implementation.

Description
This header file must be included in all QF ports that use native QF event queue for active objects. Also, this file needs to be included in the QP/C library when the application uses QActive_defer()/ QActive_recall(). Finally, this file is also needed when the "raw" thread-safe queues are used for communication between active objects and non-framework entities, such as ISRs, device drivers, or legacy code.

Valid values: 1, 2, or 4; default 1.

Description
This macro can be defined in the QF port file (qf_port.h) to configure the QEQueueCtr type. Here the macro is not defined so the default of 1 byte is chosen.

Definition at line 65 of file qequeue.h.

Typedef Documentation

◆ QEQueueCtr

The data type to store the ring-buffer counters based on the macro QF_EQUEUE_CTR_SIZE.

Description
The dynamic range of this data type determines the maximum length of the ring buffer managed by the native QF event queue.

Definition at line 76 of file qequeue.h.

Function Documentation

◆ QEQueue_get()

QEvt const* QEQueue_get ( QEQueue *const  me)

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

Description
Retrieves an event from the front of the "raw" thread-safe queue and returns a pointer to this event to the caller.
Parameters
[in,out]mepointer (see Object Orientation)
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.
See also
QEQueue_post(), QEQueue_postLIFO(), QActive_recall()

Definition at line 276 of file qf_qeq.c.

◆ QEQueue_init()

void QEQueue_init ( QEQueue *const  me,
QEvt const *  qSto[],
uint_fast16_t const  qLen 
)

Initialize the native QF event queue.

Description
Initialize the event queue by giving it the storage for the ring buffer.
Parameters
[in,out]mepointer (see Object Orientation)
[in]qStoan array of pointers to QEvt to sereve as the ring buffer for the event queue
[in]qLenthe length of the qSto[] buffer (in QEvt pointers)
Note
The actual capacity of the queue is qLen + 1, because of the extra location 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 70 of file qf_qeq.c.

◆ QEQueue_post()

bool QEQueue_post ( QEQueue *const  me,
QEvt const *const  e,
uint_fast16_t const  margin 
)

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

Note
this function is used for the "raw" thread-safe queues and NOT for the queues of active objects.
Description
Post an event to the "raw" thread-safe event queue using the First-In-First-Out (FIFO) order.
Parameters
[in,out]mepointer (see Object Orientation)
[in]epointer to the event to be posted to the queue
[in]marginnumber of unused slots in the queue that must be still available after posting the event
Note
The zero value of the margin parameter is special and denotes situation when event posting is assumed to succeed (event delivery guarantee). An assertion fires, when the event cannot be delivered in this case.
Returns
'true' (success) when the posting succeeded with the provided margin and 'false' (failure) when the posting fails.
Note
This function can be called from any task context or ISR context.
See also
QEQueue_postLIFO(), QEQueue_get()
Note
If the margin is zero, assert that the queue can accept the event. This is to support the "guaranteed event delivery" policy for most events posted within the framework.

Definition at line 118 of file qf_qeq.c.

◆ QEQueue_postLIFO()

void QEQueue_postLIFO ( QEQueue *const  me,
QEvt const *const  e 
)

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

Description
Post an event to the "raw" thread-safe event queue using the Last-In-First-Out (LIFO) order.
Parameters
[in,out]mepointer (see Object Orientation)
[in]epointer to the event to be posted to the queue
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.
See also
QEQueue_post(), QEQueue_get(), QActive_defer()
Precondition
the queue must be able to accept the event (cannot overflow)

Definition at line 215 of file qf_qeq.c.