Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
qequeue.h
00001 ////////////////////////////////////////////////////////////////////////////// 00002 // Product: QF/C++, platform-independent event queue interface. 00003 // Last Updated for Version: 4.0.00 00004 // Date of the Last Update: Apr 06, 2008 00005 // 00006 // Q u a n t u m L e a P s 00007 // --------------------------- 00008 // innovating embedded systems 00009 // 00010 // Copyright (C) 2002-2008 Quantum Leaps, LLC. All rights reserved. 00011 // 00012 // This software may be distributed and modified under the terms of the GNU 00013 // General Public License version 2 (GPL) as published by the Free Software 00014 // Foundation and appearing in the file GPL.TXT included in the packaging of 00015 // this file. Please note that GPL Section 2[b] requires that all works based 00016 // on this software must also be made publicly available under the terms of 00017 // the GPL ("Copyleft"). 00018 // 00019 // Alternatively, this software may be distributed and modified under the 00020 // terms of Quantum Leaps commercial licenses, which expressly supersede 00021 // the GPL and are specifically designed for licensees interested in 00022 // retaining the proprietary status of their code. 00023 // 00024 // Contact information: 00025 // Quantum Leaps Web site: http://www.quantum-leaps.com 00026 // e-mail: info@quantum-leaps.com 00027 ////////////////////////////////////////////////////////////////////////////// 00028 #ifndef qequeue_h 00029 #define qequeue_h 00030 00031 /// \file 00032 /// \ingroup qep qf qk qs 00033 /// \brief platform-independent event queue interface. 00034 /// 00035 /// This header file must be included in all QF ports that use native QF 00036 /// event queue implementation. Also, this file is needed when the "raw" 00037 /// thread-safe queues are used for communication between active objects 00038 /// and non-framework entities, such as ISRs, device drivers, or legacy 00039 /// code. 00040 00041 #ifndef QF_EQUEUE_CTR_SIZE 00042 00043 /// \brief The size (in bytes) of the ring-buffer counters used in the 00044 /// native QF event queue implementation. Valid values: 1, 2, or 4; 00045 /// default 1. 00046 /// 00047 /// This macro can be defined in the QF port file (qf_port.h) to 00048 /// configure the ::QEQueueCtr type. Here the macro is not defined so the 00049 /// default of 1 byte is chosen. 00050 #define QF_EQUEUE_CTR_SIZE 1 00051 #endif 00052 #if (QF_EQUEUE_CTR_SIZE == 1) 00053 00054 /// \brief The data type to store the ring-buffer counters based on 00055 /// the macro #QF_EQUEUE_CTR_SIZE. 00056 /// 00057 /// The dynamic range of this data type determines the maximum length 00058 /// of the ring buffer managed by the native QF event queue. 00059 typedef uint8_t QEQueueCtr; 00060 #elif (QF_EQUEUE_CTR_SIZE == 2) 00061 typedef uint16_t QEQueueCtr; 00062 #elif (QF_EQUEUE_CTR_SIZE == 4) 00063 typedef uint32_t QEQueueCtr; 00064 #else 00065 #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1, 2, or 4" 00066 #endif 00067 00068 00069 ////////////////////////////////////////////////////////////////////////////// 00070 /// \brief Native QF Event Queue class 00071 /// 00072 /// This structure describes the native QF event queue, which can be used as 00073 /// the event queue for active objects, or as a simple "raw" event queue for 00074 /// thread-safe event passing among non-framework entities, such as ISRs, 00075 /// device drivers, or other third-party components. 00076 /// 00077 /// The native QF event queue is configured by defining the macro 00078 /// #QF_EQUEUE_TYPE as ::QEQueue in the specific QF port header file. 00079 /// 00080 /// The ::QEQueue structure contains only data members for managing an event 00081 /// queue, but does not contain the storage for the queue buffer, which must 00082 /// be provided externally during the queue initialization. 00083 /// 00084 /// The event queue can store only event pointers, not the whole events. The 00085 /// internal implementation uses the standard ring-buffer plus one external 00086 /// location that optimizes the queue operation for the most frequent case 00087 /// of empty queue. 00088 /// 00089 /// The ::QEQueue structure is used with two sets of functions. One set is for 00090 /// the active object event queue, which needs to block the active object 00091 /// task when the event queue is empty and unblock it when events are posted 00092 /// to the queue. The interface for the native active object event queue 00093 /// consists of the following functions: QActive::postFIFO_(), 00094 /// QActive::postLIFO_(), and QActive::get_(). Additionally the function 00095 /// QEQueue_init() is used to initialize the queue. 00096 /// 00097 /// The other set of functions, uses this structure as a simple "raw" event 00098 /// queue to pass events between entities other than active objects, such as 00099 /// ISRs. The "raw" event queue is not capable of blocking on the get() 00100 /// operation, but is still thread-safe because it uses QF critical section 00101 /// to protect its integrity. The interface for the "raw" thread-safe queue 00102 /// consists of the following functions: QEQueue::postFIFO(), 00103 /// QEQueue::postLIFO(), and QEQueue::get(). Additionally the function 00104 /// QEQueue::init() is used to initialize the queue. 00105 /// 00106 /// \note Most event queue operations (both the active object queues and 00107 /// the "raw" queues) internally use the QF critical section. You should be 00108 /// careful not to invoke those operations from other critical sections when 00109 /// nesting of critical sections is not supported. 00110 class QEQueue { 00111 private: 00112 00113 /// \brief pointer to event at the front of the queue 00114 /// 00115 /// All incoming and outgoing events pass through the m_frontEvt location. 00116 /// When the queue is empty (which is most of the time), the extra 00117 /// m_frontEvt location allows to bypass the ring buffer altogether, 00118 /// greatly optimizing the performance of the queue. Only bursts of events 00119 /// engage the ring buffer. 00120 /// 00121 /// The additional role of this attribute is to indicate the empty status 00122 /// of the queue. The queue is empty if the m_frontEvt location is NULL. 00123 QEvent const *m_frontEvt; 00124 00125 /// \brief pointer to the start of the ring buffer 00126 QEvent const **m_ring; 00127 00128 /// \brief offset of the end of the ring buffer from the start of the 00129 /// buffer m_ring 00130 QEQueueCtr m_end; 00131 00132 /// \brief offset to where next event will be inserted into the buffer 00133 QEQueueCtr m_head; 00134 00135 /// \brief offset of where next event will be extracted from the buffer 00136 QEQueueCtr m_tail; 00137 00138 /// \brief number of free events in the ring buffer 00139 QEQueueCtr m_nFree; 00140 00141 /// \brief minimum number of free events ever in the ring buffer. 00142 /// 00143 /// \note this attribute remembers the low-watermark of the ring buffer, 00144 /// which provides a valuable information for sizing event queues. 00145 /// \sa QF::getQueueMargin(). 00146 QEQueueCtr m_nMin; 00147 00148 public: 00149 00150 /// \brief Initializes the native QF event queue 00151 /// 00152 /// The parameters are as follows: \a qSto[] is the ring buffer storage, 00153 /// \a qLen is the length of the ring buffer in the units of event- 00154 /// pointers. 00155 /// 00156 /// \note The actual capacity of the queue is qLen + 1, because of the 00157 /// extra location fornEvt_. 00158 void init(QEvent const *qSto[], QEQueueCtr qLen); 00159 00160 /// \brief "raw" thread-safe QF event queue implementation for the 00161 /// First-In-First-Out (FIFO) event posting. You can call this function 00162 /// from any task context or ISR context. Please note that this function 00163 /// uses internally a critical section. 00164 /// 00165 /// \note The function raises an assertion if the native QF queue becomes 00166 /// full and cannot accept the event. 00167 /// 00168 /// \sa QEQueue::postLIFO(), QEQueue::get() 00169 void postFIFO(QEvent const *e); 00170 00171 /// \brief "raw" thread-safe QF event queue implementation for the 00172 /// First-In-First-Out (FIFO) event posting. You can call this function 00173 /// from any task context or ISR context. Please note that this function 00174 /// uses internally a critical section. 00175 /// 00176 /// \note The function raises an assertion if the native QF queue becomes 00177 /// full and cannot accept the event. 00178 /// 00179 /// \sa QEQueue::postLIFO(), QEQueue::get() 00180 void postLIFO(QEvent const *e); 00181 00182 /// \brief "raw" thread-safe QF event queue implementation for the 00183 /// Last-In-First-Out (LIFO) event posting. 00184 /// 00185 /// \note The LIFO policy should be used only with great caution because 00186 /// it alters order of events in the queue. 00187 /// \note The function raises an assertion if the native QF queue becomes 00188 /// full and cannot accept the event. You can call this function from 00189 /// any task context or ISR context. Please note that this function uses 00190 /// internally a critical section. 00191 /// 00192 /// \sa QEQueue::postFIFO(), QEQueue::get() 00193 QEvent const *get(void); 00194 00195 /// \brief "raw" thread-safe QF event queue operation for 00196 /// obtaining the number of free entries still available in the queue. 00197 /// 00198 /// \note This operation needs to be used with caution because the 00199 /// number of free entries can change unexpectedly. The main intent for 00200 /// using this operation is in conjunction with event deferral. In this 00201 /// case the queue is accessed only from a single thread (by a single AO), 00202 /// so the number of free entries cannot change unexpectedly. 00203 /// 00204 /// \sa QActive::defer(), QActive::recall() 00205 QEQueueCtr getNFree(void) const { 00206 return m_nFree; 00207 } 00208 00209 private: 00210 friend class QF; 00211 friend class QActive; 00212 }; 00213 00214 #endif // qequeue_h 00215
Generated on Tue Jul 12 2022 20:22:36 by
1.7.2