qequeue.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*$file${include::qequeue.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  2. /*
  3. * Model: qpc.qm
  4. * File: ${include::qequeue.h}
  5. *
  6. * This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
  7. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  8. *
  9. * This code is covered by the following QP license:
  10. * License # : LicenseRef-QL-dual
  11. * Issued to : Any user of the QP/C real-time embedded framework
  12. * Framework(s) : qpc
  13. * Support ends : 2023-12-31
  14. * License scope:
  15. *
  16. * Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
  17. *
  18. * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
  19. *
  20. * This software is dual-licensed under the terms of the open source GNU
  21. * General Public License version 3 (or any later version), or alternatively,
  22. * under the terms of one of the closed source Quantum Leaps commercial
  23. * licenses.
  24. *
  25. * The terms of the open source GNU General Public License version 3
  26. * can be found at: <www.gnu.org/licenses/gpl-3.0>
  27. *
  28. * The terms of the closed source Quantum Leaps commercial licenses
  29. * can be found at: <www.state-machine.com/licensing>
  30. *
  31. * Redistributions in source code must retain this top-level comment block.
  32. * Plagiarizing this software to sidestep the license obligations is illegal.
  33. *
  34. * Contact information:
  35. * <www.state-machine.com/licensing>
  36. * <info@state-machine.com>
  37. */
  38. /*$endhead${include::qequeue.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  39. /*! @file
  40. * @brief QP natvie, platform-independent, thread-safe event queue interface
  41. * @details
  42. * This header file must be included in all QF ports that use native QF
  43. * event queue for active objects. Also, this file needs to be included
  44. * in the QP/C library when the application uses QActive_defer()/
  45. * QActive_recall(). Finally, this file is also needed when the "raw"
  46. * thread-safe queues are used for communication between active objects
  47. * and non-framework entities, such as ISRs, device drivers, or legacy
  48. * code.
  49. */
  50. #ifndef QEQUEUE_H_
  51. #define QEQUEUE_H_
  52. #ifndef QF_EQUEUE_CTR_SIZE
  53. /*! The size [bytes] of the ring-buffer counters used in the
  54. * native QF event queue implementation. Valid values: 1U, 2U, or 4U;
  55. * default 1U.
  56. * @details
  57. * This macro can be defined in the QF port file (qf_port.h) to
  58. * configure the ::QEQueueCtr type. Here the macro is not defined so the
  59. * default of 1 byte is chosen.
  60. */
  61. #define QF_EQUEUE_CTR_SIZE 1U
  62. #endif
  63. #if (QF_EQUEUE_CTR_SIZE == 1U)
  64. /*! The data type to store the ring-buffer counters based on
  65. * the macro #QF_EQUEUE_CTR_SIZE.
  66. * @details
  67. * The dynamic range of this data type determines the maximum length
  68. * of the ring buffer managed by the native QF event queue.
  69. */
  70. typedef uint8_t QEQueueCtr;
  71. #elif (QF_EQUEUE_CTR_SIZE == 2U)
  72. typedef uint16_t QEQueueCtr;
  73. #elif (QF_EQUEUE_CTR_SIZE == 4U)
  74. typedef uint32_t QEQueueCtr;
  75. #else
  76. #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U"
  77. #endif
  78. /*==========================================================================*/
  79. /*$declare${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  80. /*${QF::QEQueue} ...........................................................*/
  81. /*! @brief Native QF Event Queue
  82. * @class QEQueue
  83. *
  84. * @details
  85. * This class describes the native QF event queue, which can be used as
  86. * the event queue for active objects, or as a simple "raw" event queue for
  87. * thread-safe event passing among non-framework entities, such as ISRs,
  88. * device drivers, or other third-party components.<br>
  89. *
  90. * The native QF event queue is configured by defining the macro
  91. * #QF_EQUEUE_TYPE as ::QEQueue in the specific QF port header file.<br>
  92. * <br>
  93. * The ::QEQueue structure contains only data members for managing an event
  94. * queue, but does not contain the storage for the queue buffer, which must
  95. * be provided externally during the queue initialization.<br>
  96. * <br>
  97. * The event queue can store only event pointers, not the whole events. The
  98. * internal implementation uses the standard ring-buffer plus one external
  99. * location that optimizes the queue operation for the most frequent case
  100. * of empty queue.<br>
  101. * <br>
  102. * The ::QEQueue structure is used with two sets of functions. One set is for
  103. * the active object event queue, which might need to block the active object
  104. * task when the event queue is empty and might need to unblock it when
  105. * events are posted to the queue. The interface for the native active object
  106. * event queue consists of the following functions: QActive_post(),
  107. * QActive_postLIFO(), and QActive_get_(). Additionally the function
  108. * QEQueue_init() is used to initialize the queue.<br>
  109. * <br>
  110. * The other set of functions, uses ::QEQueue as a simple "raw" event
  111. * queue to pass events between entities other than active objects, such as
  112. * ISRs. The "raw" event queue is not capable of blocking on the get()
  113. * operation, but is still thread-safe because it uses QF critical section
  114. * to protect its integrity. The interface for the "raw" thread-safe queue
  115. * consists of the following functions: QEQueue_post(),
  116. * QEQueue_postLIFO(), and QEQueue_get(). Additionally the function
  117. * QEQueue_init() is used to initialize the queue.
  118. *
  119. * <br>ote Most event queue operations (both the active object queues and
  120. * the "raw" queues) internally use the QF critical section. You should be
  121. * careful not to invoke those operations from other critical sections when
  122. * nesting of critical sections is not supported.
  123. *
  124. * @sa ::QEQueue for the description of the data members
  125. */
  126. typedef struct {
  127. /* private: */
  128. /*! pointer to event at the front of the queue.
  129. * @private @memberof QEQueue
  130. *
  131. * @details
  132. * All incoming and outgoing events pass through the frontEvt location.
  133. * When the queue is empty (which is most of the time), the extra
  134. * frontEvt location allows to bypass the ring buffer altogether,
  135. * greatly optimizing the performance of the queue. Only bursts of events
  136. * engage the ring buffer.
  137. *
  138. * <br>ote The additional role of this attribute is to indicate the empty
  139. * status of the queue. The queue is empty when frontEvt is NULL.
  140. */
  141. QEvt const * volatile frontEvt;
  142. /*! pointer to the start of the ring buffer
  143. * @private @memberof QEQueue
  144. */
  145. QEvt const ** ring;
  146. /*! offset of the end of the ring buffer from the start of the buffer
  147. * @private @memberof QEQueue
  148. */
  149. QEQueueCtr end;
  150. /*! offset to where next event will be inserted into the buffer
  151. * @private @memberof QEQueue
  152. */
  153. QEQueueCtr volatile head;
  154. /*! offset of where next event will be extracted from the buffer
  155. * @private @memberof QEQueue
  156. */
  157. QEQueueCtr volatile tail;
  158. /*! number of free events in the ring buffer
  159. * @private @memberof QEQueue
  160. */
  161. QEQueueCtr volatile nFree;
  162. /*! Minimum number of free events ever in the ring buffer.
  163. * @private @memberof QEQueue
  164. *
  165. * @details
  166. * This attribute remembers the low-watermark of the ring buffer,
  167. * which provides a valuable information for sizing event queues.
  168. * @sa QF_getQueueMargin().
  169. */
  170. QEQueueCtr nMin;
  171. } QEQueue;
  172. /* public: */
  173. /*! Initialize the native QF event queue.
  174. * @public @memberof QEQueue
  175. *
  176. * @details
  177. * Initialize the event queue by giving it the storage for the ring buffer.
  178. *
  179. * @param[in,out] me current instance pointer (see @ref oop)
  180. * @param[in] qSto an array of pointers to ::QEvt to sereve as the
  181. * ring buffer for the event queue
  182. * @param[in] qLen the length of the `qSto` buffer (in ::QEvt pointers)
  183. *
  184. * @note The actual capacity of the queue is qLen + 1, because of the extra
  185. * location forntEvt.
  186. *
  187. * @note
  188. * This function is also used to initialize the event queues of active
  189. * objects in the built-int QV and QK kernels, as well as other
  190. * QP ports to OSes/RTOSes that do provide a suitable message queue.
  191. */
  192. void QEQueue_init(QEQueue * const me,
  193. QEvt const ** const qSto,
  194. uint_fast16_t const qLen);
  195. /*! Post an event to the "raw" thread-safe event queue (FIFO).
  196. * @public @memberof QEQueue
  197. *
  198. * @details
  199. * Post an event to the "raw" thread-safe event queue using the
  200. * First-In-First-Out (FIFO) order.
  201. *
  202. * @param[in,out] me current instance pointer (see @ref oop)
  203. * @param[in] e pointer to the event to be posted to the queue
  204. * @param[in] margin number of required free slots in the queue after
  205. * posting the event. The special value #QF_NO_MARGIN
  206. * means that this function will assert if posting
  207. * @returns 'true' (success) when the posting succeeded with the provided
  208. * margin and 'false' (failure) when the posting fails.
  209. *
  210. * @precondition{qf_qeq,200}
  211. * - event must be valid
  212. *
  213. * @note
  214. * The #QF_NO_MARGIN value of the `margin` parameter is special and
  215. * denotes situation when the post() operation is assumed to succeed (event
  216. * delivery guarantee). An assertion fires, when the event cannot be
  217. * delivered in this case.
  218. *
  219. * @note This function can be called from any task context or ISR context.
  220. *
  221. * @sa QEQueue_postLIFO(), QEQueue_get()
  222. */
  223. bool QEQueue_post(QEQueue * const me,
  224. QEvt const * const e,
  225. uint_fast16_t const margin,
  226. uint_fast8_t const qs_id);
  227. /*! Post an event to the "raw" thread-safe event queue (LIFO).
  228. * @public @memberof QEQueue
  229. *
  230. * @details
  231. * Post an event to the "raw" thread-safe event queue using the
  232. * Last-In-First-Out (LIFO) order.
  233. *
  234. * @param[in,out] me current instance pointer (see @ref oop)
  235. * @param[in] e pointer to the event to be posted to the queue
  236. *
  237. * @precondition{qf_qeq,300}
  238. * - the queue must be able to accept the event (cannot overflow)
  239. * @attention
  240. * The LIFO policy should be used only with great __caution__, because
  241. * it alters the order of events in the queue.
  242. *
  243. * @note
  244. * This function can be called from any task context or ISR context.
  245. *
  246. * @note
  247. * this function is used for the "raw" thread-safe queues and __not__
  248. * for the queues of active objects.
  249. *
  250. * @sa
  251. * QEQueue_post(), QEQueue_get(), QActive_defer()
  252. */
  253. void QEQueue_postLIFO(QEQueue * const me,
  254. QEvt const * const e,
  255. uint_fast8_t const qs_id);
  256. /*! Obtain an event from the "raw" thread-safe queue.
  257. * @public @memberof QEQueue
  258. *
  259. * @details
  260. * Retrieves an event from the front of the "raw" thread-safe queue and
  261. * returns a pointer to this event to the caller.
  262. *
  263. * @param[in,out] me current instance pointer (see @ref oop)
  264. *
  265. * @returns
  266. * pointer to event at the front of the queue, if the queue is
  267. * not empty and NULL if the queue is empty.
  268. *
  269. * @note
  270. * this function is used for the "raw" thread-safe queues and __not__
  271. * for the queues of active objects.
  272. *
  273. * @sa
  274. * QEQueue_post(), QEQueue_postLIFO(), QActive_recall()
  275. */
  276. QEvt const * QEQueue_get(QEQueue * const me,
  277. uint_fast8_t const qs_id);
  278. /*! "raw" thread-safe QF event queue operation for obtaining the number
  279. * of free entries still available in the queue.
  280. * @public @memberof QEQueue
  281. *
  282. * @details
  283. * This operation needs to be used with caution because the number of free
  284. * entries can change unexpectedly. The main intent for using this operation
  285. * is in conjunction with event deferral. In this case the queue is accessed
  286. * only from a single thread (by a single AO), so the number of free
  287. * entries cannot change unexpectedly.
  288. *
  289. * @param[in] me current instance pointer (see @ref oop)
  290. *
  291. * @returns the current number of free slots in the queue.
  292. */
  293. static inline QEQueueCtr QEQueue_getNFree(QEQueue const * const me) {
  294. return me->nFree;
  295. }
  296. /*! "raw" thread-safe QF event queue operation for obtaining the minimum
  297. * number of free entries ever in the queue (a.k.a. "low-watermark").
  298. * @public @memberof QEQueue
  299. *
  300. * @details
  301. * This operation needs to be used with caution because the "low-watermark"
  302. * can change unexpectedly. The main intent for using this operation is to
  303. * get an idea of queue usage to size the queue adequately.
  304. *
  305. * @param[in] me current instance pointer (see @ref oop)
  306. *
  307. * @returns the minimum number of free entries ever in the queue since init.
  308. */
  309. static inline QEQueueCtr QEQueue_getNMin(QEQueue const * const me) {
  310. return me->nMin;
  311. }
  312. /*! "raw" thread-safe QF event queue operation to find out if the queue
  313. * is empty.
  314. * @public @memberof QEQueue
  315. *
  316. * @details
  317. * This operation needs to be used with caution because the queue status
  318. * can change unexpectedly. The main intent for using this operation is in
  319. * conjunction with event deferral. In this case the queue is accessed only
  320. * from a single thread (by a single AO), so no other entity can post
  321. * events to the queue.
  322. *
  323. * @param[in] me_ current instance pointer (see @ref oop)
  324. *
  325. * @returns 'true' if the queue is current empty and 'false' otherwise.
  326. */
  327. static inline bool QEQueue_isEmpty(QEQueue const * const me) {
  328. return me->frontEvt == (QEvt *)0;
  329. }
  330. /*$enddecl${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  331. #endif /* QEQUEUE_H_ */