| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- /*$file${include::qequeue.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
- /*
- * Model: qpc.qm
- * File: ${include::qequeue.h}
- *
- * This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
- * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
- *
- * This code is covered by the following QP license:
- * License # : LicenseRef-QL-dual
- * Issued to : Any user of the QP/C real-time embedded framework
- * Framework(s) : qpc
- * Support ends : 2023-12-31
- * License scope:
- *
- * Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
- *
- * This software is dual-licensed under the terms of the open source GNU
- * General Public License version 3 (or any later version), or alternatively,
- * under the terms of one of the closed source Quantum Leaps commercial
- * licenses.
- *
- * The terms of the open source GNU General Public License version 3
- * can be found at: <www.gnu.org/licenses/gpl-3.0>
- *
- * The terms of the closed source Quantum Leaps commercial licenses
- * can be found at: <www.state-machine.com/licensing>
- *
- * Redistributions in source code must retain this top-level comment block.
- * Plagiarizing this software to sidestep the license obligations is illegal.
- *
- * Contact information:
- * <www.state-machine.com/licensing>
- * <info@state-machine.com>
- */
- /*$endhead${include::qequeue.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
- /*! @file
- * @brief QP natvie, platform-independent, thread-safe event queue interface
- * @details
- * 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.
- */
- #ifndef QEQUEUE_H_
- #define QEQUEUE_H_
- #ifndef QF_EQUEUE_CTR_SIZE
- /*! The size [bytes] of the ring-buffer counters used in the
- * native QF event queue implementation. Valid values: 1U, 2U, or 4U;
- * default 1U.
- * @details
- * 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.
- */
- #define QF_EQUEUE_CTR_SIZE 1U
- #endif
- #if (QF_EQUEUE_CTR_SIZE == 1U)
- /*! The data type to store the ring-buffer counters based on
- * the macro #QF_EQUEUE_CTR_SIZE.
- * @details
- * The dynamic range of this data type determines the maximum length
- * of the ring buffer managed by the native QF event queue.
- */
- typedef uint8_t QEQueueCtr;
- #elif (QF_EQUEUE_CTR_SIZE == 2U)
- typedef uint16_t QEQueueCtr;
- #elif (QF_EQUEUE_CTR_SIZE == 4U)
- typedef uint32_t QEQueueCtr;
- #else
- #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U"
- #endif
- /*==========================================================================*/
- /*$declare${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
- /*${QF::QEQueue} ...........................................................*/
- /*! @brief Native QF Event Queue
- * @class QEQueue
- *
- * @details
- * 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.<br>
- *
- * The native QF event queue is configured by defining the macro
- * #QF_EQUEUE_TYPE as ::QEQueue in the specific QF port header file.<br>
- * <br>
- * 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.<br>
- * <br>
- * 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.<br>
- * <br>
- * 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.<br>
- * <br>
- * 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.
- *
- * <br>ote 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.
- *
- * @sa ::QEQueue for the description of the data members
- */
- typedef struct {
- /* private: */
- /*! pointer to event at the front of the queue.
- * @private @memberof QEQueue
- *
- * @details
- * 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.
- *
- * <br>ote The additional role of this attribute is to indicate the empty
- * status of the queue. The queue is empty when frontEvt is NULL.
- */
- QEvt const * volatile frontEvt;
- /*! pointer to the start of the ring buffer
- * @private @memberof QEQueue
- */
- QEvt const ** ring;
- /*! offset of the end of the ring buffer from the start of the buffer
- * @private @memberof QEQueue
- */
- QEQueueCtr end;
- /*! offset to where next event will be inserted into the buffer
- * @private @memberof QEQueue
- */
- QEQueueCtr volatile head;
- /*! offset of where next event will be extracted from the buffer
- * @private @memberof QEQueue
- */
- QEQueueCtr volatile tail;
- /*! number of free events in the ring buffer
- * @private @memberof QEQueue
- */
- QEQueueCtr volatile nFree;
- /*! Minimum number of free events ever in the ring buffer.
- * @private @memberof QEQueue
- *
- * @details
- * This attribute remembers the low-watermark of the ring buffer,
- * which provides a valuable information for sizing event queues.
- * @sa QF_getQueueMargin().
- */
- QEQueueCtr nMin;
- } QEQueue;
- /* public: */
- /*! Initialize the native QF event queue.
- * @public @memberof QEQueue
- *
- * @details
- * Initialize the event queue by giving it the storage for the ring buffer.
- *
- * @param[in,out] me current instance pointer (see @ref oop)
- * @param[in] qSto an array of pointers to ::QEvt to sereve as the
- * ring buffer for the event queue
- * @param[in] qLen the length of the `qSto` buffer (in ::QEvt pointers)
- *
- * @note The actual capacity of the queue is qLen + 1, because of the extra
- * location forntEvt.
- *
- * @note
- * 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.
- */
- void QEQueue_init(QEQueue * const me,
- QEvt const ** const qSto,
- uint_fast16_t const qLen);
- /*! Post an event to the "raw" thread-safe event queue (FIFO).
- * @public @memberof QEQueue
- *
- * @details
- * Post an event to the "raw" thread-safe event queue using the
- * First-In-First-Out (FIFO) order.
- *
- * @param[in,out] me current instance pointer (see @ref oop)
- * @param[in] e pointer to the event to be posted to the queue
- * @param[in] margin number 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
- * @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.
- *
- * @note This function can be called from any task context or ISR context.
- *
- * @sa QEQueue_postLIFO(), QEQueue_get()
- */
- bool QEQueue_post(QEQueue * const me,
- QEvt const * const e,
- uint_fast16_t const margin,
- uint_fast8_t const qs_id);
- /*! Post an event to the "raw" thread-safe event queue (LIFO).
- * @public @memberof QEQueue
- *
- * @details
- * Post an event to the "raw" thread-safe event queue using the
- * Last-In-First-Out (LIFO) order.
- *
- * @param[in,out] me current instance pointer (see @ref oop)
- * @param[in] e pointer to the event to be posted to the queue
- *
- * @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.
- *
- * @note
- * this function is used for the "raw" thread-safe queues and __not__
- * for the queues of active objects.
- *
- * @sa
- * QEQueue_post(), QEQueue_get(), QActive_defer()
- */
- void QEQueue_postLIFO(QEQueue * const me,
- QEvt const * const e,
- uint_fast8_t const qs_id);
- /*! Obtain an event from the "raw" thread-safe queue.
- * @public @memberof QEQueue
- *
- * @details
- * Retrieves an event from the front of the "raw" thread-safe queue and
- * returns a pointer to this event to the caller.
- *
- * @param[in,out] me current instance pointer (see @ref oop)
- *
- * @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.
- *
- * @sa
- * QEQueue_post(), QEQueue_postLIFO(), QActive_recall()
- */
- QEvt const * QEQueue_get(QEQueue * const me,
- uint_fast8_t const qs_id);
- /*! "raw" thread-safe QF event queue operation for obtaining the number
- * of free entries still available in the queue.
- * @public @memberof QEQueue
- *
- * @details
- * 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.
- *
- * @param[in] me current instance pointer (see @ref oop)
- *
- * @returns the current number of free slots in the queue.
- */
- static inline QEQueueCtr QEQueue_getNFree(QEQueue const * const me) {
- return me->nFree;
- }
- /*! "raw" thread-safe QF event queue operation for obtaining the minimum
- * number of free entries ever in the queue (a.k.a. "low-watermark").
- * @public @memberof QEQueue
- *
- * @details
- * 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.
- *
- * @param[in] me current instance pointer (see @ref oop)
- *
- * @returns the minimum number of free entries ever in the queue since init.
- */
- static inline QEQueueCtr QEQueue_getNMin(QEQueue const * const me) {
- return me->nMin;
- }
- /*! "raw" thread-safe QF event queue operation to find out if the queue
- * is empty.
- * @public @memberof QEQueue
- *
- * @details
- * 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.
- *
- * @param[in] me_ current instance pointer (see @ref oop)
- *
- * @returns 'true' if the queue is current empty and 'false' otherwise.
- */
- static inline bool QEQueue_isEmpty(QEQueue const * const me) {
- return me->frontEvt == (QEvt *)0;
- }
- /*$enddecl${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
- #endif /* QEQUEUE_H_ */
|