QP/C++ 8.1.1
Real-Time Event Framework
Loading...
Searching...
No Matches
qf_defer.cpp
Go to the documentation of this file.
1//============================================================================
2// QP/C++ Real-Time Event Framework (RTEF)
3//
4// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
5//
6// Q u a n t u m L e a P s
7// ------------------------
8// Modern Embedded Software
9//
10// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
11//
12// This software is dual-licensed under the terms of the open-source GNU
13// General Public License (GPL) or under the terms of one of the closed-
14// source Quantum Leaps commercial licenses.
15//
16// Redistributions in source code must retain this top-level comment block.
17// Plagiarizing this software to sidestep the license obligations is illegal.
18//
19// NOTE:
20// The GPL does NOT permit the incorporation of this code into proprietary
21// programs. Please contact Quantum Leaps for commercial licensing options,
22// which expressly supersede the GPL and are designed explicitly for
23// closed-source distribution.
24//
25// Quantum Leaps contact information:
26// <www.state-machine.com/licensing>
27// <info@state-machine.com>
28//============================================================================
29#define QP_IMPL // this is QP implementation
30#include "qp_port.hpp" // QP port
31#include "qp_pkg.hpp" // QP package-scope interface
32#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
33#ifdef Q_SPY // QS software tracing enabled?
34 #include "qs_port.hpp" // QS port
35 #include "qs_pkg.hpp" // QS facilities for pre-defined trace records
36#else
37 #include "qs_dummy.hpp" // disable the QS software tracing
38#endif // Q_SPY
39
40// unnamed namespace for local definitions with internal linkage
41namespace {
42Q_DEFINE_THIS_MODULE("qf_defer")
43} // unnamed namespace
44
45namespace QP {
46
47//............................................................................
49 QEQueue * const eq,
50 QEvt const * const e) const noexcept
51{
52 // post with margin==0U to use all available entries in the queue
53 bool const status = eq->post(e, 0U, m_prio);
54
57 if (status) { // deferring successful?
59 QS_TIME_PRE(); // time stamp
60 QS_OBJ_PRE(this); // this active object
61 QS_OBJ_PRE(eq); // the deferred queue
62 QS_SIG_PRE(e->sig); // the signal of the event
63 QS_2U8_PRE(e->poolNum_, e->refCtr_);
65 }
66 else { // deferring failed
68 QS_TIME_PRE(); // time stamp
69 QS_OBJ_PRE(this); // this active object
70 QS_OBJ_PRE(eq); // the deferred queue
71 QS_SIG_PRE(e->sig); // the signal of the event
72 QS_2U8_PRE(e->poolNum_, e->refCtr_);
74 }
76
77 return status;
78}
79
80//............................................................................
81bool QActive::recall(QEQueue * const eq) noexcept {
82 QEvt const * const e = eq->get(m_prio); // get evt from deferred queue
83
84 bool recalled = false;
85 if (e != nullptr) { // event available?
86
87 // post it to the front of the AO's queue.
88 // NOTE: asserts internally if the posting fails.
89 postLIFO(e);
90
93
94 if (e->poolNum_ != 0U) { // mutable event?
95
96 // after posting to the AO's queue, the event must be referenced
97 // at least twice: once in the deferred event queue (eq->get()
98 // did NOT decrement the reference counter) and once in the
99 // AO's event queue.
100 Q_ASSERT_INCRIT(210, e->refCtr_ >= 2U);
101
102 // decrement the reference counter once, to account for removing
103 // the event from the deferred queue.
104 QEvt_refCtr_dec_(e); // decrement the reference counter
105 }
106
108 QS_TIME_PRE(); // time stamp
109 QS_OBJ_PRE(this); // this active object
110 QS_OBJ_PRE(eq); // the deferred queue
111 QS_SIG_PRE(e->sig); // the signal of the event
113 QS_END_PRE()
114
115 QF_CRIT_EXIT();
116
117 recalled = true; // success
118 }
119 else {
122
124 QS_TIME_PRE(); // time stamp
125 QS_OBJ_PRE(this); // this active object
126 QS_OBJ_PRE(eq); // the deferred queue
127 QS_END_PRE()
128
129 QS_CRIT_EXIT();
130 }
131 return recalled;
132}
133
134//............................................................................
136 QEQueue * const eq,
137 std::uint_fast16_t const num) const noexcept
138{
139 std::uint16_t n = 0U; // the flushed event counter
140 while (n < num) { // below the requested number?
141 QEvt const * const e = eq->get(m_prio);
142 if (e != nullptr) { // event obtained from the queue?
143 ++n; // count one more flushed event
144#if (QF_MAX_EPOOL > 0U)
145 QF::gc(e); // garbage collect
146#endif
147 }
148 else { // queue ran out of events
149 break; // done flushing
150 }
151 }
152
153 return n;
154}
155
156} // namespace QP
bool defer(QEQueue *const eq, QEvt const *const e) const noexcept
Defer an event to a given separate event queue.
Definition qf_defer.cpp:48
std::uint16_t flushDeferred(QEQueue *const eq, std::uint_fast16_t const num=0xFFFFU) const noexcept
Flush the specified deferred queue eq.
Definition qf_defer.cpp:135
void postLIFO(QEvt const *const e) noexcept
Posts an event e directly to the event queue of the active object using the Last-In-First-Out (LIFO) ...
Definition qf_actq.cpp:126
bool recall(QEQueue *const eq) noexcept
Recall a deferred event from a given event queue.
Definition qf_defer.cpp:81
std::uint8_t m_prio
QF-priority [1..QF_MAX_ACTIVE] of this AO.
Definition qp.hpp:490
Native QF Event Queue.
Definition qequeue.hpp:53
Event class.
Definition qp.hpp:101
std::uint32_t poolNum_
Event pool number of this event.
Definition qp.hpp:104
std::uint32_t refCtr_
Event reference counter.
Definition qp.hpp:105
std::uint32_t sig
Signal of the event (see Event Signal).
Definition qp.hpp:103
void gc(QEvt const *const e) noexcept
Recycle a mutable (mutable) event.
Definition qf_dyn.cpp:276
QP/C++ Framework namespace.
Definition qequeue.hpp:36
@ QS_QF_ACTIVE_RECALL
AO recalled an event.
Definition qs.hpp:69
@ QS_QF_ACTIVE_RECALL_ATTEMPT
AO attempted to recall an event.
Definition qs.hpp:76
@ QS_QF_ACTIVE_DEFER_ATTEMPT
AO attempted to defer an event.
Definition qs.hpp:171
@ QS_QF_ACTIVE_DEFER
AO deferred an event.
Definition qs.hpp:68
void QEvt_refCtr_dec_(QEvt const *const me) noexcept
Internal function to decrement the refCtr of a const event.
Definition qf_act.cpp:68
QP Framework in C++ internal (package-scope) interface
Sample QP/C++ port.
#define QS_CRIT_STAT
Internal QS macro for defining the critical section status.
Definition qs.hpp:430
#define QS_TIME_PRE()
Definition qs.hpp:362
#define QS_CRIT_EXIT()
Internal macro for exiting a critical section.
Definition qs.hpp:438
#define QS_CRIT_ENTRY()
Internal macro for entering a critical section.
Definition qs.hpp:434
QS (QP/Spy software tracing) internal (package-scope) interface.
#define QS_OBJ_PRE(obj_)
Output pre-formatted object pointer element.
Definition qs_pkg.hpp:89
#define QS_SIG_PRE(sig_)
Output pre-formatted event signal data element.
Definition qs_pkg.hpp:90
#define QS_2U8_PRE(data1_, data2_)
Output two pre-formatted unsigned 8-bit integer data elements.
Definition qs_pkg.hpp:81
#define QS_END_PRE()
Pre-formatted QS trace record end.
Definition qs_pkg.hpp:77
#define QS_BEGIN_PRE(rec_, qsId_)
Pre-formatted QS trace record begin.
Definition qs_pkg.hpp:71
Sample QS/C++ port.
QP Functional Safety (FuSa) Subsystem.
#define QF_CRIT_ENTRY()
Definition qsafe.h:40
#define Q_ASSERT_INCRIT(id_, expr_)
General-purpose assertion with user-specified ID number (in critical section).
Definition qsafe.h:54
#define QF_CRIT_EXIT()
Definition qsafe.h:44
#define QF_CRIT_STAT
Definition qsafe.h:36