QP/C++  7.0.1
Real-Time Embedded Framework
qf_defer.cpp
Go to the documentation of this file.
1//============================================================================
2// QP/C++ Real-Time Embedded Framework (RTEF)
3// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
4//
5// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
6//
7// This software is dual-licensed under the terms of the open source GNU
8// General Public License version 3 (or any later version), or alternatively,
9// under the terms of one of the closed source Quantum Leaps commercial
10// licenses.
11//
12// The terms of the open source GNU General Public License version 3
13// can be found at: <www.gnu.org/licenses/gpl-3.0>
14//
15// The terms of the closed source Quantum Leaps commercial licenses
16// can be found at: <www.state-machine.com/licensing>
17//
18// Redistributions in source code must retain this top-level comment block.
19// Plagiarizing this software to sidestep the license obligations is illegal.
20//
21// Contact information:
22// <www.state-machine.com>
23// <info@state-machine.com>
24//============================================================================
30
31#define QP_IMPL // this is QP implementation
32#include "qf_port.hpp" // QF port
33#include "qf_pkg.hpp" // QF package-scope interface
34#include "qassert.h" // QP embedded systems-friendly assertions
35#ifdef Q_SPY // QS software tracing enabled?
36 #include "qs_port.hpp" // QS port
37 #include "qs_pkg.hpp" // QS facilities for pre-defined trace records
38#else
39 #include "qs_dummy.hpp" // disable the QS software tracing
40#endif // Q_SPY
41
42// unnamed namespace for local definitions with internal linkage
43namespace {
44
45Q_DEFINE_THIS_MODULE("qf_defer")
46
47} // unnamed namespace
48
49namespace QP {
50
51//============================================================================
74bool QActive::defer(QEQueue * const eq, QEvt const * const e) const noexcept {
75 bool const status = eq->post(e, 0U, m_prio);
77
79 QS_TIME_PRE_(); // time stamp
80 QS_OBJ_PRE_(this); // this active object
81 QS_OBJ_PRE_(eq); // the deferred queue
82 QS_SIG_PRE_(e->sig); // the signal of the event
83 QS_2U8_PRE_(e->poolId_, e->refCtr_); // pool Id & ref Count
85
86 return status;
87}
88
89//============================================================================
110bool QActive::recall(QEQueue * const eq) noexcept {
111 QEvt const * const e = eq->get(m_prio); // get evt from deferred queue
112 bool recalled;
113
114 // event available?
115 if (e != nullptr) {
116 QActive::postLIFO(e); // post it to the _front_ of the AO's queue
117
119 QF_CRIT_E_();
120
121 // is it a dynamic event?
122 if (e->poolId_ != 0U) {
123
124 // after posting to the AO's queue the event must be referenced
125 // at least twice: once in the deferred event queue (eq->get()
126 // did NOT decrement the reference counter) and once in the
127 // AO's event queue.
128 Q_ASSERT_CRIT_(210, e->refCtr_ >= 2U);
129
130 // we need to decrement the reference counter once, to account
131 // for removing the event from the deferred event queue.
132 QF_EVT_REF_CTR_DEC_(e); // decrement the reference counter
133 }
134
136 QS_TIME_PRE_(); // time stamp
137 QS_OBJ_PRE_(this); // this active object
138 QS_OBJ_PRE_(eq); // the deferred queue
139 QS_SIG_PRE_(e->sig); // the signal of the event
140 QS_2U8_PRE_(e->poolId_, e->refCtr_); // pool Id & ref Count
142
143 QF_CRIT_X_();
144 recalled = true;
145 }
146 else {
148
150 QS_TIME_PRE_(); // time stamp
151 QS_OBJ_PRE_(this); // this active object
152 QS_OBJ_PRE_(eq); // the deferred queue
154
155 recalled = false;
156 }
157 return recalled;
158}
159
160//============================================================================
175std::uint_fast16_t QActive::flushDeferred(QEQueue * const eq) const noexcept {
176 std::uint_fast16_t n = 0U;
177 for (QEvt const *e = eq->get(m_prio);
178 e != nullptr;
179 e = eq->get(m_prio))
180 {
181 QF::gc(e); // garbage collect
182 ++n; // count the flushed event
183 }
184 return n;
185}
186
187} // namespace QP
virtual void postLIFO(QEvt const *const e) noexcept
Posts an event directly to the event queue of the active object using the Last-In-First-Out (LIFO) po...
Definition: qf_actq.cpp:221
bool defer(QEQueue *const eq, QEvt const *const e) const noexcept
Defer an event to a given separate event queue.
Definition: qf_defer.cpp:74
bool recall(QEQueue *const eq) noexcept
Recall a deferred event from a given event queue.
Definition: qf_defer.cpp:110
std::uint_fast16_t flushDeferred(QEQueue *const eq) const noexcept
Flush the specified deferred queue 'eq'.
Definition: qf_defer.cpp:175
Native QF Event Queue class.
Definition: qequeue.hpp:113
static void gc(QEvt const *const e) noexcept
Recycle a dynamic event.
Definition: qf_dyn.cpp:212
namespace associated with the QP/C++ framework
Definition: exa_native.dox:1
void QF_EVT_REF_CTR_DEC_(QEvt const *const e) noexcept
decrement the refCtr_ of an event e
Definition: qf_pkg.hpp:147
@ QS_QF_ACTIVE_RECALL
AO recalled an event.
Definition: qs.hpp:71
@ QS_QF_ACTIVE_RECALL_ATTEMPT
AO attempted to recall an event.
Definition: qs.hpp:78
@ QS_QF_ACTIVE_DEFER
AO deferred an event.
Definition: qs.hpp:70
Customizable and memory-efficient assertions for embedded systems.
#define Q_DEFINE_THIS_MODULE(name_)
Definition: qassert.h:102
Internal (package scope) QF/C++ interface.
#define QF_CRIT_STAT_
This is an internal macro for defining the critical section status type.
Definition: qf_pkg.hpp:48
#define Q_ASSERT_CRIT_(id_, test_)
Definition: qf_pkg.hpp:86
#define QF_CRIT_X_()
This is an internal macro for exiting a critical section.
Definition: qf_pkg.hpp:69
#define QF_CRIT_E_()
This is an internal macro for entering a critical section.
Definition: qf_pkg.hpp:58
#define QS_CRIT_STAT_
This is an internal macro for defining the critical section status type.
Definition: qs.hpp:746
#define QS_TIME_PRE_()
Definition: qs.hpp:225
Internal (package scope) QS/C++ interface.
#define QS_BEGIN_PRE_(rec_, qs_id_)
Internal QS macro to begin a predefined QS record with critical section.
Definition: qs_pkg.hpp:109
#define QS_BEGIN_NOCRIT_PRE_(rec_, qs_id_)
Internal QS macro to begin a predefined QS record without critical section.
Definition: qs_pkg.hpp:130
#define QS_OBJ_PRE_(obj_)
Internal QS macro to output object pointer data element.
Definition: qs_pkg.hpp:178
#define QS_END_NOCRIT_PRE_()
Internal QS macro to end a predefiend QS record without critical section.
Definition: qs_pkg.hpp:138
#define QS_2U8_PRE_(data1_, data2_)
Internal QS macro to output 2 unformatted uint8_t data elements.
Definition: qs_pkg.hpp:161
#define QS_END_PRE_()
Internal QS macro to end a predefined QS record with critical section.
Definition: qs_pkg.hpp:120
QEvt base class.
Definition: qep.hpp:191
QSignal sig
signal of the event instance
Definition: qep.hpp:192
std::uint8_t volatile refCtr_
reference counter
Definition: qep.hpp:194
std::uint8_t poolId_
pool ID (0 for static event)
Definition: qep.hpp:193