QP/C++  8.0.0
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qf_actq.cpp
Go to the documentation of this file.
1//$file${src::qf::qf_actq.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2//
3// Model: qpcpp.qm
4// File: ${src::qf::qf_actq.cpp}
5//
6// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
7// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
8//
9// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
10//
11// Q u a n t u m L e a P s
12// ------------------------
13// Modern Embedded Software
14//
15// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
16//
17// The QP/C++ software is dual-licensed under the terms of the open-source
18// GNU General Public License (GPL) or under the terms of one of the closed-
19// source Quantum Leaps commercial licenses.
20//
21// Redistributions in source code must retain this top-level comment block.
22// Plagiarizing this software to sidestep the license obligations is illegal.
23//
24// NOTE:
25// The GPL does NOT permit the incorporation of this code into proprietary
26// programs. Please contact Quantum Leaps for commercial licensing options,
27// which expressly supersede the GPL and are designed explicitly for
28// closed-source distribution.
29//
30// Quantum Leaps contact information:
31// <www.state-machine.com/licensing>
32// <info@state-machine.com>
33//
34//$endhead${src::qf::qf_actq.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35#define QP_IMPL // this is QP implementation
36#include "qp_port.hpp" // QP port
37#include "qp_pkg.hpp" // QP package-scope interface
38#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
39#ifdef Q_SPY // QS software tracing enabled?
40 #include "qs_port.hpp" // QS port
41 #include "qs_pkg.hpp" // QS facilities for pre-defined trace records
42#else
43 #include "qs_dummy.hpp" // disable the QS software tracing
44#endif // Q_SPY
45
46//============================================================================
47// unnamed namespace for local definitions with internal linkage
48namespace {
49Q_DEFINE_THIS_MODULE("qf_actq")
50} // unnamed namespace
51
52//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
53// Check for the minimum required QP version
54#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
55#error qpcpp version 7.3.0 or higher required
56#endif
57//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58//$define${QF::QActive::post_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
59namespace QP {
60
61//${QF::QActive::post_} ......................................................
63 QEvt const * const e,
64 std::uint_fast16_t const margin,
65 void const * const sender) noexcept
66{
67 #ifndef Q_SPY
68 Q_UNUSED_PAR(sender);
69 #endif
70
71 #ifdef Q_UTEST // test?
72 #if (Q_UTEST != 0) // testing QP-stub?
73 if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
74 return static_cast<QActiveDummy *>(this)->fakePost(e, margin, sender);
75 }
76 #endif // (Q_UTEST != 0)
77 #endif // def Q_UTEST
78
81 QF_MEM_SYS();
82
83 Q_REQUIRE_INCRIT(200, e != nullptr);
84
85 QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
86 #ifndef Q_UNSAFE
87 QEQueueCtr dis = static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis);
88 Q_INVARIANT_INCRIT(201, e->verify_() && (tmp == dis));
89 #endif // ndef Q_UNSAFE
90
91 // test-probe#1 for faking queue overflow
94 tmp = 0U; // fake no free events
95 )
96
97 // required margin available?
98 bool status;
99 if (margin == QF::NO_MARGIN) {
100 if (tmp > 0U) { // free entries available in the queue?
101 status = true; // can post
102 }
103 else { // no free entries available
104 status = false; // cannot post
105
106 // The queue overflows, but QF_NO_MARGIN indicates that
107 // the "event delivery guarantee" is required.
108 Q_ERROR_INCRIT(210); // must be able to post the event
109 }
110 }
111 else if (tmp > static_cast<QEQueueCtr>(margin)) {
112 status = true; // can post
113 }
114 else { // the # free entries below the requested margin
115 status = false; // cannot post, but don't assert
116 }
117
118 // is it a mutable event?
119 if (e->getPoolNum_() != 0U) {
120 QEvt_refCtr_inc_(e); // increment the reference counter
121 }
122
123 if (status) { // can post the event?
124 --tmp; // one free entry just used up
125
126 m_eQueue.m_nFree = tmp; // update the original
127 #ifndef Q_UNSAFE
128 m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
129 #endif // ndef Q_UNSAFE
130
131 if (m_eQueue.m_nMin > tmp) {
132 m_eQueue.m_nMin = tmp; // update minimum so far
133 }
134
135 QS_BEGIN_PRE(QS_QF_ACTIVE_POST, m_prio)
136 QS_TIME_PRE(); // timestamp
137 QS_OBJ_PRE(sender); // the sender object
138 QS_SIG_PRE(e->sig); // the signal of the event
139 QS_OBJ_PRE(this); // this active object
140 QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
141 QS_EQC_PRE(tmp); // # free entries
142 QS_EQC_PRE(m_eQueue.m_nMin); // min # free entries
143 QS_END_PRE()
144
145 #ifdef Q_UTEST
146 // callback to examine the posted event under the same conditions
147 // as producing the #QS_QF_ACTIVE_POST trace record, which are:
148 // the local filter for this AO ('m_prio') is set
149 if (QS_LOC_CHECK_(m_prio)) {
150 QF_MEM_APP();
151 QF_CRIT_EXIT();
152
153 QS::onTestPost(sender, this, e, status);
154
156 QF_MEM_SYS();
157 }
158 #endif // def Q_UTEST
159
160 if (m_eQueue.m_frontEvt == nullptr) { // is the queue empty?
161 m_eQueue.m_frontEvt = e; // deliver event directly
162 #ifndef Q_UNSAFE
163 Q_INVARIANT_INCRIT(211, m_eQueue.m_frontEvt_dis
164 == static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr)));
165 m_eQueue.m_frontEvt_dis =
166 static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(e));
167 #endif // ndef Q_UNSAFE
168
169 #ifdef QXK_HPP_
170 if (m_state.act == nullptr) { // eXtended thread?
171 QXTHREAD_EQUEUE_SIGNAL_(this); // signal eXtended Thread
172 }
173 else {
174 QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
175 }
176 #else
177 QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
178 #endif // def QXK_HPP_
179 }
180 else { // queue was not empty, insert event into the ring-buffer
181 tmp = m_eQueue.m_head; // get volatile into temporary
182 #ifndef Q_UNSAFE
183 dis = static_cast<QEQueueCtr>(~m_eQueue.m_head_dis);
184 Q_INVARIANT_INCRIT(212, tmp == dis);
185 #endif // ndef Q_UNSAFE
186 m_eQueue.m_ring[tmp] = e; // insert e into buffer
187
188 if (tmp == 0U) { // need to wrap the head?
189 tmp = m_eQueue.m_end;
190 }
191 --tmp; // advance the head (counter-clockwise)
192
193 m_eQueue.m_head = tmp; // update the original
194 #ifndef Q_UNSAFE
195 m_eQueue.m_head_dis = static_cast<QEQueueCtr>(~tmp);
196 #endif // ndef Q_UNSAFE
197 }
198
199 QF_MEM_APP();
200 QF_CRIT_EXIT();
201 }
202 else { // event cannot be posted
203
204 QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, m_prio)
205 QS_TIME_PRE(); // timestamp
206 QS_OBJ_PRE(sender); // the sender object
207 QS_SIG_PRE(e->sig); // the signal of the event
208 QS_OBJ_PRE(this); // this active object
209 QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
210 QS_EQC_PRE(tmp); // # free entries
211 QS_EQC_PRE(margin); // margin requested
212 QS_END_PRE()
213
214 #ifdef Q_UTEST
215 // callback to examine the posted event under the same conditions
216 // as producing the #QS_QF_ACTIVE_POST trace record, which are:
217 // the local filter for this AO ('m_prio') is set
218 if (QS_LOC_CHECK_(m_prio)) {
219 QF_MEM_APP();
220 QF_CRIT_EXIT();
221
222 QS::onTestPost(sender, this, e, status);
223
225 QF_MEM_SYS();
226 }
227 #endif // def Q_USTEST
228
229 QF_MEM_APP();
230 QF_CRIT_EXIT();
231
232 #if (QF_MAX_EPOOL > 0U)
233 QF::gc(e); // recycle the event to avoid a leak
234 #endif // (QF_MAX_EPOOL > 0U)
235 }
236
237 return status;
238}
239
240} // namespace QP
241//$enddef${QF::QActive::post_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
242
243//$define${QF::QActive::postLIFO} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
244namespace QP {
245
246//${QF::QActive::postLIFO} ...................................................
247void QActive::postLIFO(QEvt const * const e) noexcept {
248 #ifdef Q_UTEST // test?
249 #if (Q_UTEST != 0) // testing QP-stub?
250 if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
251 static_cast<QActiveDummy *>(this)->QActiveDummy::fakePostLIFO(e);
252 return;
253 }
254 #endif // (Q_UTEST != 0)
255 #endif // def Q_UTEST
256
259 QF_MEM_SYS();
260
261 Q_REQUIRE_INCRIT(300, e != nullptr);
262
263 QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
264 #ifndef Q_UNSAFE
265 QEQueueCtr dis = static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis);
266 Q_INVARIANT_INCRIT(301, e->verify_() && (tmp == dis));
267 #endif // ndef Q_UNSAFE
268
269 // test-probe#1 for faking queue overflow
272 tmp = 0U; // fake no free events
273 )
274
275 // The queue must NOT overflow for the LIFO posting policy.
276 Q_REQUIRE_INCRIT(310, tmp != 0U);
277
278 if (e->getPoolNum_() != 0U) {
279 QEvt_refCtr_inc_(e); // increment the reference counter
280 }
281
282 --tmp; // one free entry just used up
283
284 m_eQueue.m_nFree = tmp; // update the original
285 #ifndef Q_UNSAFE
286 m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
287 #endif // ndef Q_UNSAFE
288
289 if (m_eQueue.m_nMin > tmp) {
290 m_eQueue.m_nMin = tmp; // update minimum so far
291 }
292
293 QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, m_prio)
294 QS_TIME_PRE(); // timestamp
295 QS_SIG_PRE(e->sig); // the signal of this event
296 QS_OBJ_PRE(this); // this active object
297 QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
298 QS_EQC_PRE(tmp); // # free entries
299 QS_EQC_PRE(m_eQueue.m_nMin); // min # free entries
300 QS_END_PRE()
301
302 #ifdef Q_UTEST
303 // callback to examine the posted event under the same conditions
304 // as producing the #QS_QF_ACTIVE_POST trace record, which are:
305 // the local filter for this AO ('m_prio') is set
306 if (QS_LOC_CHECK_(m_prio)) {
307 QF_MEM_APP();
308 QF_CRIT_EXIT();
309
310 QS::onTestPost(nullptr, this, e, true);
311
313 QF_MEM_SYS();
314 }
315 #endif // def Q_UTEST
316
317 QEvt const * const frontEvt = m_eQueue.m_frontEvt;
318 m_eQueue.m_frontEvt = e; // deliver the event directly to the front
319 #ifndef Q_UNSAFE
320 m_eQueue.m_frontEvt_dis =
321 static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(e));
322 #endif // ndef Q_UNSAFE
323
324 if (frontEvt != nullptr) { // was the queue NOT empty?
325 tmp = m_eQueue.m_tail; // get volatile into temporary;
326 #ifndef Q_UNSAFE
327 dis = static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis);
328 Q_INVARIANT_INCRIT(311, tmp == dis);
329 #endif // ndef Q_UNSAFE
330 ++tmp;
331 if (tmp == m_eQueue.m_end) { // need to wrap the tail?
332 tmp = 0U; // wrap around
333 }
334 m_eQueue.m_tail = tmp;
335 #ifndef Q_UNSAFE
336 m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~tmp);
337 #endif // ndef Q_UNSAFE
338 m_eQueue.m_ring[tmp] = frontEvt;
339 }
340 else { // queue was empty
341 QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
342 }
343
344 QF_MEM_APP();
345 QF_CRIT_EXIT();
346}
347
348} // namespace QP
349//$enddef${QF::QActive::postLIFO} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
350
351//$define${QF::QActive::get_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
352namespace QP {
353
354//${QF::QActive::get_} .......................................................
355QEvt const * QActive::get_() noexcept {
358 QF_MEM_SYS();
359
360 // wait for event to arrive directly (depends on QP port)
361 // NOTE: might use assertion-IDs 400-409
362 QACTIVE_EQUEUE_WAIT_(this); // wait for event to arrive directly
363
364 // always remove evt from the front
365 QEvt const * const e = m_eQueue.m_frontEvt;
366 QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into tmp
367
368 #ifndef Q_UNSAFE
369 Q_INVARIANT_INCRIT(410, e != nullptr); // queue must NOT be empty
371 == static_cast<std::uintptr_t>(~m_eQueue.m_frontEvt_dis));
372 QEQueueCtr dis = static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis);
373 Q_INVARIANT_INCRIT(412, tmp == dis);
374 #endif // ndef Q_UNSAFE
375
376 ++tmp; // one more free event in the queue
377
378 m_eQueue.m_nFree = tmp; // update the # free
379 #ifndef Q_UNSAFE
380 m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
381 #endif // ndef Q_UNSAFE
382
383 if (tmp <= m_eQueue.m_end) { // any events in the ring buffer?
384 QS_BEGIN_PRE(QS_QF_ACTIVE_GET, m_prio)
385 QS_TIME_PRE(); // timestamp
386 QS_SIG_PRE(e->sig); // the signal of this event
387 QS_OBJ_PRE(this); // this active object
389 QS_EQC_PRE(tmp); // # free entries
390 QS_END_PRE()
391
392 // remove event from the tail
393 tmp = m_eQueue.m_tail; // get volatile into temporary
394 #ifndef Q_UNSAFE
395 dis = static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis);
396 Q_INVARIANT_INCRIT(420, tmp == dis);
397 #endif // ndef Q_UNSAFE
398 QEvt const * const frontEvt = m_eQueue.m_ring[tmp];
399 #ifndef Q_UNSAFE
400 Q_ASSERT_INCRIT(421, frontEvt != nullptr);
401 m_eQueue.m_frontEvt_dis =
402 static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(frontEvt));
403 #endif // ndef Q_UNSAFE
404 m_eQueue.m_frontEvt = frontEvt; // update the original
405
406 if (tmp == 0U) { // need to wrap the tail?
407 tmp = m_eQueue.m_end;
408 }
409 --tmp; // advance the tail (counter-clockwise)
410
411 m_eQueue.m_tail = tmp; // update the original
412 #ifndef Q_UNSAFE
413 m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~tmp);
414 #endif // ndef Q_UNSAFE
415 }
416 else {
417 m_eQueue.m_frontEvt = nullptr; // the queue becomes empty
418 #ifndef Q_UNSAFE
419 m_eQueue.m_frontEvt_dis =
420 static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr));
421 #endif // ndef Q_UNSAFE
422
423 // all entries in the queue must be free (+1 for fronEvt)
424 Q_ASSERT_INCRIT(310, tmp == (m_eQueue.m_end + 1U));
425
426 QS_BEGIN_PRE(QS_QF_ACTIVE_GET_LAST, m_prio)
427 QS_TIME_PRE(); // timestamp
428 QS_SIG_PRE(e->sig); // the signal of this event
429 QS_OBJ_PRE(this); // this active object
431 QS_END_PRE()
432 }
433
434 QF_MEM_APP();
435 QF_CRIT_EXIT();
436
437 return e;
438}
439
440} // namespace QP
441//$enddef${QF::QActive::get_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
442
443//$define${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
444namespace QP {
445
446//${QF::QTicker} .............................................................
447
448//${QF::QTicker::QTicker} ....................................................
449QTicker::QTicker(std::uint_fast8_t const tickRate) noexcept
450: QActive(nullptr)
451{
452 // reuse m_head for tick-rate
453 m_eQueue.m_head = static_cast<QEQueueCtr>(tickRate);
454 #ifndef Q_UNSAFE
455 m_eQueue.m_head_dis = static_cast<QEQueueCtr>(~tickRate);
456 #endif // ndef Q_UNSAFE
457}
458
459//${QF::QTicker::init} .......................................................
461 void const * const e,
462 std::uint_fast8_t const qsId)
463{
464 Q_UNUSED_PAR(e);
465 Q_UNUSED_PAR(qsId);
466
469 QF_MEM_SYS();
470
471 m_eQueue.m_tail = 0U;
472 #ifndef Q_UNSAFE
473 m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~0U);
474 #endif // ndef Q_UNSAFE
475
476 QF_MEM_APP();
477 QF_CRIT_EXIT();
478}
479
480//${QF::QTicker::dispatch} ...................................................
482 QEvt const * const e,
483 std::uint_fast8_t const qsId)
484{
485 Q_UNUSED_PAR(e);
486 Q_UNUSED_PAR(qsId);
487
490 QF_MEM_SYS();
491
492 // get volatile into temporaries
493 QEQueueCtr nTicks = m_eQueue.m_tail;
494 QEQueueCtr const tickRate = m_eQueue.m_head;
495
496 #ifndef Q_UNSAFE
497 Q_REQUIRE_INCRIT(700, nTicks > 0U);
498 Q_INVARIANT_INCRIT(701, nTicks
499 == static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis));
500 Q_INVARIANT_INCRIT(702, tickRate
501 == static_cast<QEQueueCtr>(~m_eQueue.m_head_dis));
502 #endif // ndef Q_UNSAFE
503
504 m_eQueue.m_tail = 0U; // clear # ticks
505 #ifndef Q_UNSAFE
506 m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~0U);
507 #endif // ndef Q_UNSAFE
508
509 QF_MEM_APP();
510 QF_CRIT_EXIT();
511
512 for (; nTicks > 0U; --nTicks) {
513 QTimeEvt::tick(static_cast<std::uint_fast8_t>(tickRate),
514 this);
515 }
516}
517
518//${QF::QTicker::trig_} ......................................................
519void QTicker::trig_(void const * const sender) noexcept {
520 #ifndef Q_SPY
521 Q_UNUSED_PAR(sender);
522 #endif
523
524 static QEvt const tickEvt(0U); // immutable event
525
528 QF_MEM_SYS();
529
530 QEQueueCtr nTicks = m_eQueue.m_tail; // get volatile into temporary
531
532 if (m_eQueue.m_frontEvt == nullptr) {
533 #ifndef Q_UNSAFE
534 Q_REQUIRE_INCRIT(800, nTicks == 0U);
535 Q_REQUIRE_INCRIT(801, m_eQueue.m_nFree == 1U);
536 Q_INVARIANT_INCRIT(802, m_eQueue.m_frontEvt_dis
537 == static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr)));
539 1U == static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis));
541 0U == static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis));
542 #endif // ndef Q_UNSAFE
543
544 m_eQueue.m_frontEvt = &tickEvt; // deliver event directly
545 m_eQueue.m_nFree = 0U;
546 #ifndef Q_UNSAFE
547 m_eQueue.m_frontEvt_dis =
548 static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(&tickEvt));
549 m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~0U);
550 #endif // ndef Q_UNSAFE
551
552 QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
553 }
554 else {
555 #ifndef Q_UNSAFE
556 Q_REQUIRE_INCRIT(810, (nTicks > 0U) && (nTicks < 0xFFU));
557 Q_REQUIRE_INCRIT(811, m_eQueue.m_nFree == 0U);
558 Q_INVARIANT_INCRIT(812, m_eQueue.m_frontEvt_dis
559 == static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(&tickEvt)));
561 0U == static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis));
563 nTicks == static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis));
564 #endif // ndef Q_UNSAFE
565 }
566
567 ++nTicks; // account for one more tick event
568
569 m_eQueue.m_tail = nTicks; // update the original
570 #ifndef Q_UNSAFE
571 m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~nTicks);
572 #endif // ndef Q_UNSAFE
573
574 QS_BEGIN_PRE(QS_QF_ACTIVE_POST, m_prio)
575 QS_TIME_PRE(); // timestamp
576 QS_OBJ_PRE(sender); // the sender object
577 QS_SIG_PRE(0U); // the signal of the event
578 QS_OBJ_PRE(this); // this active object
579 QS_2U8_PRE(0U, 0U); // poolNum & refCtr
580 QS_EQC_PRE(0U); // # free entries
581 QS_EQC_PRE(0U); // min # free entries
582 QS_END_PRE()
583
584 QF_MEM_APP();
585 QF_CRIT_EXIT();
586}
587
588} // namespace QP
589//$enddef${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dummy Active Object for testing.
Active object class (based on the QHsm implementation strategy)
Definition qp.hpp:699
friend class QTicker
Definition qp.hpp:731
bool post_(QEvt const *const e, std::uint_fast16_t const margin, void const *const sender) noexcept
Definition qf_actq.cpp:62
QACTIVE_EQUEUE_TYPE m_eQueue
Definition qp.hpp:713
QEvt const * get_() noexcept
Definition qf_actq.cpp:355
void postLIFO(QEvt const *const e) noexcept
Definition qf_actq.cpp:247
std::uint8_t m_prio
Definition qp.hpp:701
Event class.
Definition qp.hpp:131
QSignal sig
Signal of the event (see Event Signal)
Definition qp.hpp:133
std::uint8_t volatile refCtr_
Event reference counter.)
Definition qp.hpp:135
std::uint_fast8_t getPoolNum_() const noexcept
Internal function to get the event pool-number of the given event.
Definition qp.hpp:159
void trig_(void const *const sender) noexcept
Definition qf_actq.cpp:519
void dispatch(QEvt const *const e, std::uint_fast8_t const qsId) override
Virtual function to dispatch an event to the state machine.
Definition qf_actq.cpp:481
void init(void const *const e, std::uint_fast8_t const qsId) override
Virtual function to take the top-most initial transition in the state machine.
Definition qf_actq.cpp:460
static void tick(std::uint_fast8_t const tickRate, void const *const sender) noexcept
Definition qf_time.cpp:341
void gc(QEvt const *const e) noexcept
Recycle a mutable (mutable) event.
Definition qf_dyn.cpp:213
constexpr std::uint_fast16_t NO_MARGIN
Definition qp.hpp:1086
QP/C++ framework.
Definition qequeue.hpp:42
void QEvt_refCtr_inc_(QEvt const *const e) noexcept
Definition qp_pkg.hpp:81
std::uint16_t QEQueueCtr
Definition qequeue.hpp:47
#define QACTIVE_EQUEUE_SIGNAL_(me_)
Definition qk.hpp:139
#define QACTIVE_EQUEUE_WAIT_(me_)
Definition qk.hpp:135
#define QF_MEM_APP()
Definition qp.hpp:1322
#define Q_UNUSED_PAR(par_)
Helper macro to clearly mark unused parameters of functions.
Definition qp.hpp:498
#define Q_STATE_CAST(handler_)
Definition qp.hpp:456
#define QF_MEM_SYS()
Definition qp.hpp:1317
Internal (package scope) QP/C++ interface.
#define Q_PTR2UINT_CAST_(ptr_)
Internal helper macro to cast pointers to integers.
Definition qp_pkg.hpp:72
Sample QP/C++ port.
#define QS_OBJ_PRE(obj_)
Definition qs_dummy.hpp:158
#define QS_EQC_PRE(ctr_)
Definition qs_dummy.hpp:160
#define QS_SIG_PRE(sig_)
Definition qs_dummy.hpp:156
#define QS_TIME_PRE()
Definition qs_dummy.hpp:155
#define QS_2U8_PRE(data1_, data2_)
Definition qs_dummy.hpp:152
#define QS_TEST_PROBE_DEF(fun_)
Definition qs_dummy.hpp:78
#define QS_TEST_PROBE_ID(id_, code_)
Definition qs_dummy.hpp:80
#define QS_END_PRE()
Definition qs_dummy.hpp:150
#define QS_BEGIN_PRE(rec_, qsId_)
Definition qs_dummy.hpp:149
QS/C++ port to a 32-bit CPU, generic C++ compiler.
QP Functional Safety (FuSa) Subsystem.
#define QF_CRIT_ENTRY()
Definition qsafe.h:58
#define Q_ASSERT_INCRIT(id_, expr_)
Definition qsafe.h:72
#define Q_INVARIANT_INCRIT(id_, expr_)
Definition qsafe.h:154
#define QF_CRIT_EXIT()
Definition qsafe.h:62
#define Q_REQUIRE_INCRIT(id_, expr_)
Definition qsafe.h:136
#define Q_ERROR_INCRIT(id_)
Definition qsafe.h:76
#define QF_CRIT_STAT
Definition qsafe.h:54