QP/C++  7.3.3
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qf_dyn.cpp
Go to the documentation of this file.
1//$file${src::qf::qf_dyn.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2//
3// Model: qpcpp.qm
4// File: ${src::qf::qf_dyn.cpp}
5//
6// This code has been generated by QM 6.1.1 <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) : qpcpp
13// Support ends : 2024-12-31
14// License scope:
15//
16// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
17//
18// Q u a n t u m L e a P s
19// ------------------------
20// Modern Embedded Software
21//
22// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
23//
24// This software is dual-licensed under the terms of the open source GNU
25// General Public License version 3 (or any later version), or alternatively,
26// under the terms of one of the closed source Quantum Leaps commercial
27// licenses.
28//
29// The terms of the open source GNU General Public License version 3
30// can be found at: <www.gnu.org/licenses/gpl-3.0>
31//
32// The terms of the closed source Quantum Leaps commercial licenses
33// can be found at: <www.state-machine.com/licensing>
34//
35// Redistributions in source code must retain this top-level comment block.
36// Plagiarizing this software to sidestep the license obligations is illegal.
37//
38// Contact information:
39// <www.state-machine.com/licensing>
40// <info@state-machine.com>
41//
42//$endhead${src::qf::qf_dyn.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43#define QP_IMPL // this is QP implementation
44#include "qp_port.hpp" // QP port
45#include "qp_pkg.hpp" // QP package-scope interface
46#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
47#ifdef Q_SPY // QS software tracing enabled?
48 #include "qs_port.hpp" // QS port
49 #include "qs_pkg.hpp" // QS facilities for pre-defined trace records
50#else
51 #include "qs_dummy.hpp" // disable the QS software tracing
52#endif // Q_SPY
53
54#if (QF_MAX_EPOOL > 0U) // mutable events configured?
55
56// unnamed namespace for local definitions with internal linkage
57namespace {
58Q_DEFINE_THIS_MODULE("qf_dyn")
59} // unnamed namespace
60
61//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
62// Check for the minimum required QP version
63#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U))
64#error qpcpp version 7.3.0 or higher required
65#endif
66//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67
68//$define${QEP::QEvt::ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
69namespace QP {
70
71//${QEP::QEvt::ctor} .........................................................
72#ifdef QEVT_DYN_CTOR
73QEvt * QEvt::ctor(DynEvt const dummy) noexcept {
74 Q_UNUSED_PAR(dummy);
75 return this;
76}
77
78#endif // def QEVT_DYN_CTOR
79
80} // namespace QP
81//$enddef${QEP::QEvt::ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
82//$define${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
83namespace QP {
84namespace QF {
85
86//${QF::QF-dyn::poolInit} ....................................................
88 void * const poolSto,
89 std::uint_fast32_t const poolSize,
90 std::uint_fast16_t const evtSize) noexcept
91{
92 std::uint_fast8_t const poolNum = priv_.maxPool_;
93
94 // see precondition{qf_dyn,200} and precondition{qf_dyn,201}
97 QF_MEM_SYS();
98
99 Q_REQUIRE_INCRIT(200, poolNum < QF_MAX_EPOOL);
100 if (poolNum > 0U) {
102 QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum - 1U]) < evtSize);
103 }
104 priv_.maxPool_ = poolNum + 1U; // one more pool
105
106 QF_MEM_APP();
107 QF_CRIT_EXIT();
108
109 // perform the port-dependent initialization of the event-pool
110 QF_EPOOL_INIT_(priv_.ePool_[poolNum], poolSto, poolSize, evtSize);
111
112 #ifdef Q_SPY
113 // generate the object-dictionary entry for the initialized pool
114 {
115 std::uint8_t obj_name[9] = "EvtPool?";
116 obj_name[7] = static_cast<std::uint8_t>(
117 static_cast<std::uint8_t>('0')
118 + static_cast<std::uint8_t>(poolNum + 1U));
119 QS::obj_dict_pre_(&priv_.ePool_[poolNum],
120 reinterpret_cast<char *>(&obj_name[0]));
121 }
122 #endif // Q_SPY
123}
124
125//${QF::QF-dyn::poolGetMaxBlockSize} .........................................
126std::uint_fast16_t poolGetMaxBlockSize() noexcept {
129 QF_MEM_SYS();
130 std::uint_fast16_t const max_size =
132 QF_MEM_APP();
133 QF_CRIT_EXIT();
134
135 return max_size;
136}
137
138//${QF::QF-dyn::getPoolMin} ..................................................
139std::uint_fast16_t getPoolMin(std::uint_fast8_t const poolNum) noexcept {
142 QF_MEM_SYS();
143
144 Q_REQUIRE_INCRIT(400, (poolNum <= QF_MAX_EPOOL)
145 && (0U < poolNum) && (poolNum <= priv_.maxPool_));
146
147 std::uint_fast16_t const min = static_cast<std::uint_fast16_t>(
148 priv_.ePool_[poolNum - 1U].getNMin());
149
150 QF_MEM_APP();
151 QF_CRIT_EXIT();
152
153 return min;
154}
155
156//${QF::QF-dyn::newX_} .......................................................
158 std::uint_fast16_t const evtSize,
159 std::uint_fast16_t const margin,
160 enum_t const sig) noexcept
161{
164 QF_MEM_SYS();
165
166 // find the pool id that fits the requested event size...
167 std::uint_fast8_t poolNum = 0U; // zero-based poolNum initially
168 for (; poolNum < priv_.maxPool_; ++poolNum) {
169 if (evtSize <= QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum])) {
170 break;
171 }
172 }
173
174 // precondition:
175 // - cannot run out of registered pools
176 Q_REQUIRE_INCRIT(300, poolNum < priv_.maxPool_);
177
178 ++poolNum; // convert to 1-based poolNum
179
180 QF_MEM_APP();
181 QF_CRIT_EXIT();
182
183 // get event e (port-dependent)...
184 QEvt *e;
185 #ifdef Q_SPY
186 QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
187 ((margin != NO_MARGIN) ? margin : 0U),
188 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum);
189 #else
190 QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
191 ((margin != NO_MARGIN) ? margin : 0U), 0U);
192 #endif
193
194 if (e != nullptr) { // was e allocated correctly?
195 e->sig = static_cast<QSignal>(sig); // set the signal
196 e->refCtr_ = 0U; // initialize the reference counter to 0
197 e->evtTag_ = static_cast<std::uint8_t>(QEvt::MARKER | poolNum);
198
200 QS_MEM_SYS();
201 QS_BEGIN_PRE_(QS_QF_NEW,
202 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum)
203 QS_TIME_PRE_(); // timestamp
204 QS_EVS_PRE_(evtSize); // the size of the event
205 QS_SIG_PRE_(sig); // the signal of the event
206 QS_END_PRE_()
207 QS_MEM_APP();
208 QS_CRIT_EXIT();
209 }
210 else { // event was not allocated
211
213 // This assertion means that the event allocation failed,
214 // and this failure cannot be tolerated. The most frequent
215 // reason is an event leak in the application.
216 Q_ASSERT_INCRIT(320, margin != NO_MARGIN);
217
218 QS_MEM_SYS();
219 QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT,
220 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum)
221 QS_TIME_PRE_(); // timestamp
222 QS_EVS_PRE_(evtSize); // the size of the event
223 QS_SIG_PRE_(sig); // the signal of the event
224 QS_END_PRE_()
225 QS_MEM_APP();
226
227 QF_CRIT_EXIT();
228 }
229
230 // the returned event e is guaranteed to be valid (not NULL)
231 // if we can't tolerate failed allocation
232 return e;
233}
234
235//${QF::QF-dyn::gc} ..........................................................
236void gc(QEvt const * const e) noexcept {
240
241 std::uint_fast8_t const poolNum = e->getPoolNum_();
242
243 if (poolNum != 0U) { // is it a pool event (mutable)?
244 QF_MEM_SYS();
245
246 if (e->refCtr_ > 1U) { // isn't this the last reference?
247
248 QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT,
249 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum)
250 QS_TIME_PRE_(); // timestamp
251 QS_SIG_PRE_(e->sig); // the signal of the event
252 QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr
253 QS_END_PRE_()
254
255 QEvt_refCtr_dec_(e); // decrement the ref counter
256
257 QF_MEM_APP();
258 QF_CRIT_EXIT();
259 }
260 else { // this is the last reference to this event, recycle it
261
262 QS_BEGIN_PRE_(QS_QF_GC,
263 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum)
264 QS_TIME_PRE_(); // timestamp
265 QS_SIG_PRE_(e->sig); // the signal of the event
266 QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr
267 QS_END_PRE_()
268
269 // pool number must be in range
270 Q_ASSERT_INCRIT(410, (poolNum <= priv_.maxPool_)
271 && (poolNum <= QF_MAX_EPOOL));
272 QF_MEM_APP();
273 QF_CRIT_EXIT();
274
275 // NOTE: casting 'const' away is legit because it's a pool event
276 #ifdef Q_SPY
277 QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
278 QF_CONST_CAST_(QEvt*, e),
279 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum);
280 #else
281 QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
282 QF_CONST_CAST_(QEvt*, e), 0U);
283 #endif
284 }
285 }
286 else {
287 QF_CRIT_EXIT();
288 }
289}
290
291//${QF::QF-dyn::newRef_} .....................................................
292QEvt const * newRef_(
293 QEvt const * const e,
294 QEvt const * const evtRef) noexcept
295{
296 #ifdef Q_UNSAFE
297 Q_UNUSED_PAR(evtRef);
298 #endif
299
302
304
305 std::uint_fast8_t const poolNum = e->getPoolNum_();
306
307 Q_REQUIRE_INCRIT(500, (poolNum != 0U)
308 && (evtRef == nullptr));
309
310 QEvt_refCtr_inc_(e); // increments the ref counter
311
312 QS_MEM_SYS();
313 QS_BEGIN_PRE_(QS_QF_NEW_REF,
314 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum)
315 QS_TIME_PRE_(); // timestamp
316 QS_SIG_PRE_(e->sig); // the signal of the event
317 QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr
318 QS_END_PRE_()
319 QS_MEM_APP();
320
321 QF_CRIT_EXIT();
322
323 return e;
324}
325
326//${QF::QF-dyn::deleteRef_} ..................................................
327void deleteRef_(QEvt const * const evtRef) noexcept {
328 QEvt const * const e = evtRef;
329
333
334 #ifdef Q_SPY
335 std::uint_fast8_t const poolNum = e->getPoolNum_();
336 #endif
337
338 QS_MEM_SYS();
339 QS_BEGIN_PRE_(QS_QF_DELETE_REF,
340 static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum)
341 QS_TIME_PRE_(); // timestamp
342 QS_SIG_PRE_(e->sig); // the signal of the event
343 QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr
344 QS_END_PRE_()
345 QS_MEM_APP();
346
347 QF_CRIT_EXIT();
348
349 #if (QF_MAX_EPOOL > 0U)
350 gc(evtRef); // recycle the referenced event
351 #endif
352}
353
354} // namespace QF
355} // namespace QP
356//$enddef${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
357
358#endif // (QF_MAX_EPOOL > 0U) mutable events configured
Event class.
Definition qp.hpp:139
static constexpr std::uint8_t MARKER
Definition qp.hpp:146
std::uint8_t evtTag_
Definition qp.hpp:143
std::uint_fast8_t getPoolNum_() const noexcept
Definition qp.hpp:167
QEvt * ctor(DynEvt const dummy) noexcept
Definition qf_dyn.cpp:73
std::uint8_t volatile refCtr_
Definition qp.hpp:142
static bool verify_(QEvt const *const e) noexcept
Definition qp.hpp:163
QSignal sig
Definition qp.hpp:141
QF_EPOOL_TYPE_ ePool_[QF_MAX_EPOOL]
Array of event pools sized for the maximum allowed number of pools.
Definition qp_pkg.hpp:55
std::uint_fast8_t maxPool_
Number of event pools managed by the QF Framework.
Definition qp_pkg.hpp:59
void deleteRef_(QEvt const *const evtRef) noexcept
Definition qf_dyn.cpp:327
QEvt const * newRef_(QEvt const *const e, QEvt const *const evtRef) noexcept
Definition qf_dyn.cpp:292
QF::Attr priv_
Definition qf_act.cpp:78
std::uint_fast16_t getPoolMin(std::uint_fast8_t const poolNum) noexcept
Definition qf_dyn.cpp:139
std::uint_fast16_t poolGetMaxBlockSize() noexcept
Definition qf_dyn.cpp:126
void poolInit(void *const poolSto, std::uint_fast32_t const poolSize, std::uint_fast16_t const evtSize) noexcept
Definition qf_dyn.cpp:87
constexpr std::uint_fast16_t NO_MARGIN
Definition qp.hpp:1101
QEvt * newX_(std::uint_fast16_t const evtSize, std::uint_fast16_t const margin, enum_t const sig) noexcept
Definition qf_dyn.cpp:157
void gc(QEvt const *const e) noexcept
Definition qf_dyn.cpp:236
QP/C++ framework.
Definition qequeue.hpp:50
void QEvt_refCtr_dec_(QEvt const *const e) noexcept
Decrement the refCtr of a const event (requires casting const away)
Definition qp_pkg.hpp:96
std::uint16_t QSignal
Definition qp.hpp:130
@ QS_EP_ID
offset for event-pool IDs
Definition qs.hpp:227
void QEvt_refCtr_inc_(QEvt const *const e) noexcept
Definition qp_pkg.hpp:92
@ QS_QF_NEW
new event was created
Definition qs.hpp:111
@ QS_QF_GC
garbage collection
Definition qs.hpp:113
@ QS_QF_DELETE_REF
an event reference is about to be deleted
Definition qs.hpp:125
@ QS_QF_NEW_ATTEMPT
an attempt to allocate an event failed
Definition qs.hpp:102
@ QS_QF_GC_ATTEMPT
garbage collection attempt
Definition qs.hpp:112
@ QS_QF_NEW_REF
new event reference was created
Definition qs.hpp:110
#define QF_EPOOL_EVENT_SIZE_(p_)
Definition qk.hpp:184
#define QF_EPOOL_PUT_(p_, e_, qsId_)
Definition qk.hpp:191
#define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_)
Definition qk.hpp:180
#define QF_EPOOL_GET_(p_, e_, m_, qsId_)
Definition qk.hpp:187
int enum_t
Definition qp.hpp:108
#define QF_MEM_APP()
Definition qp.hpp:1276
#define Q_UNUSED_PAR(par_)
Definition qp.hpp:541
#define QF_MEM_SYS()
Definition qp.hpp:1271
#define QF_MAX_EPOOL
Internal (package scope) QP/C++ interface.
#define QF_CONST_CAST_(type_, ptr_)
Definition qp_pkg.hpp:79
Sample QP/C++ port.
#define QS_TIME_PRE_()
Definition qs.hpp:473
#define QS_MEM_APP()
Definition qs.hpp:610
#define QS_CRIT_EXIT()
Definition qs.hpp:600
#define QS_MEM_SYS()
Definition qs.hpp:605
#define QS_CRIT_ENTRY()
Definition qs.hpp:595
QS/C++ package-scope interface.
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 QF_CRIT_EXIT()
Definition qsafe.h:62
#define Q_REQUIRE_INCRIT(id_, expr_)
Definition qsafe.h:136
#define QF_CRIT_STAT
Definition qsafe.h:54