qpcpp/qpcpp.qm

6732 lines
236 KiB
Plaintext
Raw Normal View History

2022-08-11 15:36:19 -04:00
<?xml version="1.0" encoding="UTF-8"?>
2024-10-15 13:15:28 -04:00
<model version="7.0.0" links="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.state-machine.com/qm/qm7.xsd">
2022-08-11 15:36:19 -04:00
<documentation>QP/C++ Real-Time Embedded Framework (RTEF)
2024-10-15 13:15:28 -04:00
This model is used to generate the whole QP/C++ source code.
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Copyright (c) 2005 Quantum Leaps, LLC. All rights reserved.
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Q u a n t u m L e a P s
------------------------
Modern Embedded Software
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
The QP/C++ software is dual-licensed under the terms of the open-source GNU
General Public License (GPL) or under the terms of one of the closed-
source Quantum Leaps commercial licenses.
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Redistributions in source code must retain this top-level comment block.
2022-08-11 15:36:19 -04:00
Plagiarizing this software to sidestep the license obligations is illegal.
2024-10-15 13:15:28 -04:00
NOTE:
The GPL (see &lt;www.gnu.org/licenses/gpl-3.0&gt;) does NOT permit the
incorporation of the QP/C++ software into proprietary programs. Please
contact Quantum Leaps for commercial licensing options, which expressly
supersede the GPL and are designed explicitly for licensees interested
in using QP/C++ in closed-source proprietary applications.
Quantum Leaps contact information:
2022-08-11 15:36:19 -04:00
&lt;www.state-machine.com/licensing&gt;
&lt;info@state-machine.com&gt;</documentation>
<!--${qpcpp}-->
2024-07-19 19:23:03 -04:00
<framework name="qpcpp">
2024-10-15 13:15:28 -04:00
<license name="LicenseRef-QL-dual">public
2024-07-19 19:23:03 -04:00
qpcpp
2025-12-31
2024-10-15 13:15:28 -04:00
Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
2024-07-19 19:23:03 -04:00
Q u a n t u m L e a P s
------------------------
Modern Embedded Software
SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
2024-10-15 13:15:28 -04:00
The QP/C++ software is dual-licensed under the terms of the open-source
GNU General Public License (GPL) or under the terms of one of the closed-
source Quantum Leaps commercial licenses.
2024-07-19 19:23:03 -04:00
Redistributions in source code must retain this top-level comment block.
Plagiarizing this software to sidestep the license obligations is illegal.
2024-10-15 13:15:28 -04:00
NOTE:
The GPL does NOT permit the incorporation of this code into proprietary
programs. Please contact Quantum Leaps for commercial licensing options,
which expressly supersede the GPL and are designed explicitly for
closed-source distribution.
Quantum Leaps contact information:
2024-07-19 19:23:03 -04:00
&lt;www.state-machine.com/licensing&gt;
&lt;info@state-machine.com&gt;
2024-10-15 13:15:28 -04:00
#48B37CF39D4FD9DE279250B31FD388AFD0BE9B40</license>
2024-07-19 19:23:03 -04:00
</framework>
2022-08-11 15:36:19 -04:00
<!--${glob-types}-->
<package name="glob-types" stereotype="0x00">
<!--${glob-types::int_t}-->
<attribute name="int_t" type="using" visibility="0x04" properties="0x00">
<code> = int;</code>
</attribute>
<!--${glob-types::enum_t}-->
<attribute name="enum_t" type="using" visibility="0x04" properties="0x00">
<code> = int;</code>
</attribute>
<!--${glob-types::float32_t}-->
<attribute name="float32_t" type="using" visibility="0x04" properties="0x00">
<code> = float;</code>
</attribute>
<!--${glob-types::float64_t}-->
<attribute name="float64_t" type="using" visibility="0x04" properties="0x00">
<code> = double;</code>
</attribute>
</package>
<!--${QEP}-->
<package name="QEP" stereotype="0x05" namespace="QP::">
<!--${QEP::versionStr[]}-->
<attribute name="versionStr[]" type="constexpr char const" visibility="0x04" properties="0x01">
2024-10-15 13:15:28 -04:00
<documentation>//! the current QP version number string in ROM, based on #QP_VERSION_STR</documentation>
2022-08-11 15:36:19 -04:00
<code>{QP_VERSION_STR};</code>
</attribute>
<!--${QEP::QSignal}-->
<attribute name="QSignal? (Q_SIGNAL_SIZE == 1U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint8_t;</code>
</attribute>
<!--${QEP::QSignal}-->
<attribute name="QSignal? (Q_SIGNAL_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QEP::QSignal}-->
2022-08-11 15:36:19 -04:00
<attribute name="QSignal? (Q_SIGNAL_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QEP::QEvt}-->
<class name="QEvt">
<!--${QEP::QEvt::sig}-->
<attribute name="sig" type="QSignal" visibility="0x00" properties="0x00"/>
<!--${QEP::QEvt::evtTag_}-->
<attribute name="evtTag_" type="std::uint8_t" visibility="0x00" properties="0x00"/>
2024-10-15 13:15:28 -04:00
<!--${QEP::QEvt::refCtr_}-->
<attribute name="refCtr_" type="std::uint8_t volatile" visibility="0x00" properties="0x00"/>
<!--${QEP::QEvt::DynEvt}-->
2024-06-07 16:07:22 -04:00
<attribute name="DynEvt" type="enum" visibility="0x04" properties="0x00">
<code>: std::uint8_t { DYNAMIC };</code>
2022-08-11 15:36:19 -04:00
</attribute>
<!--${QEP::QEvt::QEvt}-->
<operation name="QEvt" type="explicit constexpr" visibility="0x00" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QEP::QEvt::QEvt::s}-->
<parameter name="s" type="QSignal const"/>
<code> : sig(s),
2024-10-15 13:15:28 -04:00
evtTag_(0x01U),
refCtr_(0x0EU)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QEvt::QEvt}-->
<operation name="QEvt" type="" visibility="0x00" properties="0x00">
<specifiers>= delete</specifiers>
</operation>
2024-06-07 16:07:22 -04:00
<!--${QEP::QEvt::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code>// no event parameters to initialize</code>
</operation>
<!--${QEP::QEvt::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QEvt::init::dummy}-->
<parameter name="dummy" type="DynEvt const"/>
<code>static_cast&lt;void&gt;(dummy);
// no event parameters to initialize</code>
</operation>
<!--${QEP::QEvt::verify_}-->
2024-10-15 13:15:28 -04:00
<operation name="verify_" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>std::uint8_t rc = refCtr_;
return (rc &lt;= 2U*QF_MAX_ACTIVE)
&amp;&amp; (((evtTag_ ^ rc) &amp; 0x0FU) == 0x0FU);</code>
</operation>
2024-02-08 21:09:29 -05:00
<!--${QEP::QEvt::getPoolNum_}-->
2024-01-17 07:50:09 -05:00
<operation name="getPoolNum_" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
2024-10-15 13:15:28 -04:00
<code>return static_cast&lt;std::uint8_t&gt;(evtTag_ &gt;&gt; 4U);</code>
2022-08-11 15:36:19 -04:00
</operation>
</class>
<!--${QEP::QState}-->
<attribute name="QState" type="using" visibility="0x04" properties="0x00">
<code>= std::uint_fast8_t;</code>
</attribute>
<!--${QEP::QStateHandler}-->
<attribute name="QStateHandler" type="using" visibility="0x04" properties="0x00">
<code>= QState (*)(void * const me, QEvt const * const e);</code>
</attribute>
<!--${QEP::QActionHandler}-->
<attribute name="QActionHandler" type="using" visibility="0x04" properties="0x00">
<code>= QState (*)(void * const me);</code>
</attribute>
<!--${QEP::QXThread}-->
<attribute name="QXThread" type="class" visibility="0x04" properties="0x00">
<documentation>// forward declaration</documentation>
2022-08-11 15:36:19 -04:00
</attribute>
<!--${QEP::QXThreadHandler}-->
<attribute name="QXThreadHandler" type="using" visibility="0x04" properties="0x00">
<code>= void (*)(QXThread * const me);</code>
</attribute>
<!--${QEP::QMState}-->
<attribute name="QMState" type="struct" visibility="0x04" properties="0x00">
<code>{
2024-10-15 13:15:28 -04:00
QMState const *superstate;
QStateHandler const stateHandler;
QActionHandler const entryAction;
QActionHandler const exitAction;
QActionHandler const initAction;
2022-08-11 15:36:19 -04:00
};</code>
</attribute>
<!--${QEP::QMTranActTable}-->
<attribute name="QMTranActTable" type="struct" visibility="0x04" properties="0x00">
<code>{
2024-10-15 13:15:28 -04:00
QMState const *target;
QActionHandler const act[1];
2022-08-11 15:36:19 -04:00
};</code>
</attribute>
<!--${QEP::QAsmAttr}-->
<attribute name="QAsmAttr" type="union" visibility="0x04" properties="0x00">
2022-08-11 15:36:19 -04:00
<code>{
QStateHandler fun;
QActionHandler act;
QXThreadHandler thr;
QMState const *obj;
QMTranActTable const *tatbl;
#ifndef Q_UNSAFE
std::uintptr_t uint;
#endif
constexpr QAsmAttr() : fun(nullptr) {}
2022-08-11 15:36:19 -04:00
};</code>
</attribute>
<!--${QEP::Q_USER_SIG}-->
<attribute name="Q_USER_SIG" type="constexpr enum_t " visibility="0x04" properties="0x00">
<code>{4};</code>
</attribute>
<!--${QEP::QAsm}-->
<class name="QAsm">
<documentation>Abstract State Machine</documentation>
<!--${QEP::QAsm::m_state}-->
<attribute name="m_state" type="QAsmAttr" visibility="0x01" properties="0x00"/>
<!--${QEP::QAsm::m_temp}-->
<attribute name="m_temp" type="QAsmAttr" visibility="0x01" properties="0x00"/>
<!--${QEP::QAsm::QStateRet}-->
2022-08-11 15:36:19 -04:00
<attribute name="QStateRet" type="enum" visibility="0x04" properties="0x01">
<documentation>//! All possible return values from state-handlers
//! @note
//! The order is important for algorithmic correctness.</documentation>
<code> : QState {
2022-08-11 15:36:19 -04:00
// unhandled and need to &quot;bubble up&quot;
Q_RET_SUPER, //!&lt; event passed to superstate to handle
Q_RET_UNHANDLED, //!&lt; event unhandled due to a guard
// handled and do not need to &quot;bubble up&quot;
Q_RET_HANDLED, //!&lt; event handled (internal transition)
Q_RET_IGNORED, //!&lt; event silently ignored (bubbled up to top)
// entry/exit
Q_RET_ENTRY, //!&lt; state entry action executed
Q_RET_EXIT, //!&lt; state exit action executed
// no side effects
Q_RET_NULL, //!&lt; return value without any effect
// transitions need to execute transition-action table in QP::QMsm
2022-08-28 22:12:27 -04:00
Q_RET_TRAN, //!&lt; regular transition
2024-10-15 13:15:28 -04:00
Q_RET_TRAN_INIT, //!&lt; initial transition in a state
2022-08-11 15:36:19 -04:00
// transitions that additionally clobber QHsm.m_state
Q_RET_TRAN_HIST, //!&lt; transition to history of a given state
};</code>
</attribute>
<!--${QEP::QAsm::ReservedSig}-->
<attribute name="ReservedSig" type="enum" visibility="0x04" properties="0x01">
<documentation>//! Reserved signals by the QP-framework.</documentation>
<code> : QSignal {
Q_EMPTY_SIG, //!&lt; signal to execute the default case
Q_ENTRY_SIG, //!&lt; signal for entry actions
Q_EXIT_SIG, //!&lt; signal for exit actions
Q_INIT_SIG //!&lt; signal for nested initial transitions
};</code>
</attribute>
<!--${QEP::QAsm::QAsm}-->
<operation name="QAsm" type="explicit" visibility="0x01" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<code> : m_state(),
m_temp ()</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QAsm::~QAsm}-->
<operation name="~QAsm?def Q_XTOR" type="" visibility="0x00" properties="0x06">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<code>// empty</code>
</operation>
<!--${QEP::QAsm::init}-->
2022-08-11 15:36:19 -04:00
<operation name="init" type="void" visibility="0x00" properties="0x04">
<specifiers>= 0</specifiers>
<!--${QEP::QAsm::init::e}-->
2022-08-11 15:36:19 -04:00
<parameter name="e" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QAsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
</operation>
<!--${QEP::QAsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
2024-01-17 07:50:09 -05:00
<!--${QEP::QAsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QEP::QAsm::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x04">
<specifiers>= 0</specifiers>
<!--${QEP::QAsm::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QAsm::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
</operation>
2023-12-14 16:55:58 -05:00
<!--${QEP::QAsm::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x06">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>static_cast&lt;void&gt;(state);
return false;</code>
</operation>
2024-01-17 07:50:09 -05:00
<!--${QEP::QAsm::state}-->
<operation name="state" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_state.fun;</code>
</operation>
<!--${QEP::QAsm::stateObj}-->
<operation name="stateObj" type="QMState const *" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_state.obj;</code>
</operation>
<!--${QEP::QAsm::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x06">
<specifiers>noexcept</specifiers>
<code>return m_state.fun;</code>
</operation>
<!--${QEP::QAsm::top}-->
<operation name="top" type="QState" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::top::me}-->
<parameter name="me" type="void * const"/>
<!--${QEP::QAsm::top::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>static_cast&lt;void&gt;(me);
static_cast&lt;void&gt;(e);
return Q_RET_IGNORED; // the top state ignores all events</code>
</operation>
<!--${QEP::QAsm::tran}-->
<operation name="tran" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::tran::target}-->
<parameter name="target" type="QStateHandler const"/>
<code>m_temp.fun = target;
return Q_RET_TRAN;</code>
</operation>
<!--${QEP::QAsm::tran_hist}-->
<operation name="tran_hist" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::tran_hist::hist}-->
<parameter name="hist" type="QStateHandler const"/>
<code>m_temp.fun = hist;
return Q_RET_TRAN_HIST;</code>
</operation>
<!--${QEP::QAsm::super}-->
<operation name="super" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::super::superstate}-->
<parameter name="superstate" type="QStateHandler const"/>
<code>m_temp.fun = superstate;
return Q_RET_SUPER;</code>
</operation>
<!--${QEP::QAsm::qm_tran}-->
<operation name="qm_tran" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN;</code>
</operation>
<!--${QEP::QAsm::qm_tran_init}-->
<operation name="qm_tran_init" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran_init::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN_INIT;</code>
</operation>
<!--${QEP::QAsm::qm_tran_hist}-->
<operation name="qm_tran_hist" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_tran_hist::hist}-->
<parameter name="hist" type="QMState const * const"/>
<!--${QEP::QAsm::qm_tran_hist::tatbl}-->
<parameter name="tatbl" type="void const * const"/>
<code>m_state.obj = hist;
m_temp.tatbl = static_cast&lt;QP::QMTranActTable const *&gt;(tatbl);
return Q_RET_TRAN_HIST;</code>
</operation>
<!--${QEP::QAsm::qm_entry}-->
<operation name="qm_entry?def Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_entry::s}-->
<parameter name="s" type="QMState const * const"/>
<code>m_temp.obj = s;
return Q_RET_ENTRY;</code>
</operation>
<!--${QEP::QAsm::qm_entry}-->
<operation name="qm_entry?ndef Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_entry::s}-->
<parameter name="s" type="QMState const * const"/>
<code>static_cast&lt;void&gt;(s); // unused parameter
return Q_RET_ENTRY;</code>
</operation>
<!--${QEP::QAsm::qm_exit}-->
<operation name="qm_exit?def Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_exit::s}-->
<parameter name="s" type="QMState const * const"/>
<code>m_temp.obj = s;
return Q_RET_EXIT;</code>
</operation>
<!--${QEP::QAsm::qm_exit}-->
<operation name="qm_exit?ndef Q_SPY" type="QState" visibility="0x01" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QEP::QAsm::qm_exit::s}-->
<parameter name="s" type="QMState const * const"/>
<code>static_cast&lt;void&gt;(s); // unused parameter
return Q_RET_EXIT;</code>
</operation>
</class>
<!--${QEP::QHsm}-->
<class name="QHsm" superclass="QEP::QAsm">
<documentation>Human-generated State Machine</documentation>
<!--${QEP::QHsm::QHsm}-->
<operation name="QHsm" type="explicit" visibility="0x01" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QEP::QHsm::QHsm::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code>: QAsm()
m_state.fun = Q_STATE_CAST(&amp;top);
m_temp.fun = initial;</code>
</operation>
<!--${QEP::QHsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
<!--${QEP::QHsm::init::e}-->
<parameter name="e" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QHsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
2024-10-15 13:15:28 -04:00
QState r;
// produce QS dictionary for QP::QHsm::top()
#ifdef Q_SPY
QS_CRIT_ENTRY();
QS_MEM_SYS();
if ((QS::priv_.flags &amp; 0x01U) == 0U) {
QS::priv_.flags |= 0x01U;
2024-10-15 13:15:28 -04:00
r = Q_RET_HANDLED;
}
else {
2024-10-15 13:15:28 -04:00
r = Q_RET_IGNORED;
}
QS_MEM_APP();
QS_CRIT_EXIT();
if (r == Q_RET_HANDLED) {
QS_FUN_DICTIONARY(&amp;QP::QHsm::top);
}
#else
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
2024-10-15 13:15:28 -04:00
#endif // def Q_SPY
QStateHandler t = m_state.fun;
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(200, (m_temp.fun != nullptr)
&amp;&amp; (t == Q_STATE_CAST(&amp;top)));
QF_CRIT_EXIT();
// execute the top-most initial tran.
2024-10-15 13:15:28 -04:00
r = (*m_temp.fun)(this, Q_EVT_CAST(QEvt));
QF_CRIT_ENTRY();
// the top-most initial tran. must be taken
Q_ASSERT_INCRIT(210, r == Q_RET_TRAN);
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(t); // the source state
QS_FUN_PRE(m_temp.fun); // the target of the initial tran.
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
// drill down into the state hierarchy with initial transitions...
do {
2024-07-19 19:23:03 -04:00
QStateHandler path[QHSM_MAX_NEST_DEPTH_]; // tran. entry path array
std::int_fast8_t ip = 0; // tran. entry path index
path[0] = m_temp.fun;
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
2024-04-24 09:13:46 -04:00
// note: ip is here the fixed upper loop bound
2024-07-19 19:23:03 -04:00
while ((m_temp.fun != t) &amp;&amp; (ip &lt; (QHSM_MAX_NEST_DEPTH_ - 1))) {
++ip;
path[ip] = m_temp.fun;
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
}
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
// too many state nesting levels or &quot;malformed&quot; HSM
2024-07-19 19:23:03 -04:00
Q_ENSURE_INCRIT(220, ip &lt; QHSM_MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
m_temp.fun = path[0];
// retrace the entry path in reverse (desired) order...
2024-04-24 09:13:46 -04:00
// note: ip is the fixed upper loop bound
do {
// enter path[ip]
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
== Q_RET_HANDLED)
{
2024-01-17 07:50:09 -05:00
QS_STATE_ENTRY_(path[ip], qsId);
}
--ip;
} while (ip &gt;= 0);
t = path[0]; // current state becomes the new source
r = QHSM_RESERVED_EVT_(t, Q_INIT_SIG); // execute initial tran.
2022-08-11 15:36:19 -04:00
#ifdef Q_SPY
if (r == Q_RET_TRAN) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(t); // the source state
QS_FUN_PRE(m_temp.fun); // the target of the initial tran.
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
#endif // Q_SPY
2024-04-24 09:13:46 -04:00
} while (r == Q_RET_TRAN);
QF_CRIT_ENTRY();
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId)
QS_TIME_PRE(); // time stamp
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(t); // the new active state
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
m_state.fun = t; // change the current active state
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QHsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
2024-01-17 07:50:09 -05:00
<!--${QEP::QHsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QHsm::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
2022-08-11 15:36:19 -04:00
<!--${QEP::QHsm::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QHsm::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
2022-11-17 14:13:33 -05:00
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
2022-11-17 14:13:33 -05:00
#endif
QStateHandler s = m_state.fun;
QStateHandler t = s;
QF_CRIT_STAT
2022-08-11 15:36:19 -04:00
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(300, (e != nullptr) &amp;&amp; (s != nullptr));
Q_INVARIANT_INCRIT(301,
e-&gt;verify_()
&amp;&amp; (m_state.uint == static_cast&lt;std::uintptr_t&gt;(~m_temp.uint)));
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s); // the current state
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// process the event hierarchically...
QState r;
m_temp.fun = s;
2024-07-19 19:23:03 -04:00
std::int_fast8_t ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
2022-08-11 15:36:19 -04:00
do {
s = m_temp.fun;
r = (*s)(this, e); // invoke state handler s
if (r == Q_RET_UNHANDLED) { // unhandled due to a guard?
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId)
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s); // the current state
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s
2022-08-11 15:36:19 -04:00
}
2024-04-24 09:13:46 -04:00
--ip;
} while ((r == Q_RET_SUPER) &amp;&amp; (ip &gt; 0));
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
Q_ENSURE_INCRIT(310, ip &gt; 0);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (r &gt;= Q_RET_TRAN) { // tran. (regular or history) taken?
#ifdef Q_SPY
if (r == Q_RET_TRAN_HIST) { // tran. to history?
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s); // tran. to history source
QS_FUN_PRE(m_temp.fun); // tran. to history target
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
}
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QStateHandler path[QHSM_MAX_NEST_DEPTH_];
path[0] = m_temp.fun; // tran. target
path[1] = t; // current state
path[2] = s; // tran. source
2022-08-11 15:36:19 -04:00
// exit current state to tran. source s...
2024-07-19 19:23:03 -04:00
ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
2024-04-24 09:13:46 -04:00
for (; (t != s) &amp;&amp; (ip &gt; 0); t = m_temp.fun) {
// exit from t
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {
2024-01-17 07:50:09 -05:00
QS_STATE_EXIT_(t, qsId);
2022-08-11 15:36:19 -04:00
// find superstate of t
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
2022-08-11 15:36:19 -04:00
}
2024-04-24 09:13:46 -04:00
--ip;
2022-08-11 15:36:19 -04:00
}
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
Q_ENSURE_INCRIT(320, ip &gt; 0);
QF_CRIT_EXIT();
2024-10-15 13:15:28 -04:00
ip = hsm_tran(&amp;path[0], qsId); // take the tran.
2022-08-11 15:36:19 -04:00
// execute state entry actions in the desired order...
2024-04-24 09:13:46 -04:00
// note: ip is the fixed upper loop bound
2022-08-11 15:36:19 -04:00
for (; ip &gt;= 0; --ip) {
// enter path[ip]
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
== Q_RET_HANDLED)
{
2024-01-17 07:50:09 -05:00
QS_STATE_ENTRY_(path[ip], qsId);
}
2022-08-11 15:36:19 -04:00
}
t = path[0]; // stick the target into register
m_temp.fun = t; // update the next state
// drill into the target hierarchy...
while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) {
2022-08-11 15:36:19 -04:00
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(t); // the source (pseudo)state
QS_FUN_PRE(m_temp.fun); // the target of the tran.
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
ip = 0;
path[0] = m_temp.fun;
// find superstate
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
2022-08-11 15:36:19 -04:00
2024-04-24 09:13:46 -04:00
// note: ip is the fixed upper loop bound
2024-07-19 19:23:03 -04:00
while ((m_temp.fun != t) &amp;&amp; (ip &lt; (QHSM_MAX_NEST_DEPTH_ - 1))) {
2022-08-11 15:36:19 -04:00
++ip;
path[ip] = m_temp.fun;
// find superstate
2022-11-17 14:13:33 -05:00
static_cast&lt;void&gt;(
QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
2022-08-11 15:36:19 -04:00
}
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
// too many state nesting levels or &quot;malformed&quot; HSM
2024-07-19 19:23:03 -04:00
Q_ENSURE_INCRIT(330, ip &lt; QHSM_MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
m_temp.fun = path[0];
2022-08-11 15:36:19 -04:00
// retrace the entry path in reverse (correct) order...
2024-04-24 09:13:46 -04:00
// note: ip is the fixed upper loop bound
2022-08-11 15:36:19 -04:00
do {
// enter path[ip]
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
== Q_RET_HANDLED)
{
2024-01-17 07:50:09 -05:00
QS_STATE_ENTRY_(path[ip], qsId);
}
2022-08-11 15:36:19 -04:00
--ip;
} while (ip &gt;= 0);
t = path[0]; // current state becomes the new source
2022-08-11 15:36:19 -04:00
}
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_TRAN, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s); // the source of the tran.
QS_FUN_PRE(t); // the new active state
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
#ifdef Q_SPY
else if (r == Q_RET_HANDLED) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s); // the source state
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
else {
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_IGNORED, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(m_state.fun); // the current state
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
#endif // Q_SPY
m_state.fun = t; // change the current active state
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QHsm::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x00">
2023-12-14 16:55:58 -05:00
<specifiers>noexcept override</specifiers>
<!--${QEP::QHsm::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
Q_INVARIANT_INCRIT(602,
m_state.uint == static_cast&lt;std::uintptr_t&gt;(~m_temp.uint));
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
bool inState = false; // assume that this HSM is not in 'state'
2022-08-11 15:36:19 -04:00
// scan the state hierarchy bottom-up
2023-12-11 20:51:27 -05:00
QStateHandler s = m_state.fun;
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_ + 1; // fixed upper loop bound
2023-12-11 20:51:27 -05:00
QState r = Q_RET_SUPER;
2024-04-24 09:13:46 -04:00
for (; (r != Q_RET_IGNORED) &amp;&amp; (lbound &gt; 0); --lbound) {
2023-12-11 20:51:27 -05:00
if (s == state) { // do the states match?
inState = true; // 'true' means that match found
break; // break out of the for-loop
2022-08-11 15:36:19 -04:00
}
else {
2023-12-11 20:51:27 -05:00
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG);
s = m_temp.fun;
2022-08-11 15:36:19 -04:00
}
2023-12-11 20:51:27 -05:00
}
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
Q_ENSURE_INCRIT(690, lbound &gt; 0);
2023-12-11 20:51:27 -05:00
QF_CRIT_EXIT();
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif
2022-08-11 15:36:19 -04:00
return inState; // return the status</code>
</operation>
<!--${QEP::QHsm::childState}-->
<operation name="childState" type="QStateHandler" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QEP::QHsm::childState::parent}-->
<parameter name="parent" type="QStateHandler const"/>
2024-04-24 09:13:46 -04:00
<code>QStateHandler child = m_state.fun; // start with current state
2022-08-11 15:36:19 -04:00
bool isFound = false; // start with the child not found
// establish stable state configuration
m_temp.fun = child;
2022-08-11 15:36:19 -04:00
QState r;
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
2022-08-11 15:36:19 -04:00
do {
// is this the parent of the current child?
if (m_temp.fun == parent) {
isFound = true; // child is found
r = Q_RET_IGNORED; // break out of the loop
2022-08-11 15:36:19 -04:00
}
else {
child = m_temp.fun;
r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
2022-08-11 15:36:19 -04:00
}
2024-04-24 09:13:46 -04:00
--lbound;
2024-10-15 13:15:28 -04:00
} while ((r != Q_RET_IGNORED) // the top state not reached
2024-04-24 09:13:46 -04:00
&amp;&amp; (lbound &gt; 0));
2022-08-11 15:36:19 -04:00
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
2024-06-12 16:30:04 -04:00
#else
Q_UNUSED_PAR(isFound);
2022-08-11 15:36:19 -04:00
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 0), so no extra check is necessary.
Q_ENSURE_INCRIT(890, isFound);
QF_CRIT_EXIT();
2024-04-24 09:13:46 -04:00
return child;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QHsm::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x06">
<specifiers>noexcept override</specifiers>
<code>return m_state.fun;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QHsm::hsm_tran}-->
<operation name="hsm_tran" type="std::int_fast8_t" visibility="0x02" properties="0x00">
2024-07-19 19:23:03 -04:00
<!--${QEP::QHsm::hsm_tran::path}-->
<parameter name="path" type="QStateHandler * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QHsm::hsm_tran::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
2022-11-17 14:13:33 -05:00
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
2022-11-17 14:13:33 -05:00
#endif
std::int_fast8_t ip = -1; // tran. entry path index
2022-08-11 15:36:19 -04:00
QStateHandler t = path[0];
QStateHandler const s = path[2];
QF_CRIT_STAT
2022-08-11 15:36:19 -04:00
// (a) check source==target (tran. to self)...
2022-08-11 15:36:19 -04:00
if (s == t) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
2024-01-17 07:50:09 -05:00
QS_STATE_EXIT_(s, qsId);
}
2022-08-11 15:36:19 -04:00
ip = 0; // enter the target
}
else {
// find superstate of target
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
2022-08-11 15:36:19 -04:00
t = m_temp.fun;
// (b) check source==target-&gt;super...
2022-08-11 15:36:19 -04:00
if (s == t) {
ip = 0; // enter the target
}
else {
// find superstate of src
static_cast&lt;void&gt;(QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG));
2022-08-11 15:36:19 -04:00
// (c) check source-&gt;super==target-&gt;super...
2022-08-11 15:36:19 -04:00
if (m_temp.fun == t) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
2024-01-17 07:50:09 -05:00
QS_STATE_EXIT_(s, qsId);
}
2022-08-11 15:36:19 -04:00
ip = 0; // enter the target
}
else {
// (d) check source-&gt;super==target...
2022-08-11 15:36:19 -04:00
if (m_temp.fun == path[0]) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
2024-01-17 07:50:09 -05:00
QS_STATE_EXIT_(s, qsId);
}
2022-08-11 15:36:19 -04:00
}
else {
// (e) check rest of source==target-&gt;super-&gt;super..
// and store the entry path along the way
std::int_fast8_t iq = 0; // indicate that LCA was found
ip = 1; // enter target and its superstate
path[1] = t; // save the superstate of target
t = m_temp.fun; // save source-&gt;super
2022-08-11 15:36:19 -04:00
// find target-&gt;super-&gt;super...
2024-04-24 09:13:46 -04:00
// note: ip is the fixed upper loop bound
QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG);
while ((r == Q_RET_SUPER)
2024-07-19 19:23:03 -04:00
&amp;&amp; (ip &lt; (QHSM_MAX_NEST_DEPTH_ - 1)))
{
2022-08-11 15:36:19 -04:00
++ip;
path[ip] = m_temp.fun; // store the entry path
if (m_temp.fun == s) { // is it the source?
iq = 1; // indicate that the LCA found
--ip; // do not enter the source
2022-08-11 15:36:19 -04:00
r = Q_RET_HANDLED; // terminate the loop
}
else { // it is not the source, keep going up
r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
2022-08-11 15:36:19 -04:00
}
}
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
// NOTE: The following postcondition succeeds only when
// ip &lt; QHSM_MAX_NEST_DEPTH, so no additional check is necessary
// too many state nesting levels or &quot;malformed&quot; HSM.
Q_ENSURE_INCRIT(510, r != Q_RET_SUPER);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// the LCA not found yet?
if (iq == 0) {
// exit source s
if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG)
== Q_RET_HANDLED)
{
2024-01-17 07:50:09 -05:00
QS_STATE_EXIT_(s, qsId);
}
2022-08-11 15:36:19 -04:00
// (f) check the rest of source-&gt;super
// == target-&gt;super-&gt;super...
iq = ip;
r = Q_RET_IGNORED; // indicate that the LCA NOT found
2024-04-24 09:13:46 -04:00
// note: iq is the fixed upper loop bound
2022-08-11 15:36:19 -04:00
do {
if (t == path[iq]) { // is this the LCA?
r = Q_RET_HANDLED; // indicate the LCA found
ip = iq - 1; // do not enter the LCA
2022-08-11 15:36:19 -04:00
iq = -1; // cause termination of the loop
}
else {
--iq; // try lower superstate of target
}
} while (iq &gt;= 0);
// the LCA not found yet?
2022-08-11 15:36:19 -04:00
if (r != Q_RET_HANDLED) {
// (g) check each source-&gt;super-&gt;...
// for each target-&gt;super...
r = Q_RET_IGNORED; // keep looping
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_;
2022-08-11 15:36:19 -04:00
do {
// exit from t
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG)
== Q_RET_HANDLED)
{
2024-01-17 07:50:09 -05:00
QS_STATE_EXIT_(t, qsId);
2022-11-17 14:13:33 -05:00
// find superstate of t
static_cast&lt;void&gt;(
QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
2022-08-11 15:36:19 -04:00
}
t = m_temp.fun; // set to super of t
2022-08-11 15:36:19 -04:00
iq = ip;
do {
// is this the LCA?
2022-08-11 15:36:19 -04:00
if (t == path[iq]) {
ip = iq - 1; // do not enter the LCA
iq = -1; // break out of inner loop
2022-08-11 15:36:19 -04:00
r = Q_RET_HANDLED; // break outer loop
}
else {
--iq;
}
} while (iq &gt;= 0);
2024-04-24 09:13:46 -04:00
--lbound;
} while ((r != Q_RET_HANDLED) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
2024-07-19 19:23:03 -04:00
Q_ENSURE_INCRIT(530, lbound &gt; 0);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
}
}
}
}
}
QF_CRIT_ENTRY();
2024-07-19 19:23:03 -04:00
Q_ENSURE_INCRIT(590, ip &lt; QHSM_MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
return ip;</code>
2022-08-11 15:36:19 -04:00
</operation>
</class>
<!--${QEP::QMsm}-->
<class name="QMsm" superclass="QEP::QAsm">
<documentation>Machine-generated State Machine</documentation>
<!--${QEP::QMsm::QMsm}-->
<operation name="QMsm" type="explicit" visibility="0x01" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QEP::QMsm::QMsm::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code> : QAsm()
m_state.obj = &amp;l_msm_top_s; // the current state (top)
m_temp.fun = initial; // the initial tran. handler</code>
</operation>
2022-08-11 15:36:19 -04:00
<!--${QEP::QMsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
<!--${QEP::QMsm::init::e}-->
<parameter name="e" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QMsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(200, (m_temp.fun != nullptr)
&amp;&amp; (m_state.obj == &amp;l_msm_top_s));
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// execute the top-most initial tran.
QState r = (*m_temp.fun)(this, Q_EVT_CAST(QEvt));
QF_CRIT_ENTRY();
// the top-most initial tran. must be taken
Q_ASSERT_INCRIT(210, r == Q_RET_TRAN_INIT);
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(m_state.obj-&gt;stateHandler); // source state
QS_FUN_PRE(m_temp.tatbl-&gt;target-&gt;stateHandler); // target state
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// set state to the last tran. target
m_state.obj = m_temp.tatbl-&gt;target;
// drill down into the state hierarchy with initial transitions...
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
2022-08-11 15:36:19 -04:00
do {
// execute the tran. table
2024-01-17 07:50:09 -05:00
r = execTatbl_(m_temp.tatbl, qsId);
2024-04-24 09:13:46 -04:00
--lbound;
} while ((r &gt;= Q_RET_TRAN_INIT) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
Q_ENSURE_INCRIT(290, lbound &gt; 0);
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId)
QS_TIME_PRE(); // time stamp
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(m_state.obj-&gt;stateHandler); // the new current state
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QMsm::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
2024-01-17 07:50:09 -05:00
<!--${QEP::QMsm::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QMsm::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x04">
<specifiers>override</specifiers>
<!--${QEP::QMsm::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QMsm::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QMState const *s = m_state.obj; // store the current state
QMState const *t = s;
2022-08-11 15:36:19 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(300, (e != nullptr) &amp;&amp; (s != nullptr));
Q_INVARIANT_INCRIT(301,
e-&gt;verify_()
&amp;&amp; (m_state.uint == static_cast&lt;std::uintptr_t&gt;(~m_temp.uint)));
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s-&gt;stateHandler); // the current state handler
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// scan the state hierarchy up to the top state...
QState r;
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
2022-08-11 15:36:19 -04:00
do {
r = (*t-&gt;stateHandler)(this, e); // call state handler function
// event handled? (the most frequent case)
if (r &gt;= Q_RET_HANDLED) {
break; // done scanning the state hierarchy
}
// event unhandled and passed to the superstate?
else if (r == Q_RET_SUPER) {
t = t-&gt;superstate; // advance to the superstate
}
2024-08-28 03:05:23 -04:00
else { // event unhandled due to a guard
QF_CRIT_ENTRY();
// event must be unhandled due to a guard evaluating to 'false'
Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED);
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId)
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(t-&gt;stateHandler); // the current state
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
t = t-&gt;superstate; // advance to the superstate
}
2024-04-24 09:13:46 -04:00
--lbound;
} while ((t != nullptr) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
2024-07-19 19:23:03 -04:00
Q_ENSURE_INCRIT(320, lbound &gt; 0);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
if (r &gt;= Q_RET_TRAN) { // any kind of tran. taken?
QF_CRIT_ENTRY();
// the tran. source state must not be nullptr
2024-10-15 13:15:28 -04:00
Q_ASSERT_INCRIT(330, t != nullptr);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
#ifdef Q_SPY
2024-10-15 13:15:28 -04:00
QMState const * const ts = t; // for saving tran. table
2022-08-11 15:36:19 -04:00
#endif // Q_SPY
2024-10-15 13:15:28 -04:00
QMTranActTable const *tatbl;
if (r == Q_RET_TRAN_HIST) { // was it tran. to history?
QMState const * const hist = m_state.obj; // save history
m_state.obj = s; // restore the original state
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(t-&gt;stateHandler); // source state handler
QS_FUN_PRE(hist-&gt;stateHandler); // target state handler
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
// save the tran-action table before it gets clobbered
tatbl = m_temp.tatbl;
exitToTranSource_(s, t, qsId);
static_cast&lt;void&gt;(execTatbl_(tatbl, qsId));
r = enterHistory_(hist, qsId);
s = m_state.obj;
t = s; // set target to the current state
}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
while ((r &gt;= Q_RET_TRAN) &amp;&amp; (lbound &gt; 0)) {
// save the tran-action table before it gets clobbered
tatbl = m_temp.tatbl;
m_temp.obj = nullptr; // clear
exitToTranSource_(s, t, qsId);
r = execTatbl_(tatbl, qsId);
s = m_state.obj;
2022-08-11 15:36:19 -04:00
t = s; // set target to the current state
2024-10-15 13:15:28 -04:00
--lbound;
}
2022-08-11 15:36:19 -04:00
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
Q_ENSURE_INCRIT(360, lbound &gt; 0);
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_TRAN, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(ts-&gt;stateHandler); // the tran. source
QS_FUN_PRE(s-&gt;stateHandler); // the new active state
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
#ifdef Q_SPY
// was the event handled?
else if (r == Q_RET_HANDLED) {
QF_CRIT_ENTRY();
2022-08-11 15:36:19 -04:00
// internal tran. source can't be nullptr
2024-07-19 19:23:03 -04:00
Q_ASSERT_INCRIT(380, t != nullptr);
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(t-&gt;stateHandler); // the source state
QS_END_PRE()
QS_MEM_APP();
2022-08-11 15:36:19 -04:00
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
// event bubbled to the 'top' state?
else if (t == nullptr) {
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_IGNORED, qsId)
QS_TIME_PRE(); // time stamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s-&gt;stateHandler); // the current state
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
#endif // Q_SPY
else {
// empty
}
#ifndef Q_UNSAFE
m_temp.uint = ~m_state.uint;
#endif</code>
</operation>
<!--${QEP::QMsm::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<code>return m_state.obj-&gt;stateHandler;</code>
2022-08-11 15:36:19 -04:00
</operation>
2023-12-14 16:55:58 -05:00
<!--${QEP::QMsm::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept override</specifiers>
<!--${QEP::QMsm::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>bool inState = false; // assume that this SM is not in 'state'
2023-12-14 16:55:58 -05:00
QMState const *s = m_state.obj;
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
2024-04-24 09:13:46 -04:00
for (; (s != nullptr) &amp;&amp; (lbound &gt; 0); --lbound) {
if (s-&gt;stateHandler == state) { // match found?
2023-12-14 16:55:58 -05:00
inState = true;
break;
}
else {
s = s-&gt;superstate; // advance to the superstate
}
}
QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
Q_ENSURE_INCRIT(490, lbound &gt; 0);
2023-12-14 16:55:58 -05:00
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return inState;</code>
</operation>
<!--${QEP::QMsm::childStateObj}-->
<operation name="childStateObj" type="QMState const *" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QEP::QMsm::childStateObj::parent}-->
<parameter name="parent" type="QMState const * const"/>
<code>QMState const *child = m_state.obj;
bool isFound = false; // start with the child not found
2023-01-06 12:56:50 -05:00
QMState const *s;
2022-08-11 15:36:19 -04:00
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = m_state.obj;
2024-04-24 09:13:46 -04:00
(s != nullptr) &amp;&amp; (lbound &gt; 0);
s = s-&gt;superstate)
{
2022-08-11 15:36:19 -04:00
if (s == parent) {
isFound = true; // child is found
break;
}
else {
child = s;
}
2024-04-24 09:13:46 -04:00
--lbound;
2022-08-11 15:36:19 -04:00
}
QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-07-19 19:23:03 -04:00
Q_ENSURE_INCRIT(680, lbound &gt; 0);
QF_CRIT_EXIT();
2023-01-06 12:56:50 -05:00
if (!isFound) { // still not found?
2024-07-19 19:23:03 -04:00
lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = m_temp.obj;
2024-04-24 09:13:46 -04:00
(s != nullptr) &amp;&amp; (lbound &gt; 0);
s = s-&gt;superstate)
{
2023-01-06 12:56:50 -05:00
if (s == parent) {
isFound = true; // child is found
break;
}
else {
child = s;
}
2024-04-24 09:13:46 -04:00
--lbound;
2023-01-06 12:56:50 -05:00
}
}
2022-08-11 15:36:19 -04:00
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 0), so no extra check is necessary.
Q_ENSURE_INCRIT(690, isFound);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return child; // return the child</code>
</operation>
<!--${QEP::QMsm::execTatbl_}-->
<operation name="execTatbl_" type="QState" visibility="0x02" properties="0x00">
<!--${QEP::QMsm::execTatbl_::tatbl}-->
<parameter name="tatbl" type="QMTranActTable const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QMsm::execTatbl_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
// precondition:
// - the tran-action table pointer must not be NULL
Q_REQUIRE_INCRIT(700, tatbl != nullptr);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
QState r = Q_RET_NULL;
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QMSM_MAX_TRAN_LENGTH_; // fixed upper loop bound
QActionHandler const *a = &amp;tatbl-&gt;act[0];
2024-04-24 09:13:46 -04:00
for (; (*a != nullptr) &amp;&amp; (lbound &gt; 0); ++a) {
2022-08-11 15:36:19 -04:00
r = (*(*a))(this); // call the action through the 'a' pointer
2024-07-19 19:23:03 -04:00
--lbound;
2022-08-11 15:36:19 -04:00
#ifdef Q_SPY
QS_CRIT_ENTRY();
QS_MEM_SYS();
2022-08-11 15:36:19 -04:00
if (r == Q_RET_ENTRY) {
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(m_temp.obj-&gt;stateHandler); // entered state
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
else if (r == Q_RET_EXIT) {
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(m_temp.obj-&gt;stateHandler); // exited state
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
else if (r == Q_RET_TRAN_INIT) {
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(tatbl-&gt;target-&gt;stateHandler); // source
QS_FUN_PRE(m_temp.tatbl-&gt;target-&gt;stateHandler); // target
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
else {
// empty
}
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
#endif // Q_SPY
}
QF_CRIT_ENTRY();
2024-07-19 19:23:03 -04:00
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 0), so no extra check is necessary.
Q_ENSURE_INCRIT(790, *a == nullptr);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
m_state.obj = (r &gt;= Q_RET_TRAN)
? m_temp.tatbl-&gt;target
: tatbl-&gt;target;
return r;</code>
</operation>
<!--${QEP::QMsm::exitToTranSource_}-->
<operation name="exitToTranSource_" type="void" visibility="0x02" properties="0x00">
<!--${QEP::QMsm::exitToTranSource~::cs}-->
<parameter name="cs" type="QMState const * const"/>
2022-08-11 15:36:19 -04:00
<!--${QEP::QMsm::exitToTranSource~::ts}-->
<parameter name="ts" type="QMState const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QMsm::exitToTranSource~::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
// exit states from the current state to the tran. source state
QMState const *s = cs;
2024-07-19 19:23:03 -04:00
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
2024-04-24 09:13:46 -04:00
for (; (s != ts) &amp;&amp; (lbound &gt; 0); --lbound) {
2022-08-11 15:36:19 -04:00
// exit action provided in state 's'?
if (s-&gt;exitAction != nullptr) {
// execute the exit action
static_cast&lt;void&gt;((*s-&gt;exitAction)(this));
2022-08-11 15:36:19 -04:00
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(s-&gt;stateHandler); // the exited state handler
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
s = s-&gt;superstate; // advance to the superstate
}
QF_CRIT_ENTRY();
2024-04-24 09:13:46 -04:00
Q_ENSURE_INCRIT(890, lbound &gt; 0);
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP::QMsm::enterHistory_}-->
<operation name="enterHistory_" type="QState" visibility="0x02" properties="0x00">
<!--${QEP::QMsm::enterHistory_::hist}-->
<parameter name="hist" type="QMState const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QEP::QMsm::enterHistory_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
2024-10-15 13:15:28 -04:00
// record the entry path from current state to history
2024-07-19 19:23:03 -04:00
QMState const *epath[QMSM_MAX_ENTRY_DEPTH_];
2024-10-15 13:15:28 -04:00
QMState const *s = hist;
std::int_fast8_t i = 0; // tran. entry path index
2024-10-15 13:15:28 -04:00
while ((s != m_state.obj) &amp;&amp; (i &lt; (QMSM_MAX_ENTRY_DEPTH_ - 1))) {
2022-08-11 15:36:19 -04:00
if (s-&gt;entryAction != nullptr) {
epath[i] = s;
++i;
}
s = s-&gt;superstate;
}
2024-10-15 13:15:28 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
Q_ASSERT_INCRIT(910, s == m_state.obj);
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// retrace the entry path in reverse (desired) order...
while (i &gt; 0) {
--i;
(*epath[i]-&gt;entryAction)(this); // run entry action in epath[i]
2022-08-11 15:36:19 -04:00
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId)
QS_OBJ_PRE(this);
QS_FUN_PRE(epath[i]-&gt;stateHandler); // entered state handler
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
m_state.obj = hist; // set current state to the tran. target
2022-08-11 15:36:19 -04:00
// initial tran. present?
QState r;
if (hist-&gt;initAction != nullptr) {
r = (*hist-&gt;initAction)(this); // execute the tran. action
2024-10-15 13:15:28 -04:00
QS_CRIT_ENTRY();
QS_MEM_SYS();
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
QS_OBJ_PRE(this); // this state machine object
QS_FUN_PRE(hist-&gt;stateHandler); // source
QS_FUN_PRE(m_temp.tatbl-&gt;target-&gt;stateHandler); // target
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
else {
r = Q_RET_NULL;
}
return r;</code>
</operation>
<!--${QEP::QMsm::topQMState}-->
<operation name="topQMState" type="QMState const *" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>return &amp;l_msm_top_s;</code>
</operation>
2022-08-11 15:36:19 -04:00
</class>
</package>
<!--${QEP-macros}-->
<package name="QEP-macros" stereotype="0x02">
<!--${QEP-macros::Q_STATE_DECL}-->
<operation name="Q_STATE_DECL" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_STATE_DECL::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
<code>\
QP::QState state_ ## _h(QP::QEvt const * const e); \
static QP::QState state_(void * const me, QP::QEvt const * const e)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::Q_STATE_DEF}-->
<operation name="Q_STATE_DEF" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_STATE_DEF::subclass_}-->
<parameter name="subclass_" type="&lt;QHsm subclass&gt;"/>
<!--${QEP-macros::Q_STATE_DEF::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
2022-08-11 15:36:19 -04:00
<code>\
QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) { \
return static_cast&lt;subclass_ *&gt;(me)-&gt;state_ ## _h(e); } \
QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::Q_HANDLED}-->
<operation name="Q_HANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_HANDLED)</code>
</operation>
<!--${QEP-macros::Q_UNHANDLED}-->
<operation name="Q_UNHANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_UNHANDLED)</code>
</operation>
<!--${QEP-macros::Q_EVT_CAST}-->
<operation name="Q_EVT_CAST" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_EVT_CAST::subclass_}-->
<parameter name="subclass_" type="&lt;QEvt subclass&gt;"/>
<code>(static_cast&lt;subclass_ const *&gt;(e))</code>
</operation>
<!--${QEP-macros::Q_STATE_CAST}-->
<operation name="Q_STATE_CAST" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_STATE_CAST::handler_}-->
<parameter name="handler_" type="&lt;state handler&gt;"/>
2022-08-11 15:36:19 -04:00
<code>\
(reinterpret_cast&lt;QP::QStateHandler&gt;(handler_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_STATE_DECL}-->
<operation name="QM_STATE_DECL" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_STATE_DECL::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
<code>\
QP::QState state_ ## _h(QP::QEvt const * const e); \
static QP::QState state_(void * const me, QP::QEvt const * const e); \
static QP::QMState const state_ ## _s</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_ACTION_DECL}-->
<operation name="QM_ACTION_DECL" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_ACTION_DECL::action_}-->
<parameter name="action_" type="&lt;predefined&gt;"/>
<code>\
QP::QState action_ ## _h(); \
static QP::QState action_(void * const me)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_STATE_DEF}-->
<operation name="QM_STATE_DEF" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_STATE_DEF::subclass_}-->
<parameter name="subclass_" type="&lt;QMsm subclass&gt;"/>
<!--${QEP-macros::QM_STATE_DEF::state_}-->
<parameter name="state_" type="&lt;state name&gt;"/>
2022-08-11 15:36:19 -04:00
<code>\
QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) {\
return static_cast&lt;subclass_ *&gt;(me)-&gt;state_ ## _h(e); } \
QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_ACTION_DEF}-->
<operation name="QM_ACTION_DEF" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::QM_ACTION_DEF::subclass_}-->
<parameter name="subclass_" type="&lt;QMsm subclass&gt;"/>
<!--${QEP-macros::QM_ACTION_DEF::action_}-->
<parameter name="action_" type="&lt;predefined&gt;"/>
<code> \
QP::QState subclass_::action_(void * const me) { \
return static_cast&lt;subclass_ *&gt;(me)-&gt;action_ ## _h(); } \
QP::QState subclass_::action_ ## _h()</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_HANDLED}-->
<operation name="QM_HANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_HANDLED)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_UNHANDLED}-->
<operation name="QM_UNHANDLED" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_HANDLED)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_SUPER}-->
<operation name="QM_SUPER" type="" visibility="0x03" properties="0x00">
<code>(Q_RET_SUPER)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::QM_STATE_NULL}-->
<attribute name="QM_STATE_NULL" type="&lt;action handler&gt;" visibility="0x03" properties="0x00">
<code>(nullptr)</code>
</attribute>
<!--${QEP-macros::Q_ACTION_NULL}-->
<attribute name="Q_ACTION_NULL" type="&lt;action handler&gt;" visibility="0x03" properties="0x00">
<code>(nullptr)</code>
</attribute>
<!--${QEP-macros::Q_UNUSED_PAR}-->
<operation name="Q_UNUSED_PAR" type="&lt;param type&gt;" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_UNUSED_PAR::par_}-->
<parameter name="par_" type="&lt;param type&gt;"/>
<code>(static_cast&lt;void&gt;(par_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::Q_DIM}-->
<operation name="Q_DIM" type="unsigned" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_DIM::array_}-->
<parameter name="array_" type="1-dimensional array"/>
<code>(sizeof(array_) / sizeof((array_)[0U]))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::Q_UINT2PTR_CAST}-->
<operation name="Q_UINT2PTR_CAST" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::Q_UINT2PTR_CAST::type_}-->
<parameter name="type_" type=""/>
<!--${QEP-macros::Q_UINT2PTR_CAST::uint_}-->
<parameter name="uint_" type=""/>
<code>(reinterpret_cast&lt;type_ *&gt;(uint_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::INIT}-->
<operation name="INIT?def Q_SPY" type="" visibility="0x03" properties="0x00">
2024-01-17 07:50:09 -05:00
<!--${QEP-macros::INIT::qsId_}-->
<parameter name="qsId_" type="std::uint8_fast8_t"/>
<code>init((qsId_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QEP-macros::INIT}-->
<operation name="INIT?ndef Q_SPY" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::INIT::dummy}-->
<parameter name="dummy" type="std::uint8_fast8_t"/>
<code>init(0U)</code>
</operation>
<!--${QEP-macros::DISPATCH}-->
<operation name="DISPATCH?def Q_SPY" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::DISPATCH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
2024-01-17 07:50:09 -05:00
<!--${QEP-macros::DISPATCH::qsId_}-->
<parameter name="qsId_" type="std::uint8_fast8_t"/>
<code>dispatch((e_), (qsId_))</code>
</operation>
<!--${QEP-macros::DISPATCH}-->
<operation name="DISPATCH?ndef Q_SPY" type="" visibility="0x03" properties="0x00">
<!--${QEP-macros::DISPATCH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QEP-macros::DISPATCH::dummy}-->
<parameter name="dummy" type="std::uint8_fast8_t"/>
<code>dispatch((e_), 0U)</code>
2022-08-28 22:12:27 -04:00
</operation>
2022-08-11 15:36:19 -04:00
</package>
<!--${QF}-->
<package name="QF" stereotype="0x05" namespace="QP::">
<!--${QF::types}-->
<package name="types" stereotype="0x02">
<!--${QF::types::QPrioSpec}-->
<attribute name="QPrioSpec" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
2022-08-11 15:36:19 -04:00
</attribute>
2024-10-15 13:15:28 -04:00
<!--${QF::types::QEvtPtr}-->
<attribute name="QEvtPtr" type="using" visibility="0x04" properties="0x00">
<code>= QEvt const *;</code>
</attribute>
<!--${QF::types::QTimeEvtCtr}-->
<attribute name="QTimeEvtCtr? (QF_TIMEEVT_CTR_SIZE == 1U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint8_t;</code>
2022-08-11 15:36:19 -04:00
</attribute>
<!--${QF::types::QTimeEvtCtr}-->
<attribute name="QTimeEvtCtr? (QF_TIMEEVT_CTR_SIZE == 2U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QF::types::QTimeEvtCtr}-->
<attribute name="QTimeEvtCtr? (QF_TIMEEVT_CTR_SIZE == 4U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QF::types::QPSetBits}-->
<attribute name="QPSetBits? (QF_MAX_ACTIVE &lt;= 8U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint8_t;</code>
</attribute>
<!--${QF::types::QPSetBits}-->
<attribute name="QPSetBits? (8U &lt; QF_MAX_ACTIVE) &amp;&amp; (QF_MAX_ACTIVE &lt;= 16U)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint16_t;</code>
</attribute>
<!--${QF::types::QPSetBits}-->
<attribute name="QPSetBits? (16 &lt; QF_MAX_ACTIVE)" type="using" visibility="0x04" properties="0x00">
<code>= std::uint32_t;</code>
</attribute>
<!--${QF::types::QF_LOG2}-->
2022-08-11 15:36:19 -04:00
<operation name="QF_LOG2?ndef QF_LOG2" type="std::uint_fast8_t" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::types::QF_LOG2::x}-->
2022-08-11 15:36:19 -04:00
<parameter name="x" type="QP::QPSetBits"/>
<code>static std::uint8_t const log2LUT[16] = {
0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U,
4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U
};
std::uint_fast8_t n = 0U;
QP::QPSetBits t;
#if (QF_MAX_ACTIVE &gt; 16U)
t = static_cast&lt;QP::QPSetBits&gt;(x &gt;&gt; 16U);
if (t != 0U) {
n += 16U;
x = t;
}
#endif
#if (QF_MAX_ACTIVE &gt; 8U)
t = (x &gt;&gt; 8U);
if (t != 0U) {
n += 8U;
x = t;
}
#endif
t = (x &gt;&gt; 4U);
if (t != 0U) {
n += 4U;
x = t;
}
return n + log2LUT[x];</code>
</operation>
<!--${QF::types::QPSet}-->
<class name="QPSet">
<!--${QF::types::QPSet::m_bits[((QF_MAX_ACTIVE + (8U*siz~}-->
<attribute name="m_bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U)/(8U*sizeof(QPSetBits))]" type="QPSetBits" visibility="0x02" properties="0x00"/>
<!--${QF::types::QPSet::setEmpty}-->
<operation name="setEmpty" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code>m_bits[0] = 0U;
#if (QF_MAX_ACTIVE &gt; 32)
m_bits[1] = 0U;
#endif</code>
</operation>
<!--${QF::types::QPSet::isEmpty}-->
<operation name="isEmpty" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return (m_bits[0] == 0U);
#else
return (m_bits[0] == 0U) ? (m_bits[1] == 0U) : false;
#endif</code>
</operation>
<!--${QF::types::QPSet::notEmpty}-->
<operation name="notEmpty" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return (m_bits[0] != 0U);
#else
return (m_bits[0] != 0U) ? true : (m_bits[1] != 0U);
#endif</code>
</operation>
<!--${QF::types::QPSet::hasElement}-->
<operation name="hasElement" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::types::QPSet::hasElement::n}-->
<parameter name="n" type="std::uint_fast8_t const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return (m_bits[0] &amp; (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U))) != 0U;
#else
return (n &lt;= 32U)
? ((m_bits[0] &amp; (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U))) != 0U)
: ((m_bits[1] &amp; (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 33U))) != 0U);
#endif</code>
</operation>
<!--${QF::types::QPSet::insert}-->
<operation name="insert" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::types::QPSet::insert::n}-->
<parameter name="n" type="std::uint_fast8_t const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
m_bits[0] = (m_bits[0] | (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U)));
#else
if (n &lt;= 32U) {
m_bits[0] = (m_bits[0] | (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U)));
}
else {
m_bits[1] = (m_bits[1] | (static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 33U)));
}
#endif</code>
</operation>
<!--${QF::types::QPSet::remove}-->
<operation name="remove" type="void" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::types::QPSet::remove::n}-->
<parameter name="n" type="std::uint_fast8_t const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
m_bits[0] = (m_bits[0] &amp; static_cast&lt;QPSetBits&gt;(~(1U &lt;&lt; (n - 1U))));
#else
if (n &lt;= 32U) {
(m_bits[0] = (m_bits[0] &amp; ~(static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 1U))));
}
else {
(m_bits[1] = (m_bits[1] &amp; ~(static_cast&lt;QPSetBits&gt;(1U) &lt;&lt; (n - 33U))));
}
#endif</code>
</operation>
<!--${QF::types::QPSet::findMax}-->
<operation name="findMax" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return QF_LOG2(m_bits[0]);
#else
return (m_bits[1] != 0U)
? (QF_LOG2(m_bits[1]) + 32U)
: (QF_LOG2(m_bits[0]));
#endif</code>
</operation>
<!--${QF::types::QPSet::update_}-->
<operation name="update_?ndef Q_UNSAFE" type="void" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::types::QPSet::update_::dis}-->
<parameter name="dis" type="QPSet * const"/>
<code>dis-&gt;m_bits[0] = ~m_bits[0];
#if (QF_MAX_ACTIVE &gt; 32U)
dis-&gt;m_bits[1] = ~m_bits[1];
#endif</code>
</operation>
<!--${QF::types::QPSet::verify_}-->
<operation name="verify_?ndef Q_UNSAFE" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<!--${QF::types::QPSet::verify_::dis}-->
<parameter name="dis" type="QPSet const * const"/>
<code>#if (QF_MAX_ACTIVE &lt;= 32U)
return m_bits[0] == static_cast&lt;QPSetBits&gt;(~dis-&gt;m_bits[0]);
#else
return (m_bits[0] == static_cast&lt;QPSetBits&gt;(~dis-&gt;m_bits[0]))
&amp;&amp; (m_bits[1] == static_cast&lt;QPSetBits&gt;(~dis-&gt;m_bits[1]));
#endif</code>
</operation>
</class>
<!--${QF::types::QSubscrList}-->
<class name="QSubscrList">
<!--${QF::types::QSubscrList::m_set}-->
<attribute name="m_set" type="QPSet" visibility="0x02" properties="0x00"/>
<!--${QF::types::QSubscrList::m_set_dis}-->
<attribute name="m_set_dis?ndef Q_UNSAFE" type="QPSet" visibility="0x02" properties="0x00"/>
<!--${QF::types::QSubscrList::QActive}-->
<attribute name="QActive" type="friend class" visibility="0x02" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
</class>
2024-10-15 13:15:28 -04:00
<!--${QF::types::QPtrDis}-->
<class name="QPtrDis">
<!--${QF::types::QPtrDis::m_ptr_dis}-->
<attribute name="m_ptr_dis" type="std::uintptr_t" visibility="0x02" properties="0x00"/>
<!--${QF::types::QPtrDis::QTimeEvt}-->
<attribute name="QTimeEvt" type="friend class" visibility="0x02" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
<!--${QF::types::QPtrDis::QXThread}-->
<attribute name="QXThread" type="friend class" visibility="0x02" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
<!--${QF::types::QPtrDis::QPtrDis}-->
<operation name="QPtrDis" type="" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::types::QPtrDis::QPtrDis::ptr = nullptr}-->
<parameter name="ptr = nullptr" type="void const * const"/>
<code> : m_ptr_dis(static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(ptr)))</code>
</operation>
</class>
<!--${QF::types::QEQueue}-->
<attribute name="QEQueue" type="class" visibility="0x04" properties="0x00"/>
</package>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive}-->
<class name="QActive" superclass="QEP::QAsm">
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::m_prio}-->
<attribute name="m_prio" type="std::uint8_t" visibility="0x01" properties="0x00"/>
2022-08-28 22:12:27 -04:00
<!--${QF::QActive::m_pthre}-->
<attribute name="m_pthre" type="std::uint8_t" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_thread}-->
<attribute name="m_thread?def QACTIVE_THREAD_TYPE" type="QACTIVE_THREAD_TYPE" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_osObject}-->
<attribute name="m_osObject?def QACTIVE_OS_OBJ_TYPE" type="QACTIVE_OS_OBJ_TYPE" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_eQueue}-->
<attribute name="m_eQueue?def QACTIVE_EQUEUE_TYPE" type="QACTIVE_EQUEUE_TYPE" visibility="0x01" properties="0x00"/>
<!--${QF::QActive::m_prio_dis}-->
<attribute name="m_prio_dis?ndef Q_UNSAFE" type="std::uint8_t" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::m_pthre_dis}-->
<attribute name="m_pthre_dis?ndef Q_UNSAFE" type="std::uint8_t" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]}-->
<attribute name="registry_[QF_MAX_ACTIVE + 1U]" type="QActive *" visibility="0x00" properties="0x01"/>
<!--${QF::QActive::subscrList_}-->
<attribute name="subscrList_" type="QSubscrList *" visibility="0x00" properties="0x01"/>
<!--${QF::QActive::maxPubSignal_}-->
<attribute name="maxPubSignal_" type="enum_t" visibility="0x00" properties="0x01"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::QTimeEvt}-->
<attribute name="QTimeEvt" type="friend class" visibility="0x00" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::QTicker}-->
<attribute name="QTicker" type="friend class" visibility="0x00" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::QXThread}-->
<attribute name="QXThread" type="friend class" visibility="0x00" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::QXMutex}-->
<attribute name="QXMutex" type="friend class" visibility="0x00" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::QXSemaphore}-->
<attribute name="QXSemaphore" type="friend class" visibility="0x00" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::QActiveDummy}-->
<attribute name="QActiveDummy" type="friend class" visibility="0x00" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::GuiQActive}-->
<attribute name="GuiQActive" type="friend class" visibility="0x00" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::GuiQMActive}-->
<attribute name="GuiQMActive" type="friend class" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::schedLock()}-->
<attribute name="schedLock()" type="friend void" visibility="0x00" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::QActive}-->
<operation name="QActive" type="explicit" visibility="0x01" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QActive::QActive::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code> : QAsm(),
2022-08-28 22:12:27 -04:00
m_prio(0U),
m_pthre(0U)
2022-08-11 15:36:19 -04:00
m_state.fun = Q_STATE_CAST(&amp;top);
m_temp.fun = initial;
#ifndef Q_UNSAFE
m_prio_dis = static_cast&lt;std::uint8_t&gt;(~m_prio);
m_pthre_dis = static_cast&lt;std::uint8_t&gt;(~m_pthre);
#endif</code>
</operation>
<!--${QF::QActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x02">
<specifiers>override</specifiers>
<!--${QF::QActive::init::e}-->
<parameter name="e" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::init(e, qsId);</code>
</operation>
<!--${QF::QActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
2024-01-17 07:50:09 -05:00
<!--${QF::QActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QF::QActive::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x02">
<specifiers>override</specifiers>
<!--${QF::QActive::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QActive::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::dispatch(e, qsId);</code>
</operation>
2023-12-14 16:55:58 -05:00
<!--${QF::QActive::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<!--${QF::QActive::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>return reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::isIn(state);</code>
</operation>
2024-01-17 07:50:09 -05:00
<!--${QF::QActive::childState}-->
<operation name="childState" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::childState::parent}-->
<parameter name="parent" type="QStateHandler const"/>
<code>return reinterpret_cast&lt;QHsm *&gt;(this)-&gt;QHsm::childState(parent);</code>
</operation>
<!--${QF::QActive::setAttr}-->
<operation name="setAttr" type="void" visibility="0x00" properties="0x00">
<!--${QF::QActive::setAttr::attr1}-->
<parameter name="attr1" type="std::uint32_t"/>
<!--${QF::QActive::setAttr::attr2 = nullptr}-->
<parameter name="attr2 = nullptr" type="void const *"/>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x00">
2022-08-28 22:12:27 -04:00
<!--${QF::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::start::qSto}-->
2024-10-15 13:15:28 -04:00
<parameter name="qSto" type="QEvtPtr * const"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QF::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QF::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QF::QActive::start::par}-->
<parameter name="par" type="void const * const"/>
</operation>
<!--${QF::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x02">
2022-08-28 22:12:27 -04:00
<!--${QF::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::start::qSto}-->
2024-10-15 13:15:28 -04:00
<parameter name="qSto" type="QEvtPtr * const"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QF::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QF::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
2022-08-28 22:12:27 -04:00
<code>this-&gt;start(prioSpec, qSto, qLen, stkSto, stkSize, nullptr);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::stop}-->
<operation name="stop?def QACTIVE_CAN_STOP" type="void" visibility="0x00" properties="0x00"/>
<!--${QF::QActive::register_}-->
<operation name="register_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (m_pthre == 0U) { // preemption-threshold not defined?
m_pthre = m_prio; // apply the default
}
#ifndef Q_UNSAFE
Q_REQUIRE_INCRIT(100, (0U &lt; m_prio) &amp;&amp; (m_prio &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[m_prio] == nullptr)
&amp;&amp; (m_prio &lt;= m_pthre));
std::uint8_t prev_thre = m_pthre;
std::uint8_t next_thre = m_pthre;
std::uint_fast8_t p;
for (p = static_cast&lt;std::uint_fast8_t&gt;(m_prio) - 1U; p &gt; 0U; --p) {
if (registry_[p] != nullptr) {
prev_thre = registry_[p]-&gt;m_pthre;
break;
}
}
for (p = static_cast&lt;std::uint_fast8_t&gt;(m_prio) + 1U;
p &lt;= QF_MAX_ACTIVE; ++p)
{
if (registry_[p] != nullptr) {
next_thre = registry_[p]-&gt;m_pthre;
break;
}
}
Q_ASSERT_INCRIT(190, (prev_thre &lt;= m_pthre)
&amp;&amp; (m_pthre &lt;= next_thre));
m_prio_dis = static_cast&lt;std::uint8_t&gt;(~m_prio);
m_pthre_dis = static_cast&lt;std::uint8_t&gt;(~m_pthre);
#endif // Q_UNSAFE
// register the AO at the QF-prio.
registry_[m_prio] = this;
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QActive::unregister_}-->
<operation name="unregister_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
registry_[p] = nullptr; // free-up the priority level
m_state.fun = nullptr; // invalidate the state
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::post_}-->
<operation name="post_" type="bool" visibility="0x00" properties="0x00">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QActive::post_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QActive::post_::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QActive::post_::sender}-->
<parameter name="sender" type="void const * const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
#endif
#ifdef Q_UTEST // test?
2024-10-15 13:15:28 -04:00
#if (Q_UTEST != 0) // testing QP-stub?
if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
return static_cast&lt;QActiveDummy *&gt;(this)-&gt;fakePost(e, margin, sender);
}
2024-10-15 13:15:28 -04:00
#endif // (Q_UTEST != 0)
#endif // def Q_UTEST
2022-08-11 15:36:19 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(200, e != nullptr);
2024-10-15 13:15:28 -04:00
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
#ifndef Q_UNSAFE
QEQueueCtr dis = static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_nFree_dis);
Q_INVARIANT_INCRIT(201, e-&gt;verify_() &amp;&amp; (tmp == dis));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
// test-probe#1 for faking queue overflow
QS_TEST_PROBE_DEF(&amp;QActive::post_)
QS_TEST_PROBE_ID(1,
2024-10-15 13:15:28 -04:00
tmp = 0U; // fake no free events
2022-08-11 15:36:19 -04:00
)
2024-10-15 13:15:28 -04:00
// required margin available?
2022-08-11 15:36:19 -04:00
bool status;
2022-09-22 11:13:20 -04:00
if (margin == QF::NO_MARGIN) {
2024-10-15 13:15:28 -04:00
if (tmp &gt; 0U) { // free entries available in the queue?
2022-08-11 15:36:19 -04:00
status = true; // can post
}
2024-10-15 13:15:28 -04:00
else { // no free entries available
2022-08-11 15:36:19 -04:00
status = false; // cannot post
2024-10-15 13:15:28 -04:00
// The queue overflows, but QF_NO_MARGIN indicates that
// the &quot;event delivery guarantee&quot; is required.
Q_ERROR_INCRIT(210); // must be able to post the event
2022-08-11 15:36:19 -04:00
}
}
2024-10-15 13:15:28 -04:00
else if (tmp &gt; static_cast&lt;QEQueueCtr&gt;(margin)) {
2022-08-11 15:36:19 -04:00
status = true; // can post
}
2024-10-15 13:15:28 -04:00
else { // the # free entries below the requested margin
2022-08-11 15:36:19 -04:00
status = false; // cannot post, but don't assert
}
// is it a mutable event?
2024-01-17 07:50:09 -05:00
if (e-&gt;getPoolNum_() != 0U) {
2022-11-17 14:13:33 -05:00
QEvt_refCtr_inc_(e); // increment the reference counter
2022-08-11 15:36:19 -04:00
}
if (status) { // can post the event?
2024-10-15 13:15:28 -04:00
--tmp; // one free entry just used up
m_eQueue.m_nFree = tmp; // update the original
#ifndef Q_UNSAFE
m_eQueue.m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (m_eQueue.m_nMin &gt; tmp) {
m_eQueue.m_nMin = tmp; // update minimum so far
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_POST, m_prio)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(sender); // the sender object
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this active object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_EQC_PRE(m_eQueue.m_nMin); // min # free entries
QS_END_PRE()
2022-08-11 15:36:19 -04:00
#ifdef Q_UTEST
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
2022-08-11 15:36:19 -04:00
if (QS_LOC_CHECK_(m_prio)) {
2024-06-12 16:30:04 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
QS::onTestPost(sender, this, e, status);
2024-06-12 16:30:04 -04:00
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
#endif // def Q_UTEST
2024-10-15 13:15:28 -04:00
if (m_eQueue.m_frontEvt == nullptr) { // is the queue empty?
m_eQueue.m_frontEvt = e; // deliver event directly
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(211, m_eQueue.m_frontEvt_dis
== static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr)));
m_eQueue.m_frontEvt_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(e));
#endif // ndef Q_UNSAFE
#ifdef QXK_HPP_
2024-10-15 13:15:28 -04:00
if (m_state.act == nullptr) { // eXtended thread?
QXTHREAD_EQUEUE_SIGNAL_(this); // signal eXtended Thread
}
else {
2024-10-15 13:15:28 -04:00
QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
}
#else
2024-10-15 13:15:28 -04:00
QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
#endif // def QXK_HPP_
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
else { // queue was not empty, insert event into the ring-buffer
tmp = m_eQueue.m_head; // get volatile into temporary
#ifndef Q_UNSAFE
dis = static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_head_dis);
Q_INVARIANT_INCRIT(212, tmp == dis);
#endif // ndef Q_UNSAFE
m_eQueue.m_ring[tmp] = e; // insert e into buffer
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (tmp == 0U) { // need to wrap the head?
tmp = m_eQueue.m_end;
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
--tmp; // advance the head (counter-clockwise)
m_eQueue.m_head = tmp; // update the original
#ifndef Q_UNSAFE
m_eQueue.m_head_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
else { // event cannot be posted
QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, m_prio)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(sender); // the sender object
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this active object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_EQC_PRE(margin); // margin requested
QS_END_PRE()
2022-08-11 15:36:19 -04:00
#ifdef Q_UTEST
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
2022-08-11 15:36:19 -04:00
if (QS_LOC_CHECK_(m_prio)) {
2024-06-12 16:30:04 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
QS::onTestPost(sender, this, e, status);
2024-06-12 16:30:04 -04:00
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
#endif // def Q_USTEST
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
2022-09-09 16:34:14 -04:00
#if (QF_MAX_EPOOL &gt; 0U)
2022-08-11 15:36:19 -04:00
QF::gc(e); // recycle the event to avoid a leak
2024-10-15 13:15:28 -04:00
#endif // (QF_MAX_EPOOL &gt; 0U)
2022-08-11 15:36:19 -04:00
}
return status;</code>
</operation>
<!--${QF::QActive::postLIFO}-->
<operation name="postLIFO" type="void" visibility="0x00" properties="0x00">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QActive::postLIFO::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>#ifdef Q_UTEST // test?
2024-10-15 13:15:28 -04:00
#if (Q_UTEST != 0) // testing QP-stub?
if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
static_cast&lt;QActiveDummy *&gt;(this)-&gt;QActiveDummy::fakePostLIFO(e);
return;
}
2024-10-15 13:15:28 -04:00
#endif // (Q_UTEST != 0)
#endif // def Q_UTEST
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(300, e != nullptr);
2024-10-15 13:15:28 -04:00
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
#ifndef Q_UNSAFE
QEQueueCtr dis = static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_nFree_dis);
Q_INVARIANT_INCRIT(301, e-&gt;verify_() &amp;&amp; (tmp == dis));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
// test-probe#1 for faking queue overflow
2022-08-11 15:36:19 -04:00
QS_TEST_PROBE_DEF(&amp;QActive::postLIFO)
QS_TEST_PROBE_ID(1,
2024-10-15 13:15:28 -04:00
tmp = 0U; // fake no free events
2022-08-11 15:36:19 -04:00
)
2024-10-15 13:15:28 -04:00
// The queue must NOT overflow for the LIFO posting policy.
Q_REQUIRE_INCRIT(310, tmp != 0U);
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (e-&gt;getPoolNum_() != 0U) {
2022-11-17 14:13:33 -05:00
QEvt_refCtr_inc_(e); // increment the reference counter
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
--tmp; // one free entry just used up
m_eQueue.m_nFree = tmp; // update the original
#ifndef Q_UNSAFE
m_eQueue.m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
if (m_eQueue.m_nMin &gt; tmp) {
m_eQueue.m_nMin = tmp; // update minimum so far
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, m_prio)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of this event
QS_OBJ_PRE(this); // this active object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_EQC_PRE(m_eQueue.m_nMin); // min # free entries
QS_END_PRE()
2022-08-11 15:36:19 -04:00
#ifdef Q_UTEST
// callback to examine the posted event under the same conditions
// as producing the #QS_QF_ACTIVE_POST trace record, which are:
// the local filter for this AO ('m_prio') is set
2022-08-11 15:36:19 -04:00
if (QS_LOC_CHECK_(m_prio)) {
2024-06-12 16:30:04 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
QS::onTestPost(nullptr, this, e, true);
2024-06-12 16:30:04 -04:00
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
#endif // def Q_UTEST
2022-08-11 15:36:19 -04:00
QEvt const * const frontEvt = m_eQueue.m_frontEvt;
m_eQueue.m_frontEvt = e; // deliver the event directly to the front
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_eQueue.m_frontEvt_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(e));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (frontEvt != nullptr) { // was the queue NOT empty?
tmp = m_eQueue.m_tail; // get volatile into temporary;
#ifndef Q_UNSAFE
dis = static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_tail_dis);
Q_INVARIANT_INCRIT(311, tmp == dis);
#endif // ndef Q_UNSAFE
++tmp;
if (tmp == m_eQueue.m_end) { // need to wrap the tail?
tmp = 0U; // wrap around
}
m_eQueue.m_tail = tmp;
#ifndef Q_UNSAFE
m_eQueue.m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
m_eQueue.m_ring[tmp] = frontEvt;
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
else { // queue was empty
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
2022-08-11 15:36:19 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::get_}-->
<operation name="get_" type="QEvt const *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
// wait for event to arrive directly (depends on QP port)
// NOTE: might use assertion-IDs 400-409
2022-08-11 15:36:19 -04:00
QACTIVE_EQUEUE_WAIT_(this); // wait for event to arrive directly
// always remove evt from the front
QEvt const * const e = m_eQueue.m_frontEvt;
2024-10-15 13:15:28 -04:00
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into tmp
2024-06-12 16:30:04 -04:00
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(410, e != nullptr); // queue must NOT be empty
Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e)
== static_cast&lt;std::uintptr_t&gt;(~m_eQueue.m_frontEvt_dis));
QEQueueCtr dis = static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_nFree_dis);
Q_INVARIANT_INCRIT(412, tmp == dis);
#endif // ndef Q_UNSAFE
++tmp; // one more free event in the queue
m_eQueue.m_nFree = tmp; // update the # free
#ifndef Q_UNSAFE
m_eQueue.m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
if (tmp &lt;= m_eQueue.m_end) { // any events in the ring buffer?
QS_BEGIN_PRE(QS_QF_ACTIVE_GET, m_prio)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of this event
QS_OBJ_PRE(this); // this active object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_END_PRE()
2022-08-11 15:36:19 -04:00
// remove event from the tail
2024-10-15 13:15:28 -04:00
tmp = m_eQueue.m_tail; // get volatile into temporary
#ifndef Q_UNSAFE
dis = static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_tail_dis);
Q_INVARIANT_INCRIT(420, tmp == dis);
#endif // ndef Q_UNSAFE
QEvt const * const frontEvt = m_eQueue.m_ring[tmp];
#ifndef Q_UNSAFE
Q_ASSERT_INCRIT(421, frontEvt != nullptr);
m_eQueue.m_frontEvt_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(frontEvt));
#endif // ndef Q_UNSAFE
m_eQueue.m_frontEvt = frontEvt; // update the original
if (tmp == 0U) { // need to wrap the tail?
tmp = m_eQueue.m_end;
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
--tmp; // advance the tail (counter-clockwise)
m_eQueue.m_tail = tmp; // update the original
#ifndef Q_UNSAFE
m_eQueue.m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
else {
m_eQueue.m_frontEvt = nullptr; // the queue becomes empty
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_eQueue.m_frontEvt_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
// all entries in the queue must be free (+1 for fronEvt)
2024-10-15 13:15:28 -04:00
Q_ASSERT_INCRIT(310, tmp == (m_eQueue.m_end + 1U));
QS_BEGIN_PRE(QS_QF_ACTIVE_GET_LAST, m_prio)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of this event
QS_OBJ_PRE(this); // this active object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return e;</code>
</operation>
<!--${QF::QActive::getQueueMin}-->
<operation name="getQueueMin" type="std::uint_fast16_t" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::getQueueMin::prio}-->
<parameter name="prio" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(400, (prio &lt;= QF_MAX_ACTIVE)
&amp;&amp; (QActive::registry_[prio] != nullptr));
std::uint_fast16_t const min = static_cast&lt;std::uint_fast16_t&gt;(
QActive::registry_[prio]-&gt;m_eQueue.getNMin());
QF_CRIT_EXIT();
return min;</code>
</operation>
<!--${QF::QActive::psInit}-->
<operation name="psInit" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::psInit::subscrSto}-->
<parameter name="subscrSto" type="QSubscrList * const"/>
<!--${QF::QActive::psInit::maxSignal}-->
<parameter name="maxSignal" type="enum_t const"/>
<code>subscrList_ = subscrSto;
maxPubSignal_ = maxSignal;
// initialize the subscriber list
for (enum_t sig = 0; sig &lt; maxSignal; ++sig) {
subscrSto[sig].m_set.setEmpty();
#ifndef Q_UNSAFE
subscrSto[sig].m_set.update_(&amp;subscrSto[sig].m_set_dis);
#endif
}</code>
</operation>
<!--${QF::QActive::publish_}-->
<operation name="publish_" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::publish_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QActive::publish_::sender}-->
<parameter name="sender" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QActive::publish_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QSignal const sig = e-&gt;sig;
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, sig &lt; static_cast&lt;QSignal&gt;(maxPubSignal_));
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(202,
subscrList_[sig].m_set.verify_(&amp;subscrList_[sig].m_set_dis));
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_PUBLISH, qsId)
QS_TIME_PRE(); // the timestamp
QS_OBJ_PRE(sender); // the sender object
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_END_PRE()
// is it a mutable event?
2024-01-17 07:50:09 -05:00
if (e-&gt;getPoolNum_() != 0U) {
// NOTE: The reference counter of a mutable event is incremented to
// prevent premature recycling of the event while the multicasting
// is still in progress. At the end of the function, the garbage
// collector step (QF::gc()) decrements the reference counter and
// recycles the event if the counter drops to zero. This covers the
// case when the event was published without any subscribers.
QEvt_refCtr_inc_(e);
}
// make a local, modifiable copy of the subscriber set
QPSet subscrSet = subscrList_[sig].m_set;
QF_MEM_APP();
QF_CRIT_EXIT();
if (subscrSet.notEmpty()) { // any subscribers?
// highest-prio subscriber
std::uint_fast8_t p = subscrSet.findMax();
QF_CRIT_ENTRY();
QF_MEM_SYS();
QActive *a = registry_[p];
// the AO must be registered with the framework
Q_ASSERT_INCRIT(210, a != nullptr);
QF_MEM_APP();
QF_CRIT_EXIT();
QF_SCHED_STAT_
QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio
2024-04-24 09:13:46 -04:00
std::uint_fast8_t lbound = QF_MAX_ACTIVE + 1U;
do { // loop over all subscribers
2024-04-24 09:13:46 -04:00
--lbound;
// POST() asserts internally if the queue overflows
a-&gt;POST(e, sender);
subscrSet.remove(p); // remove the handled subscriber
if (subscrSet.notEmpty()) { // still more subscribers?
p = subscrSet.findMax(); // highest-prio subscriber
QF_CRIT_ENTRY();
QF_MEM_SYS();
a = registry_[p];
// the AO must be registered with the framework
Q_ASSERT_INCRIT(220, a != nullptr);
QF_MEM_APP();
QF_CRIT_EXIT();
}
else {
p = 0U; // no more subscribers
}
2024-04-24 09:13:46 -04:00
} while ((p != 0U) &amp;&amp; (lbound &gt; 0U));
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(290, p == 0U);
QF_CRIT_EXIT();
QF_SCHED_UNLOCK_(); // unlock the scheduler
}
// The following garbage collection step decrements the reference counter
// and recycles the event if the counter drops to zero. This covers both
// cases when the event was published with or without any subscribers.
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e);
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::subscribe}-->
<operation name="subscribe" type="void" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::subscribe::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
Q_REQUIRE_INCRIT(300, (Q_USER_SIG &lt;= sig)
&amp;&amp; (sig &lt; maxPubSignal_)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(302,
subscrList_[sig].m_set.verify_(&amp;subscrList_[sig].m_set_dis));
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_SUBSCRIBE, m_prio)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(sig); // the signal of this event
QS_OBJ_PRE(this); // this active object
QS_END_PRE()
2022-08-11 15:36:19 -04:00
// insert the prio. into the subscriber set
subscrList_[sig].m_set.insert(p);
#ifndef Q_UNSAFE
subscrList_[sig].m_set.update_(&amp;subscrList_[sig].m_set_dis);
#endif
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::unsubscribe}-->
<operation name="unsubscribe" type="void" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::unsubscribe::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
Q_REQUIRE_INCRIT(400, (Q_USER_SIG &lt;= sig)
&amp;&amp; (sig &lt; maxPubSignal_)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(402,
subscrList_[sig].m_set.verify_(&amp;subscrList_[sig].m_set_dis));
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(sig); // the signal of this event
QS_OBJ_PRE(this); // this active object
QS_END_PRE()
2022-08-11 15:36:19 -04:00
// remove the prio. from the subscriber set
subscrList_[sig].m_set.remove(p);
#ifndef Q_UNSAFE
subscrList_[sig].m_set.update_(&amp;subscrList_[sig].m_set_dis);
#endif
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::unsubscribeAll}-->
<operation name="unsubscribeAll" type="void" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
std::uint_fast8_t const p = static_cast&lt;std::uint_fast8_t&gt;(m_prio);
2022-08-11 15:36:19 -04:00
Q_REQUIRE_INCRIT(500, (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (registry_[p] == this));
enum_t const maxPubSig = maxPubSignal_;
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
for (enum_t sig = Q_USER_SIG; sig &lt; maxPubSig; ++sig) {
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
if (subscrList_[sig].m_set.hasElement(p)) {
subscrList_[sig].m_set.remove(p);
#ifndef Q_UNSAFE
subscrList_[sig].m_set.update_(&amp;subscrList_[sig].m_set_dis);
#endif
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(sig); // the signal of this event
QS_OBJ_PRE(this); // this active object
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
QF_CRIT_EXIT_NOP(); // prevent merging critical sections
2022-08-11 15:36:19 -04:00
}</code>
</operation>
<!--${QF::QActive::defer}-->
<operation name="defer" type="bool" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::defer::eq}-->
<parameter name="eq" type="QEQueue * const"/>
<!--${QF::QActive::defer::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>bool const status = eq-&gt;post(e, 0U, m_prio);
QS_CRIT_STAT
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_DEFER, m_prio)
QS_TIME_PRE(); // time stamp
QS_OBJ_PRE(this); // this active object
QS_OBJ_PRE(eq); // the deferred queue
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return status;</code>
</operation>
<!--${QF::QActive::recall}-->
<operation name="recall" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::recall::eq}-->
<parameter name="eq" type="QEQueue * const"/>
<code>QEvt const * const e = eq-&gt;get(m_prio); // get evt from deferred queue
QF_CRIT_STAT
2022-08-11 15:36:19 -04:00
bool recalled;
if (e != nullptr) { // event available?
postLIFO(e); // post it to the _front_ of the AO's queue
2022-08-11 15:36:19 -04:00
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-01-17 07:50:09 -05:00
if (e-&gt;getPoolNum_() != 0U) { // is it a mutable event?
2022-08-11 15:36:19 -04:00
// after posting to the AO's queue the event must be referenced
// at least twice: once in the deferred event queue (eq-&gt;get()
// did NOT decrement the reference counter) and once in the
// AO's event queue.
Q_ASSERT_INCRIT(210, e-&gt;refCtr_ &gt;= 2U);
2022-08-11 15:36:19 -04:00
// we need to decrement the reference counter once, to account
// for removing the event from the deferred event queue.
2022-11-17 14:13:33 -05:00
QEvt_refCtr_dec_(e); // decrement the reference counter
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL, m_prio)
QS_TIME_PRE(); // time stamp
QS_OBJ_PRE(this); // this active object
QS_OBJ_PRE(eq); // the deferred queue
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_END_PRE()
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
recalled = true;
}
else {
QS_CRIT_ENTRY();
QS_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL_ATTEMPT, m_prio)
QS_TIME_PRE(); // time stamp
QS_OBJ_PRE(this); // this active object
QS_OBJ_PRE(eq); // the deferred queue
QS_END_PRE()
2022-08-11 15:36:19 -04:00
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
recalled = false;
}
return recalled;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::flushDeferred}-->
<operation name="flushDeferred" type="std::uint_fast16_t" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<!--${QF::QActive::flushDeferred::eq}-->
<parameter name="eq" type="QEQueue * const"/>
<!--${QF::QActive::flushDeferred::num = 0xFFFFU}-->
<parameter name="num = 0xFFFFU" type="std::uint_fast16_t const"/>
2022-08-11 15:36:19 -04:00
<code>std::uint_fast16_t n = 0U;
while (n &lt; num) {
2023-12-10 15:54:28 -05:00
QEvt const * const e = eq-&gt;get(m_prio);
if (e != nullptr) {
++n; // count one more flushed event
2022-09-09 16:34:14 -04:00
#if (QF_MAX_EPOOL &gt; 0U)
QF::gc(e); // garbage collect
2022-09-09 16:34:14 -04:00
#endif
}
else {
break;
}
2022-08-11 15:36:19 -04:00
}
2022-08-11 15:36:19 -04:00
return n;</code>
</operation>
<!--${QF::QActive::getPrio}-->
2023-01-06 12:56:50 -05:00
<operation name="getPrio" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>const noexcept</specifiers>
2023-01-06 12:56:50 -05:00
<code>return static_cast&lt;std::uint_fast8_t&gt;(m_prio);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::setPrio}-->
<operation name="setPrio" type="void" visibility="0x00" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QActive::setPrio::prio}-->
2022-08-28 22:12:27 -04:00
<parameter name="prio" type="QPrioSpec const"/>
<code>m_prio = static_cast&lt;std::uint8_t&gt;(prio &amp; 0xFFU);
m_pthre = static_cast&lt;std::uint8_t&gt;(prio &gt;&gt; 8U);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::getPThre}-->
<operation name="getPThre" type="std::uint_fast8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return static_cast&lt;std::uint_fast8_t&gt;(m_pthre);</code>
</operation>
<!--${QF::QActive::getEQueue}-->
<operation name="getEQueue?def QACTIVE_EQUEUE_TYPE" type="QACTIVE_EQUEUE_TYPE const &amp;" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_eQueue;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::getOsObject}-->
<operation name="getOsObject?def QACTIVE_OS_OBJ_TYPE" type="QACTIVE_OS_OBJ_TYPE const &amp;" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
2022-08-11 15:36:19 -04:00
<code>return m_osObject;</code>
</operation>
<!--${QF::QActive::getThread}-->
<operation name="getThread?def QACTIVE_THREAD_TYPE" type="QACTIVE_THREAD_TYPE const &amp;" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
2022-08-11 15:36:19 -04:00
<code>return m_thread;</code>
</operation>
<!--${QF::QActive::setThread}-->
<operation name="setThread?def QACTIVE_THREAD_TYPE" type="void" visibility="0x00" properties="0x02">
<!--${QF::QActive::setThread::thr}-->
<parameter name="thr" type="QACTIVE_THREAD_TYPE const &amp;"/>
<code>m_thread = thr;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QActive::evtLoop_}-->
<operation name="evtLoop_" type="void" visibility="0x00" properties="0x01">
<!--${QF::QActive::evtLoop_::act}-->
<parameter name="act" type="QActive *"/>
</operation>
<!--${QF::QActive::postFromISR}-->
<operation name="postFromISR?def QF_ISR_API" type="bool" visibility="0x00" properties="0x04">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QActive::postFromISR::e}-->
2022-08-11 15:36:19 -04:00
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QActive::postFromISR::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QActive::postFromISR::par}-->
<parameter name="par" type="void *"/>
<!--${QF::QActive::postFromISR::sender}-->
2022-08-11 15:36:19 -04:00
<parameter name="sender" type="void const * const"/>
</operation>
<!--${QF::QActive::publishFromISR}-->
<operation name="publishFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QActive::publishFromISR::e}-->
<parameter name="e" type="QEvt const *"/>
<!--${QF::QActive::publishFromISR::par}-->
<parameter name="par" type="void *"/>
<!--${QF::QActive::publishFromISR::sender}-->
<parameter name="sender" type="void const *"/>
2022-08-11 15:36:19 -04:00
</operation>
</class>
<!--${QF::QMActive}-->
<class name="QMActive" superclass="QF::QActive">
<!--${QF::QMActive::QMActive}-->
<operation name="QMActive" type="" visibility="0x01" properties="0x00">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QMActive::QMActive::initial}-->
<parameter name="initial" type="QStateHandler const"/>
<code> : QActive(initial)
2022-08-11 15:36:19 -04:00
m_state.obj = reinterpret_cast&lt;QMsm *&gt;(this)-&gt;topQMState();
2022-08-11 15:36:19 -04:00
m_temp.fun = initial;</code>
</operation>
<!--${QF::QMActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>override</specifiers>
<!--${QF::QMActive::init::e}-->
<parameter name="e" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QMActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::init(e, qsId);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMActive::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
2022-08-11 15:36:19 -04:00
<specifiers>override</specifiers>
2024-01-17 07:50:09 -05:00
<!--${QF::QMActive::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMActive::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>override</specifiers>
<!--${QF::QMActive::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QMActive::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::dispatch(e, qsId);</code>
</operation>
2023-12-14 16:55:58 -05:00
<!--${QF::QMActive::isIn}-->
<operation name="isIn" type="bool" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<!--${QF::QMActive::isIn::state}-->
<parameter name="state" type="QStateHandler const"/>
<code>return reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::isIn(state);</code>
</operation>
<!--${QF::QMActive::getStateHandler}-->
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x02">
<specifiers>noexcept override</specifiers>
<code>return reinterpret_cast&lt;QMsm *&gt;(this)-&gt;QMsm::getStateHandler();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMActive::childStateObj}-->
<operation name="childStateObj" type="QMState const *" visibility="0x00" properties="0x02">
2022-08-11 15:36:19 -04:00
<specifiers>const noexcept</specifiers>
<!--${QF::QMActive::childStateObj::parent}-->
<parameter name="parent" type="QMState const * const"/>
<code>return reinterpret_cast&lt;QMsm const *&gt;(this)
2022-08-11 15:36:19 -04:00
-&gt;QMsm::childStateObj(parent);</code>
</operation>
</class>
<!--${QF::QTimeEvt}-->
<class name="QTimeEvt" superclass="QEP::QEvt">
<!--${QF::QTimeEvt::m_next}-->
<attribute name="m_next" type="QTimeEvt * volatile" visibility="0x02" properties="0x00"/>
2024-10-15 13:15:28 -04:00
<!--${QF::QTimeEvt::m_next_dis}-->
<attribute name="m_next_dis?ndef Q_UNSAFE" type="std::uintptr_t" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::m_act}-->
<attribute name="m_act" type="void *" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::m_ctr}-->
<attribute name="m_ctr" type="QTimeEvtCtr volatile" visibility="0x02" properties="0x00"/>
2024-10-15 13:15:28 -04:00
<!--${QF::QTimeEvt::m_ctr_dis}-->
<attribute name="m_ctr_dis?ndef Q_UNSAFE" type="QTimeEvtCtr" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::m_interval}-->
<attribute name="m_interval" type="QTimeEvtCtr" visibility="0x02" properties="0x00"/>
2024-10-15 13:15:28 -04:00
<!--${QF::QTimeEvt::m_tickRate}-->
<attribute name="m_tickRate" type="std::uint8_t" visibility="0x02" properties="0x00"/>
<!--${QF::QTimeEvt::m_flags}-->
<attribute name="m_flags" type="std::uint8_t" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::timeEvtHead_[QF_MAX_TICK_RATE]}-->
<attribute name="timeEvtHead_[QF_MAX_TICK_RATE]" type="QTimeEvt" visibility="0x00" properties="0x01"/>
2024-10-15 13:15:28 -04:00
<!--${QF::QTimeEvt::timeEvtHead_dis_[QF_MAX_TICK_RAT~}-->
<attribute name="timeEvtHead_dis_[QF_MAX_TICK_RATE]?ndef Q_UNSAFE" type="QPtrDis" visibility="0x00" properties="0x01"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::QXThread}-->
<attribute name="QXThread" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QTimeEvt::QTimeEvt}-->
<operation name="QTimeEvt" type="" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::QTimeEvt::act}-->
<parameter name="act" type="QActive * const"/>
<!--${QF::QTimeEvt::QTimeEvt::sig}-->
<parameter name="sig" type="QSignal const"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::QTimeEvt::tickRate = 0U}-->
<parameter name="tickRate = 0U" type="std::uint_fast8_t const"/>
2024-10-15 13:15:28 -04:00
<code> : QEvt(sig),
2022-08-11 15:36:19 -04:00
m_next(nullptr),
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_next_dis(static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr))),
#endif
2022-08-11 15:36:19 -04:00
m_act(act),
m_ctr(0U),
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_ctr_dis(static_cast&lt;QTimeEvtCtr&gt;(~static_cast&lt;QTimeEvtCtr&gt;(0U))),
#endif
m_interval(0U),
m_tickRate(0U),
m_flags(0U)
2022-08-11 15:36:19 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, (sig != 0U)
&amp;&amp; (tickRate &lt; QF_MAX_TICK_RATE));
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// adjust the settings from the QEvt(sig) ctor
evtTag_ = 0x0FU;
refCtr_ = 0U;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QTimeEvt::armX}-->
<operation name="armX" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::armX::nTicks}-->
2024-10-15 13:15:28 -04:00
<parameter name="nTicks" type="std::uint32_t const"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QTimeEvt::armX::interval = 0U}-->
2024-10-15 13:15:28 -04:00
<parameter name="interval = 0U" type="std::uint32_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// dynamic range checks
#if (QF_TIMEEVT_CTR_SIZE == 1U)
Q_REQUIRE_INCRIT(400, (nTicks &lt; 0xFFU) &amp;&amp; (interval &lt; 0xFFU));
#elif (QF_TIMEEVT_CTR_SIZE == 2U)
Q_REQUIRE_INCRIT(400, (nTicks &lt; 0xFFFFU) &amp;&amp; (interval &lt; 0xFFFFU));
#endif
Q_REQUIRE_INCRIT(401, verify_() &amp;&amp; (nTicks != 0U));
QTimeEvtCtr const ctr = m_ctr;
2024-10-15 13:15:28 -04:00
std::uint8_t const tickRate = m_tickRate;
#ifdef Q_SPY
2024-01-17 07:50:09 -05:00
std::uint_fast8_t const qsId =
static_cast&lt;QActive const *&gt;(m_act)-&gt;m_prio;
2024-10-15 13:15:28 -04:00
#endif // def Q_SPY
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(410, (ctr == 0U)
&amp;&amp; (m_act != nullptr)
&amp;&amp; (tickRate &lt; QF_MAX_TICK_RATE));
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(411, ctr == static_cast&lt;QTimeEvtCtr&gt;(~m_ctr_dis));
#else
Q_UNUSED_PAR(ctr);
2024-10-15 13:15:28 -04:00
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
m_ctr = static_cast&lt;QTimeEvtCtr&gt;(nTicks);
m_interval = static_cast&lt;QTimeEvtCtr&gt;(interval);
#ifndef Q_UNSAFE
m_ctr_dis = static_cast&lt;QTimeEvtCtr&gt;(~nTicks);
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
// is the time event unlinked?
// NOTE: For the duration of a single clock tick of the specified tick
// rate a time event can be disarmed and yet still linked into the list
2022-08-11 15:36:19 -04:00
// because un-linking is performed exclusively in the QF_tickX() function.
2024-10-15 13:15:28 -04:00
if ((m_flags &amp; QTE_FLAG_IS_LINKED) == 0U) {
m_flags |= QTE_FLAG_IS_LINKED; // mark as linked
2022-08-11 15:36:19 -04:00
// The time event is initially inserted into the separate
// &quot;freshly armed&quot; list based on timeEvtHead_[tickRate].act.
// Only later, inside QTimeEvt::tick(), the &quot;freshly armed&quot;
2022-08-11 15:36:19 -04:00
// list is appended to the main list of armed time events based on
// timeEvtHead_[tickRate].next. Again, this is to keep any
// changes to the main list exclusively inside QTimeEvt::tick().
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(420,
Q_PTR2UINT_CAST_(m_next) ==
static_cast&lt;std::uintptr_t&gt;(~m_next_dis));
Q_INVARIANT_INCRIT(411,
Q_PTR2UINT_CAST_(timeEvtHead_[tickRate].m_act) ==
static_cast&lt;std::uintptr_t&gt;(~timeEvtHead_dis_[tickRate].m_ptr_dis));
#endif
2022-08-11 15:36:19 -04:00
m_next = timeEvtHead_[tickRate].toTimeEvt();
timeEvtHead_[tickRate].m_act = this;
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_next_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(m_next));
timeEvtHead_dis_[tickRate].m_ptr_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(this));
#endif // ndef Q_UNSAFE
}
QS_BEGIN_PRE(QS_QF_TIMEEVT_ARM, qsId)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(this); // this time event object
QS_OBJ_PRE(m_act); // the active object
QS_TEC_PRE(nTicks); // the # ticks
QS_TEC_PRE(interval); // the interval
QS_U8_PRE(tickRate); // tick rate
QS_END_PRE()
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QTimeEvt::disarm}-->
<operation name="disarm" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
2024-10-15 13:15:28 -04:00
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(500, verify_());
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QTimeEvtCtr const ctr = m_ctr;
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(501, ctr == static_cast&lt;QTimeEvtCtr&gt;(~m_ctr_dis));
#endif // ndef Q_UNSAFE
#ifdef Q_SPY
std::uint_fast8_t const qsId = static_cast&lt;QActive *&gt;(m_act)-&gt;m_prio;
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// was the time event actually armed?
bool wasArmed;
if (ctr != 0U) {
wasArmed = true;
m_flags |= QTE_FLAG_WAS_DISARMED;
2022-08-11 15:36:19 -04:00
m_ctr = 0U; // schedule removal from the list
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_ctr_dis = static_cast&lt;QTimeEvtCtr&gt;(~static_cast&lt;QTimeEvtCtr&gt;(0U));
#endif // ndef Q_UNSAFE
QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM, qsId)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(this); // this time event object
QS_OBJ_PRE(m_act); // the target AO
QS_TEC_PRE(ctr); // the # ticks
QS_TEC_PRE(m_interval); // the interval
QS_U8_PRE(m_tickRate); // tick rate
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
else { // the time event was already disarmed automatically
wasArmed = false;
2024-10-15 13:15:28 -04:00
m_flags &amp;= static_cast&lt;std::uint8_t&gt;(~QTE_FLAG_WAS_DISARMED);
QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(this); // this time event object
QS_OBJ_PRE(m_act); // the target AO
QS_U8_PRE(m_tickRate); // tick rate
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return wasArmed;</code>
</operation>
<!--${QF::QTimeEvt::rearm}-->
<operation name="rearm" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::rearm::nTicks}-->
2024-10-15 13:15:28 -04:00
<parameter name="nTicks" type="std::uint32_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// dynamic range checks
#if (QF_TIMEEVT_CTR_SIZE == 1U)
Q_REQUIRE_INCRIT(600, nTicks &lt; 0xFFU);
#elif (QF_TIMEEVT_CTR_SIZE == 2U)
Q_REQUIRE_INCRIT(600, nTicks &lt; 0xFFFFU);
#endif
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(601, verify_() &amp;&amp; (nTicks != 0U));
QTimeEvtCtr const ctr = m_ctr;
std::uint8_t const tickRate = m_tickRate;
#ifdef Q_SPY
std::uint_fast8_t const qsId = static_cast&lt;QActive *&gt;(m_act)-&gt;m_prio;
#endif
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(610, (m_act != nullptr)
&amp;&amp; (tickRate &lt; QF_MAX_TICK_RATE));
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(602, ctr == static_cast&lt;QTimeEvtCtr&gt;(~m_ctr_dis));
#endif // ndef Q_UNSAFE
m_ctr = static_cast&lt;QTimeEvtCtr&gt;(nTicks);
#ifndef Q_UNSAFE
m_ctr_dis = static_cast&lt;QTimeEvtCtr&gt;(~nTicks);
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
// is the time evt not running?
bool wasArmed;
2024-10-15 13:15:28 -04:00
if (ctr == 0U) {
2022-08-11 15:36:19 -04:00
wasArmed = false;
// NOTE: For a duration of a single clock tick of the specified
// tick rate a time event can be disarmed and yet still linked into
// the list, because unlinking is performed exclusively in the
2024-10-15 13:15:28 -04:00
// QTimeEvt::tick() function.
2024-10-15 13:15:28 -04:00
// was the time event unlinked?
if ((m_flags &amp; QTE_FLAG_IS_LINKED) == 0U) {
m_flags |= QTE_FLAG_IS_LINKED; // mark as linked
2022-08-11 15:36:19 -04:00
// The time event is initially inserted into the separate
// &quot;freshly armed&quot; list based on timeEvtHead_[tickRate].act.
// Only later, inside QTimeEvt::tick(), the &quot;freshly armed&quot;
2022-08-11 15:36:19 -04:00
// list is appended to the main list of armed time events based on
// timeEvtHead_[tickRate].next. Again, this is to keep any
// changes to the main list exclusively inside QTimeEvt::tick().
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(620,
Q_PTR2UINT_CAST_(m_next) ==
static_cast&lt;std::uintptr_t&gt;(~m_next_dis));
Q_INVARIANT_INCRIT(611,
Q_PTR2UINT_CAST_(timeEvtHead_[tickRate].m_act) ==
static_cast&lt;std::uintptr_t&gt;(~timeEvtHead_dis_[tickRate].m_ptr_dis));
#endif
2022-08-11 15:36:19 -04:00
m_next = timeEvtHead_[tickRate].toTimeEvt();
timeEvtHead_[tickRate].m_act = this;
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_next_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(m_next));
timeEvtHead_dis_[tickRate].m_ptr_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(this));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
}
else { // the time event was armed
2022-08-11 15:36:19 -04:00
wasArmed = true;
}
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_TIMEEVT_REARM, qsId)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(this); // this time event object
QS_OBJ_PRE(m_act); // the target AO
QS_TEC_PRE(nTicks); // the # ticks
QS_TEC_PRE(m_interval); // the interval
QS_2U8_PRE(tickRate, (wasArmed ? 1U : 0U));
QS_END_PRE()
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return wasArmed;</code>
</operation>
<!--${QF::QTimeEvt::wasDisarmed}-->
<operation name="wasDisarmed" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
bool const wasDisarmed = (m_flags &amp; QTE_FLAG_WAS_DISARMED) != 0U;
m_flags |= QTE_FLAG_WAS_DISARMED;
QF_MEM_APP();
QF_CRIT_EXIT();
2024-10-15 13:15:28 -04:00
return wasDisarmed;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QTimeEvt::getAct}-->
<operation name="getAct" type="void const *" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_act;</code>
</operation>
<!--${QF::QTimeEvt::getCtr}-->
<operation name="getCtr" type="QTimeEvtCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_ctr;</code>
</operation>
<!--${QF::QTimeEvt::getInterval}-->
<operation name="getInterval" type="QTimeEvtCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_interval;</code>
</operation>
2024-10-15 13:15:28 -04:00
<!--${QF::QTimeEvt::getTickRate}-->
<operation name="getTickRate" type="std::uint8_t" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_tickRate;</code>
</operation>
<!--${QF::QTimeEvt::tick}-->
<operation name="tick" type="void" visibility="0x00" properties="0x01">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::tick::tickRate}-->
2022-08-11 15:36:19 -04:00
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QTimeEvt::tick::sender}-->
2022-08-11 15:36:19 -04:00
<parameter name="sender" type="void const * const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
#endif
2022-08-11 15:36:19 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(800, tickRate &lt; Q_DIM(timeEvtHead_));
QTimeEvt *prev = &amp;timeEvtHead_[tickRate];
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_TICK, 0U)
2022-08-11 15:36:19 -04:00
prev-&gt;m_ctr = (prev-&gt;m_ctr + 1U);
2024-10-15 13:15:28 -04:00
QS_TEC_PRE(prev-&gt;m_ctr); // tick ctr
QS_U8_PRE(tickRate); // tick rate
QS_END_PRE()
2022-08-11 15:36:19 -04:00
// scan the linked-list of time events at this rate...
2024-04-24 09:13:46 -04:00
std::uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
for (; lbound &gt; 0U; --lbound) {
2024-10-15 13:15:28 -04:00
Q_ASSERT_INCRIT(810, prev != nullptr); // sanity check
QTimeEvt *te = prev-&gt;m_next; // advance down the time evt. list
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(811,
Q_PTR2UINT_CAST_(te) ==
static_cast&lt;std::uintptr_t&gt;(~prev-&gt;m_next_dis));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (te == nullptr) { // end of the list?
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// any new time events armed since the last QTimeEvt_tick_()?
2022-08-11 15:36:19 -04:00
if (timeEvtHead_[tickRate].m_act != nullptr) {
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(812,
Q_PTR2UINT_CAST_(timeEvtHead_[tickRate].m_act) ==
static_cast&lt;std::uintptr_t&gt;(
~timeEvtHead_dis_[tickRate].m_ptr_dis));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
prev-&gt;m_next = timeEvtHead_[tickRate].toTimeEvt();
timeEvtHead_[tickRate].m_act = nullptr;
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
prev-&gt;m_next_dis =
static_cast&lt;std::uintptr_t&gt;(
~Q_PTR2UINT_CAST_(prev-&gt;m_next));
timeEvtHead_dis_[tickRate].m_ptr_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr));
#endif // ndef Q_UNSAFE
te = prev-&gt;m_next; // switch to the new list
2022-08-11 15:36:19 -04:00
}
else { // all currently armed time events are processed
break; // terminate the for-loop
2022-08-11 15:36:19 -04:00
}
}
2024-10-15 13:15:28 -04:00
// the time event 'te' must be valid
Q_ASSERT_INCRIT(820, te != nullptr);
Q_INVARIANT_INCRIT(821, te-&gt;verify_());
QTimeEvtCtr ctr = te-&gt;m_ctr;
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(822, ctr ==
static_cast&lt;QTimeEvtCtr&gt;(~te-&gt;m_ctr_dis));
#endif // ndef Q_UNSAFE
if (ctr == 0U) { // time event scheduled for removal?
prev-&gt;m_next = te-&gt;m_next;
#ifndef Q_UNSAFE
prev-&gt;m_next_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(te-&gt;m_next));
#endif // ndef Q_UNSAFE
// mark time event 'te' as NOT linked
te-&gt;m_flags &amp;= static_cast&lt;std::uint8_t&gt;(~QTE_FLAG_IS_LINKED);
2022-08-11 15:36:19 -04:00
// do NOT advance the prev pointer
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section to reduce latency
// NOTE: prevent merging critical sections
// In some QF ports the critical section exit takes effect only
// on the next machine instruction. If the next instruction is
// another entry to a critical section, the critical section
// might not be really exited, but rather the two adjacent
// critical sections would be MERGED. The QF_CRIT_EXIT_NOP()
// macro contains minimal code required to prevent such merging
// of critical sections in QF ports, in which it can occur.
2022-08-11 15:36:19 -04:00
QF_CRIT_EXIT_NOP();
}
2024-10-15 13:15:28 -04:00
else if (ctr == 1U) { // is time evt about to expire?
QActive * const act = te-&gt;toActive();
if (te-&gt;m_interval != 0U) { // periodic time evt?
te-&gt;m_ctr = te-&gt;m_interval; // rearm the time event
#ifndef Q_UNSAFE
te-&gt;m_ctr_dis = static_cast&lt;QTimeEvtCtr&gt;(~te-&gt;m_interval);
#endif // ndef Q_UNSAFE
prev = te; // advance to this time event
}
else { // one-shot time event: automatically disarm
te-&gt;m_ctr = 0U;
prev-&gt;m_next = te-&gt;m_next;
#ifndef Q_UNSAFE
te-&gt;m_ctr_dis =
static_cast&lt;QTimeEvtCtr&gt;(~static_cast&lt;QTimeEvtCtr&gt;(0U));
prev-&gt;m_next_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(te-&gt;m_next));
#endif // ndef Q_UNSAFE
// mark time event 'te' as NOT linked
te-&gt;m_flags &amp;=
static_cast&lt;std::uint8_t&gt;(~QTE_FLAG_IS_LINKED);
// do NOT advance the prev pointer
QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act-&gt;m_prio)
QS_OBJ_PRE(te); // this time event object
QS_OBJ_PRE(act); // the target AO
QS_U8_PRE(tickRate); // tick rate
QS_END_PRE()
}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act-&gt;m_prio)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(te); // the time event object
QS_SIG_PRE(te-&gt;sig); // signal of this time event
QS_OBJ_PRE(act); // the target AO
QS_U8_PRE(tickRate); // tick rate
QS_END_PRE()
#ifdef QXK_HPP_
2024-10-15 13:15:28 -04:00
if (te-&gt;sig &lt; Q_USER_SIG) {
QXThread::timeout_(act);
QF_MEM_APP();
QF_CRIT_EXIT();
}
else {
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section before posting
2022-08-11 15:36:19 -04:00
// act-&gt;POST() asserts if the queue overflows
2024-10-15 13:15:28 -04:00
act-&gt;POST(te, sender);
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
#else
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section before posting
2024-10-15 13:15:28 -04:00
// act-&gt;POST() asserts if the queue overflows
act-&gt;POST(te, sender);
#endif
}
else { // time event keeps timing out
--ctr; // decrement the tick counter
te-&gt;m_ctr = ctr; // update the original
#ifndef Q_UNSAFE
te-&gt;m_ctr_dis = static_cast&lt;QTimeEvtCtr&gt;(~ctr);
#endif // ndef Q_UNSAFE
2024-10-15 13:15:28 -04:00
prev = te; // advance to this time event
QF_MEM_APP();
QF_CRIT_EXIT(); // exit crit. section to reduce latency
// prevent merging critical sections, see NOTE above
QF_CRIT_EXIT_NOP();
2022-08-11 15:36:19 -04:00
}
QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
Q_ENSURE_INCRIT(890, lbound &gt; 0U);
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QTimeEvt::tick1_}-->
<operation name="tick1_?def Q_UTEST" type="void" visibility="0x00" properties="0x01">
<!--${QF::QTimeEvt::tick1_::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QTimeEvt::tick1_::sender}-->
<parameter name="sender" type="void const * const"/>
</operation>
<!--${QF::QTimeEvt::tickFromISR}-->
<operation name="tickFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x01">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::tickFromISR::tickRate}-->
2022-08-11 15:36:19 -04:00
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QTimeEvt::tickFromISR::par}-->
2022-08-11 15:36:19 -04:00
<parameter name="par" type="void *"/>
<!--${QF::QTimeEvt::tickFromISR::sender}-->
2022-08-11 15:36:19 -04:00
<parameter name="sender" type="void const *"/>
</operation>
<!--${QF::QTimeEvt::noActive}-->
<operation name="noActive" type="bool" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QTimeEvt::noActive::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<code>// NOTE: this function must be called *inside* critical section
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(900, tickRate &lt; QF_MAX_TICK_RATE);
2022-08-11 15:36:19 -04:00
bool inactive;
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
if (timeEvtHead_[tickRate].m_next != nullptr) {
inactive = false;
}
else if (timeEvtHead_[tickRate].m_act != nullptr) {
inactive = false;
}
else {
inactive = true;
}
QF_MEM_APP();
2022-08-11 15:36:19 -04:00
return inactive;</code>
</operation>
<!--${QF::QTimeEvt::toActive}-->
<operation name="toActive" type="QActive *" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code>return static_cast&lt;QActive *&gt;(m_act);</code>
</operation>
<!--${QF::QTimeEvt::toTimeEvt}-->
<operation name="toTimeEvt" type="QTimeEvt *" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code>return static_cast&lt;QTimeEvt *&gt;(m_act);</code>
</operation>
<!--${QF::QTimeEvt::QTimeEvt}-->
<operation name="QTimeEvt" type="" visibility="0x02" properties="0x00">
<specifiers>noexcept</specifiers>
2024-10-15 13:15:28 -04:00
<code> : QEvt(0U),
2022-08-11 15:36:19 -04:00
m_next(nullptr),
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_next_dis(static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr))),
#endif
2022-08-11 15:36:19 -04:00
m_act(nullptr),
m_ctr(0U),
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_ctr_dis(static_cast&lt;QTimeEvtCtr&gt;(~static_cast&lt;QTimeEvtCtr&gt;(0U))),
#endif
m_interval(0U),
m_tickRate(0U),
m_flags(0U)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QTimeEvt::QTimeEvt}-->
<operation name="QTimeEvt" type="" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QTimeEvt::QTimeEvt::other}-->
<parameter name="other" type="QTimeEvt const &amp;"/>
</operation>
<!--${QF::QTimeEvt::operator=}-->
<operation name="operator=" type="QTimeEvt &amp;" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QTimeEvt::operator=::other}-->
<parameter name="other" type="QTimeEvt const &amp;"/>
</operation>
</class>
<!--${QF::QTicker}-->
<class name="QTicker" superclass="QF::QActive">
<!--${QF::QTicker::QTicker}-->
<operation name="QTicker" type="explicit" visibility="0x00" properties="0x00">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QTicker::QTicker::tickRate}-->
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<code>: QActive(nullptr)
// reuse m_head for tick-rate
2024-10-15 13:15:28 -04:00
m_eQueue.m_head = static_cast&lt;QEQueueCtr&gt;(tickRate);
#ifndef Q_UNSAFE
m_eQueue.m_head_dis = static_cast&lt;QEQueueCtr&gt;(~tickRate);
#endif // ndef Q_UNSAFE</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QTicker::init}-->
2022-08-11 15:36:19 -04:00
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QF::QTicker::init::e}-->
<parameter name="e" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QTicker::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
m_eQueue.m_tail = 0U;
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_eQueue.m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~0U);
#endif // ndef Q_UNSAFE
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QTicker::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x06">
<specifiers>override</specifiers>
2024-01-17 07:50:09 -05:00
<!--${QF::QTicker::init::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>this-&gt;init(nullptr, qsId);</code>
</operation>
<!--${QF::QTicker::dispatch}-->
<operation name="dispatch" type="void" visibility="0x00" properties="0x00">
<specifiers>override</specifiers>
<!--${QF::QTicker::dispatch::e}-->
<parameter name="e" type="QEvt const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QTicker::dispatch::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>Q_UNUSED_PAR(e);
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
// get volatile into temporaries
QEQueueCtr nTicks = m_eQueue.m_tail;
QEQueueCtr const tickRate = m_eQueue.m_head;
#ifndef Q_UNSAFE
Q_REQUIRE_INCRIT(700, nTicks &gt; 0U);
Q_INVARIANT_INCRIT(701, nTicks
== static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_tail_dis));
Q_INVARIANT_INCRIT(702, tickRate
== static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_head_dis));
#endif // ndef Q_UNSAFE
m_eQueue.m_tail = 0U; // clear # ticks
#ifndef Q_UNSAFE
m_eQueue.m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~0U);
#endif // ndef Q_UNSAFE
QF_MEM_APP();
QF_CRIT_EXIT();
for (; nTicks &gt; 0U; --nTicks) {
2024-10-15 13:15:28 -04:00
QTimeEvt::tick(static_cast&lt;std::uint_fast8_t&gt;(tickRate),
this);
}</code>
</operation>
<!--${QF::QTicker::trig_}-->
<operation name="trig_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QTicker::trig_::sender}-->
<parameter name="sender" type="void const * const"/>
<code>#ifndef Q_SPY
Q_UNUSED_PAR(sender);
#endif
2024-10-15 13:15:28 -04:00
static QEvt const tickEvt(0U); // immutable event
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
QEQueueCtr nTicks = m_eQueue.m_tail; // get volatile into temporary
2024-10-15 13:15:28 -04:00
if (m_eQueue.m_frontEvt == nullptr) {
#ifndef Q_UNSAFE
Q_REQUIRE_INCRIT(800, nTicks == 0U);
Q_REQUIRE_INCRIT(801, m_eQueue.m_nFree == 1U);
Q_INVARIANT_INCRIT(802, m_eQueue.m_frontEvt_dis
== static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr)));
Q_INVARIANT_INCRIT(803,
1U == static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_nFree_dis));
Q_INVARIANT_INCRIT(804,
0U == static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_tail_dis));
#endif // ndef Q_UNSAFE
m_eQueue.m_frontEvt = &amp;tickEvt; // deliver event directly
2024-10-15 13:15:28 -04:00
m_eQueue.m_nFree = 0U;
#ifndef Q_UNSAFE
m_eQueue.m_frontEvt_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(&amp;tickEvt));
m_eQueue.m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~0U);
#endif // ndef Q_UNSAFE
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
}
2024-10-15 13:15:28 -04:00
else {
#ifndef Q_UNSAFE
Q_REQUIRE_INCRIT(810, (nTicks &gt; 0U) &amp;&amp; (nTicks &lt; 0xFFU));
Q_REQUIRE_INCRIT(811, m_eQueue.m_nFree == 0U);
Q_INVARIANT_INCRIT(812, m_eQueue.m_frontEvt_dis
== static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(&amp;tickEvt)));
Q_INVARIANT_INCRIT(813,
0U == static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_nFree_dis));
Q_INVARIANT_INCRIT(814,
nTicks == static_cast&lt;QEQueueCtr&gt;(~m_eQueue.m_tail_dis));
#endif // ndef Q_UNSAFE
}
2024-10-15 13:15:28 -04:00
++nTicks; // account for one more tick event
2024-10-15 13:15:28 -04:00
m_eQueue.m_tail = nTicks; // update the original
#ifndef Q_UNSAFE
m_eQueue.m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~nTicks);
#endif // ndef Q_UNSAFE
QS_BEGIN_PRE(QS_QF_ACTIVE_POST, m_prio)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(sender); // the sender object
QS_SIG_PRE(0U); // the signal of the event
QS_OBJ_PRE(this); // this active object
QS_2U8_PRE(0U, 0U); // poolNum &amp; refCtr
QS_EQC_PRE(0U); // # free entries
QS_EQC_PRE(0U); // min # free entries
QS_END_PRE()
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
</class>
<!--${QF::QEQueue}-->
<class name="QEQueue">
<!--${QF::QEQueue::m_frontEvt}-->
<attribute name="m_frontEvt" type="QEvt const * volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_ring}-->
2024-10-15 13:15:28 -04:00
<attribute name="m_ring" type="QEvt const * *" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_end}-->
<attribute name="m_end" type="QEQueueCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_head}-->
<attribute name="m_head" type="QEQueueCtr volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_tail}-->
<attribute name="m_tail" type="QEQueueCtr volatile" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_nFree}-->
<attribute name="m_nFree" type="QEQueueCtr volatile" visibility="0x02" properties="0x00"/>
2024-10-15 13:15:28 -04:00
<!--${QF::QEQueue::m_frontEvt_dis}-->
<attribute name="m_frontEvt_dis?ndef Q_UNSAFE" type="std::uintptr_t" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_head_dis}-->
<attribute name="m_head_dis?ndef Q_UNSAFE" type="QEQueueCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_tail_dis}-->
<attribute name="m_tail_dis?ndef Q_UNSAFE" type="QEQueueCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_nFree_dis}-->
<attribute name="m_nFree_dis?ndef Q_UNSAFE" type="QEQueueCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::m_nMin}-->
<attribute name="m_nMin" type="QEQueueCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QActive}-->
<attribute name="QActive" type="friend class" visibility="0x02" properties="0x00">
<documentation>// friends...</documentation>
</attribute>
<!--${QF::QEQueue::QTicker}-->
<attribute name="QTicker" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QXMutex}-->
<attribute name="QXMutex" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QXThread}-->
<attribute name="QXThread" type="friend class" visibility="0x02" properties="0x00"/>
<!--${QF::QEQueue::QEQueue}-->
<operation name="QEQueue" type="" visibility="0x00" properties="0x02">
<specifiers>noexcept</specifiers>
<code> : m_frontEvt(nullptr),
m_ring(nullptr),
m_end(0U),
m_head(0U),
m_tail(0U),
m_nFree(0U),
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_frontEvt_dis(static_cast&lt;std::uintptr_t&gt;(~0U)),
m_head_dis(static_cast&lt;QEQueueCtr&gt;(~0U)),
m_tail_dis(static_cast&lt;QEQueueCtr&gt;(~0U)),
m_nFree_dis(static_cast&lt;QEQueueCtr&gt;(~0U)),
#endif
m_nMin(0U)</code>
</operation>
<!--${QF::QEQueue::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QEQueue::init::qSto[]}-->
<parameter name="qSto[]" type="QEvt const *"/>
<!--${QF::QEQueue::init::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
2024-06-07 16:07:22 -04:00
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
#if (QF_EQUEUE_CTR_SIZE == 1U)
Q_REQUIRE_INCRIT(100, qLen &lt; 0xFFU);
#endif
m_frontEvt = nullptr; // no events in the queue
m_ring = &amp;qSto[0];
m_end = static_cast&lt;QEQueueCtr&gt;(qLen);
if (qLen &gt; 0U) {
m_head = 0U;
m_tail = 0U;
}
m_nFree = static_cast&lt;QEQueueCtr&gt;(qLen + 1U); //+1 for frontEvt
2024-06-07 16:07:22 -04:00
m_nMin = m_nFree;
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_frontEvt_dis = static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(m_frontEvt));
m_head_dis = static_cast&lt;QEQueueCtr&gt;(~m_head);
m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~m_tail);
m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~m_nFree);
#endif
2024-06-07 16:07:22 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QF::QEQueue::post}-->
2022-08-11 15:36:19 -04:00
<operation name="post" type="bool" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QEQueue::post::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QEQueue::post::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QEQueue::post::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(200, e != nullptr);
Q_INVARIANT_INCRIT(201, e-&gt;verify_());
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QEQueueCtr tmp = m_nFree; // get volatile into temporary
#ifndef Q_UNSAFE
QEQueueCtr dis = static_cast&lt;QEQueueCtr&gt;(~m_nFree_dis);
Q_INVARIANT_INCRIT(201, tmp == dis);
#endif // ndef Q_UNSAFE
// test-probe#1 for faking queue overflow
QS_TEST_PROBE_DEF(&amp;QEQueue::post)
QS_TEST_PROBE_ID(1,
tmp = 0U; // fake no free events
)
// required margin available?
2022-08-11 15:36:19 -04:00
bool status;
2024-10-15 13:15:28 -04:00
if (((margin == QF::NO_MARGIN) &amp;&amp; (tmp &gt; 0U))
|| (tmp &gt; static_cast&lt;QEQueueCtr&gt;(margin)))
2022-08-11 15:36:19 -04:00
{
// is it a mutable event?
2024-01-17 07:50:09 -05:00
if (e-&gt;getPoolNum_() != 0U) {
2022-11-17 14:13:33 -05:00
QEvt_refCtr_inc_(e); // increment the reference counter
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
--tmp; // one free entry just used up
m_nFree = tmp; // update the original
#ifndef Q_UNSAFE
m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
if (m_nMin &gt; tmp) {
m_nMin = tmp; // update minimum so far
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_EQUEUE_POST, qsId)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_OBJ_PRE(this); // this queue object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_EQC_PRE(m_nMin); // min # free entries
QS_END_PRE()
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (m_frontEvt == nullptr) { // is the queue empty?
2022-08-11 15:36:19 -04:00
m_frontEvt = e; // deliver event directly
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(211, m_frontEvt_dis
== static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr)));
m_frontEvt_dis = static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(e));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
else { // queue was not empty, insert event into the ring-buffer
2024-10-15 13:15:28 -04:00
tmp = m_head; // get volatile into temporary
#ifndef Q_UNSAFE
dis = static_cast&lt;QEQueueCtr&gt;(~m_head_dis);
Q_INVARIANT_INCRIT(212, tmp == dis);
#endif // ndef Q_UNSAFE
m_ring[tmp] = e; // insert e into buffer
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (tmp == 0U) { // need to wrap the head?
tmp = m_end;
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
--tmp; // advance head (counter-clockwise)
m_head = tmp; // update the original
#ifndef Q_UNSAFE
m_head_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
status = true; // event posted successfully
}
else { // event cannot be posted
// dropping events must be acceptable
Q_ASSERT_INCRIT(210, margin != QF::NO_MARGIN);
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_EQUEUE_POST_ATTEMPT, qsId)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of this event
QS_OBJ_PRE(this); // this queue object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_EQC_PRE(margin); // margin requested
QS_END_PRE()
2022-08-11 15:36:19 -04:00
status = false; // event not posted
}
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return status;</code>
</operation>
<!--${QF::QEQueue::postLIFO}-->
<operation name="postLIFO" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QEQueue::postLIFO::e}-->
<parameter name="e" type="QEvt const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QEQueue::postLIFO::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(300, e != nullptr);
Q_INVARIANT_INCRIT(301, e-&gt;verify_());
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QEQueueCtr tmp = m_nFree; // get volatile into temporary
#ifndef Q_UNSAFE
QEQueueCtr dis = static_cast&lt;QEQueueCtr&gt;(~m_nFree_dis);
Q_INVARIANT_INCRIT(301, tmp == dis);
#endif // ndef Q_UNSAFE
// test-probe#1 for faking queue overflow
QS_TEST_PROBE_DEF(&amp;QEQueue::postLIFO)
QS_TEST_PROBE_ID(1,
tmp = 0U; // fake no free events
)
// must be able to LIFO-post the event
Q_REQUIRE_INCRIT(310, tmp != 0U);
2022-08-11 15:36:19 -04:00
2024-01-17 07:50:09 -05:00
if (e-&gt;getPoolNum_() != 0U) { // is it a mutable event?
2022-11-17 14:13:33 -05:00
QEvt_refCtr_inc_(e); // increment the reference counter
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
--tmp; // one free entry just used up
m_nFree = tmp; // update the original
#ifndef Q_UNSAFE
m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
if (m_nMin &gt; tmp) {
m_nMin = tmp; // update minimum so far
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_EQUEUE_POST_LIFO, qsId)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of this event
QS_OBJ_PRE(this); // this queue object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_EQC_PRE(m_nMin); // min # free entries
QS_END_PRE()
2022-08-11 15:36:19 -04:00
QEvt const * const frontEvt = m_frontEvt; // read into temporary
2024-10-15 13:15:28 -04:00
m_frontEvt = e; // deliver the event directly to the front
#ifndef Q_UNSAFE
m_frontEvt_dis = static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(e));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
if (frontEvt != nullptr) { // was the queue NOT empty?
tmp = m_tail; // get volatile into temporary;
#ifndef Q_UNSAFE
dis = static_cast&lt;QEQueueCtr&gt;(~m_tail_dis);
Q_INVARIANT_INCRIT(311, tmp == dis);
#endif // ndef Q_UNSAFE
++tmp;
if (tmp == m_end) { // need to wrap the tail?
tmp = 0U; // wrap around
}
m_tail = tmp;
#ifndef Q_UNSAFE
m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif
m_ring[tmp] = frontEvt;
2022-08-11 15:36:19 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QEQueue::get}-->
<operation name="get" type="QEvt const *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
2024-01-17 07:50:09 -05:00
<!--${QF::QEQueue::get::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QEvt const * const e = m_frontEvt; // always remove evt from the front
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e)
== static_cast&lt;std::uintptr_t&gt;(~m_frontEvt_dis));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
if (e != nullptr) { // was the queue not empty?
2024-10-15 13:15:28 -04:00
QEQueueCtr tmp = m_nFree; // get volatile into temporary
#ifndef Q_UNSAFE
QEQueueCtr const dis = static_cast&lt;QEQueueCtr&gt;(~m_nFree_dis);
Q_INVARIANT_INCRIT(412, tmp == dis);
#endif // ndef Q_UNSAFE
2024-06-12 16:30:04 -04:00
2024-10-15 13:15:28 -04:00
++tmp; // one more free event in the queue
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
m_nFree = tmp; // update the # free
#ifndef Q_UNSAFE
m_nFree_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
// any events in the ring buffer?
if (tmp &lt;= m_end) {
QS_BEGIN_PRE(QS_QF_EQUEUE_GET, qsId)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of this event
QS_OBJ_PRE(this); // this queue object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_EQC_PRE(tmp); // # free entries
QS_END_PRE()
tmp = m_tail; // get volatile into temporary
QEvt const * const frontEvt = m_ring[tmp];
#ifndef Q_UNSAFE
Q_ASSERT_INCRIT(421, frontEvt != nullptr);
m_frontEvt_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(frontEvt));
#endif // ndef Q_UNSAFE
m_frontEvt = frontEvt; // update the original
if (tmp == 0U) { // need to wrap the tail?
tmp = m_end;
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
--tmp; // advance the tail (counter-clockwise)
m_tail = tmp; // update the original
#ifndef Q_UNSAFE
m_tail_dis = static_cast&lt;QEQueueCtr&gt;(~tmp);
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
else {
m_frontEvt = nullptr; // queue becomes empty
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_frontEvt_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(nullptr));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// all entries in the queue must be free (+1 for frontEvt)
Q_INVARIANT_INCRIT(440, tmp == (m_end + 1U));
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_EQUEUE_GET_LAST, qsId)
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of this event
QS_OBJ_PRE(this); // this queue object
QS_2U8_PRE(e-&gt;getPoolNum_(), e-&gt;refCtr_);
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
}
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return e;</code>
</operation>
<!--${QF::QEQueue::getNFree}-->
<operation name="getNFree" type="QEQueueCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_nFree;</code>
</operation>
<!--${QF::QEQueue::getNMin}-->
<operation name="getNMin" type="QEQueueCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
2024-10-15 13:15:28 -04:00
<code>#ifndef Q_UNSAFE
return m_nMin;
#else
return 0U;
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QEQueue::isEmpty}-->
<operation name="isEmpty" type="bool" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_frontEvt == nullptr;</code>
</operation>
<!--${QF::QEQueue::QEQueue}-->
<operation name="QEQueue" type="" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QEQueue::QEQueue::other}-->
<parameter name="other" type="QEQueue const &amp;"/>
</operation>
<!--${QF::QEQueue::operator=}-->
<operation name="operator=" type="QEQueue &amp;" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QEQueue::operator=::other}-->
<parameter name="other" type="QEQueue const &amp;"/>
</operation>
</class>
<!--${QF::QFreeBlock}-->
<class name="QFreeBlock">
<!--${QF::QFreeBlock::m_next}-->
<attribute name="m_next" type="QFreeBlock *" visibility="0x02" properties="0x00"/>
<!--${QF::QFreeBlock::m_next_dis}-->
<attribute name="m_next_dis?ndef Q_UNSAFE" type="std::uintptr_t" visibility="0x02" properties="0x00"/>
<!--${QF::QFreeBlock::QMPool}-->
<attribute name="QMPool" type="friend class" visibility="0x02" properties="0x00"/>
</class>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool}-->
<class name="QMPool">
<!--${QF::QMPool::m_start}-->
<attribute name="m_start" type="QFreeBlock *" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::m_end}-->
<attribute name="m_end" type="QFreeBlock *" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::m_free_head}-->
<attribute name="m_free_head" type="QFreeBlock * volatile" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::m_blockSize}-->
<attribute name="m_blockSize" type="QMPoolSize" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::m_nTot}-->
<attribute name="m_nTot" type="QMPoolCtr" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::m_nFree}-->
<attribute name="m_nFree" type="QMPoolCtr volatile" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::m_nMin}-->
2024-10-15 13:15:28 -04:00
<attribute name="m_nMin?ndef Q_UNSAFE" type="QMPoolCtr" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_free_head_dis}-->
<attribute name="m_free_head_dis?ndef Q_UNSAFE" type="std::uintptr_t" visibility="0x02" properties="0x00"/>
<!--${QF::QMPool::m_nFree_dis}-->
<attribute name="m_nFree_dis?ndef Q_UNSAFE" type="QMPoolCtr" visibility="0x02" properties="0x00"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::QMPool}-->
<operation name="QMPool" type="" visibility="0x00" properties="0x02">
2022-08-11 15:36:19 -04:00
<code> : m_start(nullptr),
m_end(nullptr),
m_free_head(nullptr),
m_blockSize(0U),
m_nTot(0U),
2024-10-15 13:15:28 -04:00
m_nFree(0U)
#ifndef Q_UNSAFE
,m_nMin(0U),
m_free_head_dis(static_cast&lt;std::uintptr_t&gt;(~0U)),
m_nFree_dis(static_cast&lt;QEQueueCtr&gt;(~0U))
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMPool::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::init::poolSto}-->
<parameter name="poolSto" type="void * const"/>
<!--${QF::QMPool::init::poolSize}-->
<parameter name="poolSize" type="std::uint_fast32_t const"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QMPool::init::blockSize}-->
<parameter name="blockSize" type="std::uint_fast16_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(100, poolSto != nullptr);
Q_REQUIRE_INCRIT(101,
poolSize &gt;= static_cast&lt;std::uint_fast32_t&gt;(sizeof(QFreeBlock)));
Q_REQUIRE_INCRIT(102,
static_cast&lt;std::uint_fast16_t&gt;(blockSize + sizeof(QFreeBlock))
&gt; blockSize);
2022-08-11 15:36:19 -04:00
m_free_head = static_cast&lt;QFreeBlock *&gt;(poolSto);
2022-08-11 15:36:19 -04:00
// find # free blocks in a memory block, NO DIVISION
2024-10-15 13:15:28 -04:00
m_blockSize = static_cast&lt;QMPoolSize&gt;(2U * sizeof(void *));
2022-08-11 15:36:19 -04:00
std::uint_fast16_t nblocks = 1U;
while (m_blockSize &lt; static_cast&lt;QMPoolSize&gt;(blockSize)) {
m_blockSize += static_cast&lt;QMPoolSize&gt;(sizeof(QFreeBlock));
++nblocks;
}
// the pool buffer must fit at least one rounded-up block
Q_ASSERT_INCRIT(110, poolSize &gt;= m_blockSize);
2022-08-11 15:36:19 -04:00
// start at the head of the free list
QFreeBlock *fb = m_free_head;
2024-06-07 16:07:22 -04:00
std::uint32_t nTot = 1U; // the last block already in the list
2022-08-11 15:36:19 -04:00
// chain all blocks together in a free-list...
for (std::uint_fast32_t size = poolSize - m_blockSize;
size &gt;= static_cast&lt;std::uint_fast32_t&gt;(m_blockSize);
size -= static_cast&lt;std::uint_fast32_t&gt;(m_blockSize))
{
fb-&gt;m_next = &amp;fb[nblocks]; // point next link to next block
#ifndef Q_UNSAFE
2024-10-15 13:15:28 -04:00
fb-&gt;m_next_dis = ~Q_PTR2UINT_CAST_(fb-&gt;m_next);
#endif
fb = fb-&gt;m_next; // advance to the next block
2024-06-07 16:07:22 -04:00
++nTot; // one more free block in the pool
2022-08-11 15:36:19 -04:00
}
2024-06-07 16:07:22 -04:00
// dynamic range check
#if (QF_MPOOL_CTR_SIZE == 1U)
Q_ENSURE_INCRIT(190, nTot &lt; 0xFFU);
#elif (QF_MPOOL_CTR_SIZE == 2U)
Q_ENSURE_INCRIT(190, nTot &lt; 0xFFFFU);
#endif
fb-&gt;m_next = nullptr; // the last link points to NULL
2024-06-07 16:07:22 -04:00
m_nTot = static_cast&lt;QMPoolCtr&gt;(nTot);
m_nFree = m_nTot; // all blocks are free
m_start = static_cast&lt;QFreeBlock *&gt;(poolSto); // original start
m_end = fb; // the last block in this pool
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_free_head_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(m_free_head));
m_nFree_dis = static_cast&lt;QMPoolCtr&gt;(~m_nFree);
m_nMin = m_nTot; // the minimum # free blocks
fb-&gt;m_next_dis = ~Q_PTR2UINT_CAST_(fb-&gt;m_next);
#endif
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMPool::get}-->
<operation name="get" type="void *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::get::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QMPool::get::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
2022-08-11 15:36:19 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// get volatile into temporaries
QFreeBlock *fb = m_free_head;
QMPoolCtr nFree = m_nFree;
#ifndef Q_UNSAFE
Q_INVARIANT_INCRIT(301, Q_PTR2UINT_CAST_(fb)
== static_cast&lt;std::uintptr_t&gt;(~m_free_head_dis));
Q_INVARIANT_INCRIT(302, nFree == static_cast&lt;QMPoolCtr&gt;(~m_nFree_dis));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// have more free blocks than the requested margin?
if (nFree &gt; static_cast&lt;QMPoolCtr&gt;(margin)) {
Q_ASSERT_INCRIT(310, fb != nullptr);
2022-08-11 15:36:19 -04:00
QFreeBlock * const fb_next = fb-&gt;m_next;
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
// the free block must have integrity (duplicate inverse storage)
2024-10-15 13:15:28 -04:00
Q_INVARIANT_INCRIT(311, Q_PTR2UINT_CAST_(fb_next)
== static_cast&lt;std::uintptr_t&gt;(~fb-&gt;m_next_dis));
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
--nFree; // one less free block
if (nFree == 0U) { // is the pool becoming empty?
2022-08-11 15:36:19 -04:00
// pool is becoming empty, so the next free block must be NULL
Q_ASSERT_INCRIT(320, fb_next == nullptr);
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
m_nFree = 0U;
#ifndef Q_UNSAFE
m_nFree_dis = static_cast&lt;QMPoolCtr&gt;(~m_nFree);
m_nMin = 0U; // remember that the pool got empty
2024-10-15 13:15:28 -04:00
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
else {
2024-10-15 13:15:28 -04:00
m_nFree = nFree; // update the original
#ifndef Q_UNSAFE
m_nFree_dis = static_cast&lt;QMPoolCtr&gt;(~nFree);
// The pool is not empty, so the next free-block pointer
// must be in range.
Q_INVARIANT_INCRIT(330,
QF_PTR_RANGE_(fb_next, m_start, m_end));
2022-08-11 15:36:19 -04:00
// is the # free blocks the new minimum so far?
2024-10-15 13:15:28 -04:00
if (m_nMin &gt; nFree) {
m_nMin = nFree; // remember the minimum so far
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
#endif // ndef Q_UNSAFE
2022-08-11 15:36:19 -04:00
}
m_free_head = fb_next; // set the head to the next free block
2024-10-15 13:15:28 -04:00
#ifndef Q_UNSAFE
m_free_head_dis =
static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(fb_next));
#endif // ndef Q_UNSAFE
QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(this); // this memory pool
QS_MPC_PRE(nFree); // # of free blocks in the pool
#ifndef Q_UNSAFE
QS_MPC_PRE(m_nMin); // min # free blocks ever in the pool
#else
QS_MPC_PRE(0U); // min # free blocks (not available)
#endif // ndef Q_UNSAFE
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
else { // don't have enough free blocks at this point
2022-08-11 15:36:19 -04:00
fb = nullptr;
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(this); // this memory pool
QS_MPC_PRE(nFree); // # of free blocks in the pool
QS_MPC_PRE(margin); // the requested margin
QS_END_PRE()
2022-08-11 15:36:19 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();
return fb; // return the block or nullptr to the caller</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMPool::put}-->
<operation name="put" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::put::block}-->
<parameter name="block" type="void * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QMPool::put::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>#ifndef Q_SPY
2024-01-17 07:50:09 -05:00
Q_UNUSED_PAR(qsId);
#endif
2022-08-11 15:36:19 -04:00
QFreeBlock * const fb = static_cast&lt;QFreeBlock *&gt;(block);
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-10-15 13:15:28 -04:00
// get volatile into temporaries
QFreeBlock * const free_head = m_free_head;
QMPoolCtr nFree = m_nFree;
#ifndef Q_UNSAFE
2024-10-15 13:15:28 -04:00
Q_INVARIANT_INCRIT(401, Q_PTR2UINT_CAST_(free_head)
== static_cast&lt;std::uintptr_t&gt;(~m_free_head_dis));
Q_INVARIANT_INCRIT(402, nFree == static_cast&lt;QMPoolCtr&gt;(~m_nFree_dis));
Q_REQUIRE_INCRIT(410, nFree &lt; m_nTot);
Q_REQUIRE_INCRIT(411, QF_PTR_RANGE_(fb, m_start, m_end));
2024-10-15 13:15:28 -04:00
// the block must not be in the pool already
Q_REQUIRE_INCRIT(412, Q_PTR2UINT_CAST_(fb-&gt;m_next)
!= static_cast&lt;std::uintptr_t&gt;(~fb-&gt;m_next_dis));
#endif // ndef Q_UNSAFE
2024-10-15 13:15:28 -04:00
++nFree; // one more free block in this pool
2024-10-15 13:15:28 -04:00
m_free_head = fb; // set as new head of the free list
m_nFree = nFree;
fb-&gt;m_next = free_head; // link into the list
#ifndef Q_UNSAFE
m_free_head_dis = static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(fb));
m_nFree_dis = static_cast&lt;QMPoolCtr&gt;(~nFree);
fb-&gt;m_next_dis = static_cast&lt;std::uintptr_t&gt;(~Q_PTR2UINT_CAST_(free_head));
#endif
QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId)
QS_TIME_PRE(); // timestamp
QS_OBJ_PRE(this); // this memory pool
QS_MPC_PRE(nFree); // the # free blocks in the pool
QS_END_PRE()
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMPool::getBlockSize}-->
<operation name="getBlockSize" type="QMPoolSize" visibility="0x00" properties="0x00">
<specifiers>const noexcept</specifiers>
<code>return m_blockSize;</code>
</operation>
<!--${QF::QMPool::getNMin}-->
<operation name="getNMin" type="QMPoolCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
2024-10-15 13:15:28 -04:00
<code>#ifndef Q_UNSAFE
return m_nMin;
#else
return 0U;
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMPool::getNFree}-->
<operation name="getNFree" type="QMPoolCtr" visibility="0x00" properties="0x02">
<specifiers>const noexcept</specifiers>
<code>return m_nFree;</code>
</operation>
<!--${QF::QMPool::QMPool}-->
<operation name="QMPool" type="" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QMPool::QMPool::other}-->
<parameter name="other" type="QEQueue const &amp;"/>
</operation>
<!--${QF::QMPool::operator=}-->
<operation name="operator=" type="QMPool &amp;" visibility="0x02" properties="0x00">
<specifiers>= delete</specifiers>
<!--${QF::QMPool::operator=::other}-->
<parameter name="other" type="QMPool const &amp;"/>
</operation>
<!--${QF::QMPool::getFromISR}-->
<operation name="getFromISR?def QF_ISR_API" type="void *" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::getFromISR::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QMPool::getFromISR::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QMPool::putFromISR}-->
<operation name="putFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
<!--${QF::QMPool::putFromISR::b}-->
<parameter name="b" type="void * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QMPool::putFromISR::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
2022-08-11 15:36:19 -04:00
</operation>
</class>
<!--${QF::QF-pkg}-->
<package name="QF-pkg" stereotype="0x02" namespace="QF::">
<!--${QF::QF-pkg::Attr}-->
<class name="Attr">
<!--${QF::QF-pkg::Attr::ePool_[QF_MAX_EPOOL]}-->
<attribute name="ePool_[QF_MAX_EPOOL]? (QF_MAX_EPOOL &gt; 0U)" type="QF_EPOOL_TYPE_" visibility="0x00" properties="0x00"/>
<!--${QF::QF-pkg::Attr::maxPool_}-->
<attribute name="maxPool_? (QF_MAX_EPOOL &gt; 0U)" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QF::QF-pkg::Attr::dummy}-->
<attribute name="dummy? (QF_MAX_EPOOL == 0U)" type="std::uint8_t" visibility="0x00" properties="0x00"/>
</class>
<!--${QF::QF-pkg::priv_}-->
<attribute name="priv_" type="QF::Attr" visibility="0x00" properties="0x00"/>
<!--${QF::QF-pkg::bzero_}-->
<operation name="bzero_" type="void" visibility="0x00" properties="0x01">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QF::QF-pkg::bzero_::start}-->
<parameter name="start" type="void * const"/>
<!--${QF::QF-pkg::bzero_::len}-->
<parameter name="len" type="std::uint_fast16_t const"/>
<code>std::uint8_t *ptr = static_cast&lt;std::uint8_t *&gt;(start);
for (std::uint_fast16_t n = len; n &gt; 0U; --n) {
*ptr = 0U;
++ptr;
2022-08-11 15:36:19 -04:00
}</code>
</operation>
</package>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base}-->
<package name="QF-base" stereotype="0x02" namespace="QF::">
<!--${QF::QF-base::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x01"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base::stop}-->
<operation name="stop" type="void" visibility="0x00" properties="0x01"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base::onStartup}-->
<operation name="onStartup" type="void" visibility="0x00" properties="0x01"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base::onCleanup}-->
<operation name="onCleanup" type="void" visibility="0x00" properties="0x01"/>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base::psInit}-->
<operation name="psInit" type="void" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base::psInit::subscrSto}-->
<parameter name="subscrSto" type="QSubscrList * const"/>
<!--${QF::QF-base::psInit::maxSignal}-->
<parameter name="maxSignal" type="enum_t const"/>
<code>QActive::psInit(subscrSto, maxSignal);</code>
</operation>
<!--${QF::QF-base::publish_}-->
<operation name="publish_" type="void" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
2022-08-11 15:36:19 -04:00
<!--${QF::QF-base::publish_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QF-base::publish_::sender}-->
<parameter name="sender" type="void const * const"/>
2024-01-17 07:50:09 -05:00
<!--${QF::QF-base::publish_::qsId}-->
<parameter name="qsId" type="std::uint_fast8_t const"/>
<code>QActive::publish_(e, sender, qsId);</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QF-base::tick}-->
<operation name="tick" type="void" visibility="0x00" properties="0x03">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
<!--${QF::QF-base::tick::tickRate}-->
2022-08-11 15:36:19 -04:00
<parameter name="tickRate" type="std::uint_fast8_t const"/>
<!--${QF::QF-base::tick::sender}-->
2022-08-11 15:36:19 -04:00
<parameter name="sender" type="void const * const"/>
<code>QTimeEvt::tick(tickRate, sender);</code>
</operation>
<!--${QF::QF-base::getQueueMin}-->
<operation name="getQueueMin" type="std::uint_fast16_t" visibility="0x00" properties="0x03">
<specifiers>noexcept</specifiers>
<documentation>//! @deprecated</documentation>
<!--${QF::QF-base::getQueueMin::prio}-->
<parameter name="prio" type="std::uint_fast8_t const"/>
<code>return QActive::getQueueMin(prio);</code>
2022-08-11 15:36:19 -04:00
</operation>
2022-09-22 11:13:20 -04:00
<!--${QF::QF-base::NO_MARGIN}-->
<attribute name="NO_MARGIN" type="constexpr std::uint_fast16_t" visibility="0x04" properties="0x00">
<code>{0xFFFFU};</code>
</attribute>
2022-08-11 15:36:19 -04:00
</package>
<!--${QF::QF-dyn}-->
<package name="QF-dyn" stereotype="0x02" namespace="QF::">
<!--${QF::QF-dyn::poolInit}-->
<operation name="poolInit" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::poolInit::poolSto}-->
<parameter name="poolSto" type="void * const"/>
<!--${QF::QF-dyn::poolInit::poolSize}-->
<parameter name="poolSize" type="std::uint_fast32_t const"/>
<!--${QF::QF-dyn::poolInit::evtSize}-->
<parameter name="evtSize" type="std::uint_fast16_t const"/>
2024-01-17 07:50:09 -05:00
<code>std::uint_fast8_t const poolNum = priv_.maxPool_;
// see precondition{qf_dyn,200} and precondition{qf_dyn,201}
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-01-17 07:50:09 -05:00
Q_REQUIRE_INCRIT(200, poolNum &lt; QF_MAX_EPOOL);
if (poolNum &gt; 0U) {
Q_REQUIRE_INCRIT(201,
2024-01-17 07:50:09 -05:00
QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum - 1U]) &lt; evtSize);
2022-08-11 15:36:19 -04:00
}
2024-01-17 07:50:09 -05:00
priv_.maxPool_ = poolNum + 1U; // one more pool
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
// perform the port-dependent initialization of the event-pool
2024-01-17 07:50:09 -05:00
QF_EPOOL_INIT_(priv_.ePool_[poolNum], poolSto, poolSize, evtSize);
2022-08-11 15:36:19 -04:00
#ifdef Q_SPY
// generate the object-dictionary entry for the initialized pool
{
std::uint8_t obj_name[9] = &quot;EvtPool?&quot;;
obj_name[7] = static_cast&lt;std::uint8_t&gt;(
static_cast&lt;std::uint8_t&gt;('0')
2024-01-17 07:50:09 -05:00
+ static_cast&lt;std::uint8_t&gt;(poolNum + 1U));
QS::obj_dict_pre_(&amp;priv_.ePool_[poolNum],
reinterpret_cast&lt;char *&gt;(&amp;obj_name[0]));
}
2022-08-11 15:36:19 -04:00
#endif // Q_SPY</code>
</operation>
<!--${QF::QF-dyn::poolGetMaxBlockSize}-->
<operation name="poolGetMaxBlockSize" type="std::uint_fast16_t" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
std::uint_fast16_t const max_size =
QF_EPOOL_EVENT_SIZE_(priv_.ePool_[priv_.maxPool_ - 1U]);
QF_MEM_APP();
QF_CRIT_EXIT();
return max_size;</code>
</operation>
<!--${QF::QF-dyn::getPoolMin}-->
<operation name="getPoolMin" type="std::uint_fast16_t" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
2024-01-17 07:50:09 -05:00
<!--${QF::QF-dyn::getPoolMin::poolNum}-->
<parameter name="poolNum" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-01-17 07:50:09 -05:00
Q_REQUIRE_INCRIT(400, (poolNum &lt;= QF_MAX_EPOOL)
&amp;&amp; (0U &lt; poolNum) &amp;&amp; (poolNum &lt;= priv_.maxPool_));
std::uint_fast16_t const min = static_cast&lt;std::uint_fast16_t&gt;(
2024-01-17 07:50:09 -05:00
priv_.ePool_[poolNum - 1U].getNMin());
QF_MEM_APP();
QF_CRIT_EXIT();
return min;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QF-dyn::newX_}-->
<operation name="newX_" type="QEvt *" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::newX_::evtSize}-->
<parameter name="evtSize" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newX_::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newX_::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
// find the pool id that fits the requested event size...
2024-01-17 07:50:09 -05:00
std::uint_fast8_t poolNum = 0U; // zero-based poolNum initially
for (; poolNum &lt; priv_.maxPool_; ++poolNum) {
if (evtSize &lt;= QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum])) {
2022-08-11 15:36:19 -04:00
break;
}
}
// precondition:
// - cannot run out of registered pools
2024-01-17 07:50:09 -05:00
Q_REQUIRE_INCRIT(300, poolNum &lt; priv_.maxPool_);
2024-01-17 07:50:09 -05:00
++poolNum; // convert to 1-based poolNum
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// get event e (port-dependent)...
QEvt *e;
2022-08-11 15:36:19 -04:00
#ifdef Q_SPY
2024-01-17 07:50:09 -05:00
QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
((margin != NO_MARGIN) ? margin : 0U),
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum);
2022-08-11 15:36:19 -04:00
#else
2024-01-17 07:50:09 -05:00
QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
((margin != NO_MARGIN) ? margin : 0U), 0U);
2022-08-11 15:36:19 -04:00
#endif
if (e != nullptr) { // was e allocated correctly?
2022-08-11 15:36:19 -04:00
e-&gt;sig = static_cast&lt;QSignal&gt;(sig); // set the signal
2024-10-15 13:15:28 -04:00
e-&gt;evtTag_ = static_cast&lt;std::uint8_t&gt;((poolNum &lt;&lt; 4U) | 0x0FU);
2022-08-11 15:36:19 -04:00
e-&gt;refCtr_ = 0U; // initialize the reference counter to 0
QS_CRIT_ENTRY();
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_NEW,
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
2024-10-15 13:15:28 -04:00
QS_TIME_PRE(); // timestamp
QS_EVS_PRE(evtSize); // the size of the event
QS_SIG_PRE(sig); // the signal of the event
QS_END_PRE()
QS_MEM_APP();
QS_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
else { // event was not allocated
QF_CRIT_ENTRY();
2022-08-11 15:36:19 -04:00
// This assertion means that the event allocation failed,
// and this failure cannot be tolerated. The most frequent
// reason is an event leak in the application.
Q_ASSERT_INCRIT(320, margin != NO_MARGIN);
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT,
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
2024-10-15 13:15:28 -04:00
QS_TIME_PRE(); // timestamp
QS_EVS_PRE(evtSize); // the size of the event
QS_SIG_PRE(sig); // the signal of the event
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}
// the returned event e is guaranteed to be valid (not NULL)
// if we can't tolerate failed allocation
return e;</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF::QF-dyn::gc}-->
<operation name="gc" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::gc::e}-->
<parameter name="e" type="QEvt const * const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(400, e != nullptr);
Q_INVARIANT_INCRIT(401, e-&gt;verify_());
2022-08-11 15:36:19 -04:00
2024-01-17 07:50:09 -05:00
std::uint_fast8_t const poolNum = e-&gt;getPoolNum_();
2022-08-11 15:36:19 -04:00
2024-01-17 07:50:09 -05:00
if (poolNum != 0U) { // is it a pool event (mutable)?
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
if (e-&gt;refCtr_ &gt; 1U) { // isn't this the last reference?
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_GC_ATTEMPT,
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
2024-10-15 13:15:28 -04:00
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_2U8_PRE(poolNum, e-&gt;refCtr_);
QS_END_PRE()
2022-08-11 15:36:19 -04:00
QEvt_refCtr_dec_(e); // decrement the ref counter
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
}
else { // this is the last reference to this event, recycle it
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_GC,
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
2024-10-15 13:15:28 -04:00
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_2U8_PRE(poolNum, e-&gt;refCtr_);
QS_END_PRE()
2022-08-11 15:36:19 -04:00
// pool number must be in range
2024-01-17 07:50:09 -05:00
Q_ASSERT_INCRIT(410, (poolNum &lt;= priv_.maxPool_)
&amp;&amp; (poolNum &lt;= QF_MAX_EPOOL));
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
// NOTE: casting 'const' away is legit because it's a pool event
2022-08-11 15:36:19 -04:00
#ifdef Q_SPY
2024-01-17 07:50:09 -05:00
QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
QF_CONST_CAST_(QEvt*, e),
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum);
2022-08-11 15:36:19 -04:00
#else
2024-01-17 07:50:09 -05:00
QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
QF_CONST_CAST_(QEvt*, e), 0U);
2022-08-11 15:36:19 -04:00
#endif
}
}
else {
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
}</code>
</operation>
<!--${QF::QF-dyn::newRef_}-->
<operation name="newRef_" type="QEvt const *" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::newRef_::e}-->
<parameter name="e" type="QEvt const * const"/>
<!--${QF::QF-dyn::newRef_::evtRef}-->
<parameter name="evtRef" type="QEvt const * const"/>
<code>#ifdef Q_UNSAFE
Q_UNUSED_PAR(evtRef);
#endif
2022-08-11 15:36:19 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(500, e != nullptr);
Q_INVARIANT_INCRIT(501, e-&gt;verify_());
2024-01-17 07:50:09 -05:00
std::uint_fast8_t const poolNum = e-&gt;getPoolNum_();
2024-06-12 16:30:04 -04:00
Q_UNUSED_PAR(poolNum); // might be unused
2024-06-12 16:30:04 -04:00
Q_REQUIRE_INCRIT(501, (poolNum != 0U)
&amp;&amp; (evtRef == nullptr));
2022-08-11 15:36:19 -04:00
2022-11-17 14:13:33 -05:00
QEvt_refCtr_inc_(e); // increments the ref counter
2022-08-11 15:36:19 -04:00
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_NEW_REF,
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
2024-10-15 13:15:28 -04:00
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_2U8_PRE(poolNum, e-&gt;refCtr_);
QS_END_PRE()
QS_MEM_APP();
2022-08-11 15:36:19 -04:00
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return e;</code>
</operation>
<!--${QF::QF-dyn::deleteRef_}-->
<operation name="deleteRef_" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::deleteRef_::evtRef}-->
<parameter name="evtRef" type="QEvt const * const"/>
2024-06-12 16:30:04 -04:00
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
2024-06-12 16:30:04 -04:00
QEvt const * const e = evtRef;
2024-10-15 13:15:28 -04:00
Q_REQUIRE_INCRIT(600, e != nullptr);
Q_INVARIANT_INCRIT(601, e-&gt;verify_());
#ifdef Q_SPY
2024-01-17 07:50:09 -05:00
std::uint_fast8_t const poolNum = e-&gt;getPoolNum_();
#endif
QS_MEM_SYS();
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_QF_DELETE_REF,
2024-01-17 07:50:09 -05:00
static_cast&lt;std::uint_fast8_t&gt;(QS_EP_ID) + poolNum)
2024-10-15 13:15:28 -04:00
QS_TIME_PRE(); // timestamp
QS_SIG_PRE(e-&gt;sig); // the signal of the event
QS_2U8_PRE(poolNum, e-&gt;refCtr_);
QS_END_PRE()
QS_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
2022-09-09 16:34:14 -04:00
#if (QF_MAX_EPOOL &gt; 0U)
2024-06-12 16:30:04 -04:00
gc(e); // recycle the referenced event
2022-09-09 16:34:14 -04:00
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
2024-06-05 15:09:15 -04:00
<!--${QF::QF-dyn::q_new}-->
2024-06-07 16:07:22 -04:00
<operation name="q_new?ndef QEVT_PAR_INIT" type="template&lt;class evtT_&gt;&#10;evtT_ *" visibility="0x00" properties="0x02">
2024-06-05 15:09:15 -04:00
<!--${QF::QF-dyn::q_new::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>return static_cast&lt;evtT_*&gt;(
QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, sig));</code>
</operation>
<!--${QF::QF-dyn::q_new}-->
2024-06-07 16:07:22 -04:00
<operation name="q_new?def QEVT_PAR_INIT" type="template&lt;class evtT_, typename... Args&gt;&#10;evtT_ *" visibility="0x00" properties="0x02">
2024-06-05 15:09:15 -04:00
<!--${QF::QF-dyn::q_new::sig}-->
<parameter name="sig" type="enum_t const"/>
<!--${QF::QF-dyn::q_new::args}-->
<parameter name="args" type="Args..."/>
<code>evtT_ *e = static_cast&lt;evtT_*&gt;(
QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, sig));
2024-06-07 16:07:22 -04:00
e-&gt;init(args...); // e cannot be nullptr
2024-06-05 15:09:15 -04:00
return e;</code>
</operation>
<!--${QF::QF-dyn::q_new_x}-->
2024-06-07 16:07:22 -04:00
<operation name="q_new_x?ndef QEVT_PAR_INIT" type="template&lt;class evtT_&gt;&#10;evtT_ *" visibility="0x00" properties="0x02">
2024-06-05 15:09:15 -04:00
<!--${QF::QF-dyn::q_new_x::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::q_new_x::sig}-->
<parameter name="sig" type="enum_t const"/>
<code>return static_cast&lt;evtT_*&gt;(QP::QF::newX_(sizeof(evtT_), margin, sig));</code>
</operation>
<!--${QF::QF-dyn::q_new_x}-->
2024-06-07 16:07:22 -04:00
<operation name="q_new_x?def QEVT_PAR_INIT" type="template&lt;class evtT_, typename... Args&gt;&#10;evtT_ *" visibility="0x00" properties="0x02">
2024-06-05 15:09:15 -04:00
<!--${QF::QF-dyn::q_new_x::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::q_new_x::sig}-->
<parameter name="sig" type="enum_t const"/>
<!--${QF::QF-dyn::q_new_x::args}-->
<parameter name="args" type="Args..."/>
<code>evtT_ *e = static_cast&lt;evtT_*&gt;(QP::QF::newX_(sizeof(evtT_), margin, sig));
if (e != nullptr) {
2024-06-07 16:07:22 -04:00
e-&gt;init(args...);
2024-06-05 15:09:15 -04:00
}
return e;</code>
</operation>
<!--${QF::QF-dyn::q_new_ref}-->
<operation name="q_new_ref" type="template&lt;class evtT_&gt;&#10;void" visibility="0x00" properties="0x02">
<!--${QF::QF-dyn::q_new_ref::e}-->
<parameter name="e" type="QP::QEvt const * const"/>
<!--${QF::QF-dyn::q_new_ref::evtRef}-->
<parameter name="evtRef" type="evtT_ const *&amp;"/>
<code>evtRef = static_cast&lt;evtT_ const *&gt;(QP::QF::newRef_(e, evtRef));</code>
</operation>
<!--${QF::QF-dyn::q_delete_ref}-->
<operation name="q_delete_ref" type="template&lt;class evtT_&gt; void" visibility="0x00" properties="0x02">
<!--${QF::QF-dyn::q_delete_ref::evtRef}-->
<parameter name="evtRef" type="evtT_ const *&amp;"/>
<code>QP::QF::deleteRef_(evtRef);
evtRef = nullptr;</code>
</operation>
2024-06-07 16:07:22 -04:00
<!--${QF::QF-dyn::newXfromISR_}-->
<operation name="newXfromISR_?def QF_ISR_API" type="QEvt *" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::newXfromISR_::evtSize}-->
<parameter name="evtSize" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newXfromISR_::margin}-->
<parameter name="margin" type="std::uint_fast16_t const"/>
<!--${QF::QF-dyn::newXfromISR_::sig}-->
<parameter name="sig" type="enum_t const"/>
</operation>
<!--${QF::QF-dyn::gcFromISR}-->
<operation name="gcFromISR?def QF_ISR_API" type="void" visibility="0x00" properties="0x01">
<specifiers>noexcept</specifiers>
<!--${QF::QF-dyn::gcFromISR::e}-->
<parameter name="e" type="QEvt const *"/>
</operation>
2022-08-11 15:36:19 -04:00
</package>
</package>
<!--${QF-extern-C}-->
<package name="QF-extern-C" stereotype="0x02">
<!--${QF-extern-C::QF_onContextSw}-->
<operation name="QF_onContextSw?def QF_ON_CONTEXT_SW" type="void" visibility="0x00" properties="0x00">
<!--${QF-extern-C::QF_onContextSw::prev}-->
<parameter name="prev" type="QP::QActive *"/>
<!--${QF-extern-C::QF_onContextSw::next}-->
<parameter name="next" type="QP::QActive *"/>
2022-08-11 15:36:19 -04:00
</operation>
</package>
<!--${QF-macros}-->
<package name="QF-macros" stereotype="0x02">
<!--${QF-macros::Q_PRIO}-->
<operation name="Q_PRIO" type="QP::QPrioSpec" visibility="0x03" properties="0x02">
<!--${QF-macros::Q_PRIO::prio_}-->
<parameter name="prio_" type="std::uint8_t"/>
<!--${QF-macros::Q_PRIO::pthre_}-->
<parameter name="pthre_" type="std::uint8_t"/>
2022-08-11 15:36:19 -04:00
<code>\
(static_cast&lt;QP::QPrioSpec&gt;((prio_) | (pthre_) &lt;&lt; 8U))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::Q_NEW}-->
2024-06-07 16:07:22 -04:00
<operation name="Q_NEW?ndef QEVT_PAR_INIT" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
2024-06-05 15:09:15 -04:00
<code>(QP::QF::q_new&lt;evtT_&gt;((sig_)))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::Q_NEW}-->
2024-06-07 16:07:22 -04:00
<operation name="Q_NEW?def QEVT_PAR_INIT" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QF-macros::Q_NEW::...}-->
<parameter name="..." type="__VA_ARGS__"/>
2024-06-05 15:09:15 -04:00
<code>(QP::QF::q_new&lt;evtT_&gt;((sig_), __VA_ARGS__))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::Q_NEW_X}-->
2024-06-07 16:07:22 -04:00
<operation name="Q_NEW_X?ndef QEVT_PAR_INIT" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW_X::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::Q_NEW_X::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
2024-06-05 15:09:15 -04:00
<code>(QP::QF::q_new_x&lt;evtT_&gt;((margin_), (sig_)))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::Q_NEW_X}-->
2024-06-07 16:07:22 -04:00
<operation name="Q_NEW_X?def QEVT_PAR_INIT" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW_X::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::Q_NEW_X::sig_}-->
<parameter name="sig_" type="QP::QSignal"/>
<!--${QF-macros::Q_NEW_X::...}-->
<parameter name="..." type="__VA_ARGS__"/>
2024-06-05 15:09:15 -04:00
<code>(QP::QF::q_new_x&lt;evtT_&gt;((margin_), (sig_), __VA_ARGS__))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::Q_NEW_REF}-->
<operation name="Q_NEW_REF" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_NEW_REF::evtRef_}-->
<parameter name="evtRef_" type="&lt;event class&gt;"/>
<!--${QF-macros::Q_NEW_REF::evtT_}-->
<parameter name="evtT_" type="&lt;event class&gt;"/>
2024-06-05 15:09:15 -04:00
<code>(QP::QF::q_new_ref&lt;evtT_&gt;(e, (evtRef_)))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::Q_DELETE_REF}-->
<operation name="Q_DELETE_REF" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::Q_DELETE_REF::evtRef_}-->
<parameter name="evtRef_" type="&lt;event class&gt;"/>
<code>do { \
QP::QF::deleteRef_((evtRef_)); \
2024-06-05 15:09:15 -04:00
(evtRef_) = nullptr; \
} while (false)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::PUBLISH}-->
<operation name="PUBLISH?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::PUBLISH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::PUBLISH::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
2022-08-11 15:36:19 -04:00
<code>\
publish_((e_), (sender_), (sender_)-&gt;getPrio())</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::PUBLISH}-->
<operation name="PUBLISH?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::PUBLISH::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::PUBLISH::dummy}-->
<parameter name="dummy" type=""/>
<code>publish_((e_), nullptr, 0U)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::POST}-->
<operation name="POST?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST::sender_}-->
<parameter name="sender_" type="&lt;sender *&gt;"/>
<code>post_((e_), QP::QF::NO_MARGIN, (sender_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::POST}-->
<operation name="POST?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST::dummy}-->
<parameter name="dummy" type=""/>
<code>post_((e_), QP::QF::NO_MARGIN, nullptr)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::POST_X}-->
<operation name="POST_X?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST_X::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::POST_X::sender_}-->
<parameter name="sender_" type="&lt;sender *&gt;"/>
2022-08-11 15:36:19 -04:00
<code>\
post_((e_), (margin_), (sender_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::POST_X}-->
<operation name="POST_X?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::POST_X::e_}-->
<parameter name="e_" type="QP::QEvt const *"/>
<!--${QF-macros::POST_X::margin_}-->
<parameter name="margin_" type="std::uint16_t"/>
<!--${QF-macros::POST_X::dummy}-->
<parameter name="dummy" type=""/>
<code>post_((e_), (margin_), nullptr)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::TICK_X}-->
<operation name="TICK_X?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TICK_X::tickRate_}-->
<parameter name="tickRate_" type="std::uint_fast8_t const"/>
<!--${QF-macros::TICK_X::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
<code>tick((tickRate_), (sender_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::TICK_X}-->
<operation name="TICK_X?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TICK_X::tickRate_}-->
<parameter name="tickRate_" type="std::uint_fast8_t const"/>
<!--${QF-macros::TICK_X::dummy}-->
<parameter name="dummy" type=""/>
<code>tick((tickRate_), nullptr)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::TICK}-->
<operation name="TICK" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TICK::sender_}-->
<parameter name="sender_" type="&lt;sender *&gt;"/>
<code>TICK_X(0U, (sender_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::TRIG}-->
<operation name="TRIG?def Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TRIG::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
<code>trig_((sender_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::TRIG}-->
<operation name="TRIG?ndef Q_SPY" type="void" visibility="0x03" properties="0x00">
<!--${QF-macros::TRIG::sender_}-->
<parameter name="sender_" type="&lt;void const *&gt;"/>
<code>trig_(nullptr)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::QF_CRIT_EXIT_NOP}-->
<operation name="QF_CRIT_EXIT_NOP?ndef QF_CRIT_EXIT_NOP" type="void" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF-macros::QF_MEM_SYS}-->
<operation name="QF_MEM_SYS?ndef QF_MEM_SYS" type="void" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QF-macros::QF_MEM_APP}-->
<operation name="QF_MEM_APP?ndef QF_MEM_APP" type="void" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
</package>
<!--${QF_EPOOL-impl}-->
<package name="QF_EPOOL-impl" stereotype="0x02">
<!--${QF_EPOOL-impl::QF_EPOOL_TYPE_}-->
<attribute name="QF_EPOOL_TYPE_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool</documentation>
<code>QMPool</code>
</attribute>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_}-->
<operation name="QF_EPOOL_INIT_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool initialization</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::p_}-->
<parameter name="p_" type="QMPool *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::poolSto_}-->
<parameter name="poolSto_" type="void *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::poolSize_}-->
<parameter name="poolSize_" type="std::uint_fast32_t"/>
<!--${QF_EPOOL-impl::QF_EPOOL_INIT_::evtSize_}-->
<parameter name="evtSize_" type="std::uint_fast16_t"/>
2022-08-11 15:36:19 -04:00
<code>\
(p_).init((poolSto_), (poolSize_), (evtSize_))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_}-->
<operation name="QF_EPOOL_EVENT_SIZE_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool event-size getter</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_EVENT_S~::p_}-->
<parameter name="p_" type="QMPool const *"/>
<code>((p_).getBlockSize())</code>
</operation>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_}-->
<operation name="QF_EPOOL_GET_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool get-event</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::p_}-->
<parameter name="p_" type="QMPool *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::e_}-->
<parameter name="e_" type="QEvt *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::m_}-->
<parameter name="m_" type="std::uint_fast16_t"/>
2024-01-17 07:50:09 -05:00
<!--${QF_EPOOL-impl::QF_EPOOL_GET_::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
2022-08-11 15:36:19 -04:00
<code>\
2024-01-17 07:50:09 -05:00
((e_) = static_cast&lt;QEvt *&gt;((p_).get((m_), (qsId_))))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_}-->
<operation name="QF_EPOOL_PUT_" type="" visibility="0x03" properties="0x00">
<documentation>Native QF event pool put-event</documentation>
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_::p_}-->
<parameter name="p_" type="QMPool *"/>
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_::e_}-->
<parameter name="e_" type="QEvt *"/>
2024-01-17 07:50:09 -05:00
<!--${QF_EPOOL-impl::QF_EPOOL_PUT_::qsId_}-->
<parameter name="qsId_" type="std::uint8_t"/>
<code>((p_).put((e_), (qsId_)))</code>
</operation>
</package>
<!--${QV}-->
<package name="QV" stereotype="0x05" namespace="QP::">
<!--${QV::QV-base}-->
<package name="QV-base" stereotype="0x02" namespace="QV::">
<!--${QV::QV-base::Attr}-->
<class name="Attr">
<!--${QV::QV-base::Attr::readySet}-->
<attribute name="readySet" type="QPSet" visibility="0x00" properties="0x00"/>
<!--${QV::QV-base::Attr::schedCeil}-->
<attribute name="schedCeil" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QV::QV-base::Attr::readySet_dis}-->
<attribute name="readySet_dis?ndef Q_UNSAFE" type="QPSet" visibility="0x00" properties="0x00"/>
<!--${QV::QV-base::Attr::schedCeil_dis}-->
<attribute name="schedCeil_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
</class>
<!--${QV::QV-base::priv_}-->
<attribute name="priv_" type="QV::Attr" visibility="0x00" properties="0x01"/>
<!--${QV::QV-base::schedDisable}-->
<operation name="schedDisable" type="void" visibility="0x00" properties="0x01">
<!--${QV::QV-base::schedDisable::ceiling}-->
<parameter name="ceiling" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(102, priv_.schedCeil
== static_cast&lt;std::uint_fast8_t&gt;(~priv_.schedCeil_dis));
if (ceiling &gt; priv_.schedCeil) { // raising the scheduler ceiling?
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_SCHED_LOCK, 0U)
QS_TIME_PRE(); // timestamp
// the previous sched ceiling &amp; new sched ceiling
2024-10-15 13:15:28 -04:00
QS_2U8_PRE(static_cast&lt;std::uint8_t&gt;(priv_.schedCeil),
static_cast&lt;std::uint8_t&gt;(ceiling));
2024-10-15 13:15:28 -04:00
QS_END_PRE()
priv_.schedCeil = ceiling;
#ifndef Q_UNSAFE
priv_.schedCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~ceiling);
#endif
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QV::QV-base::schedEnable}-->
<operation name="schedEnable" type="void" visibility="0x00" properties="0x01">
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(202, priv_.schedCeil
== static_cast&lt;std::uint_fast8_t&gt;(~priv_.schedCeil_dis));
if (priv_.schedCeil != 0U) { // actually enabling the scheduler?
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_SCHED_UNLOCK, 0U)
QS_TIME_PRE(); // timestamp
// current sched ceiling (old), previous sched ceiling (new)
2024-10-15 13:15:28 -04:00
QS_2U8_PRE(static_cast&lt;std::uint8_t&gt;(priv_.schedCeil), 0U);
QS_END_PRE()
priv_.schedCeil = 0U;
#ifndef Q_UNSAFE
priv_.schedCeil_dis = ~static_cast&lt;std::uint_fast8_t&gt;(0U);
#endif
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
<!--${QV::QV-base::onIdle}-->
<operation name="onIdle" type="void" visibility="0x00" properties="0x01"/>
</package>
<!--${QV::QF-cust}-->
<package name="QF-cust" stereotype="0x02" namespace="QF::">
<!--${QV::QF-cust::init}-->
<operation name="init" type="void" visibility="0x00" properties="0x01">
<code>bzero_(&amp;QF::priv_, sizeof(QF::priv_));
bzero_(&amp;QV::priv_, sizeof(QV::priv_));
bzero_(&amp;QActive::registry_[0], sizeof(QActive::registry_));
#ifndef Q_UNSAFE
QV::priv_.readySet.update_(&amp;QV::priv_.readySet_dis);
QV::priv_.schedCeil_dis = ~static_cast&lt;std::uint_fast8_t&gt;(0U);
#endif
#ifdef QV_INIT
QV_INIT(); // port-specific initialization of the QV kernel
#endif</code>
</operation>
<!--${QV::QF-cust::stop}-->
<operation name="stop" type="void" visibility="0x00" properties="0x01">
<code>onCleanup(); // cleanup callback
// nothing else to do for the QV kernel</code>
</operation>
<!--${QV::QF-cust::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01">
<code>#ifdef Q_SPY
// produce the QS_QF_RUN trace record
QF_INT_DISABLE();
QF_MEM_SYS();
QS::beginRec_(QS_REC_NUM_(QS_QF_RUN));
QS::endRec_();
QF_MEM_APP();
QF_INT_ENABLE();
#endif // Q_SPY
onStartup(); // application-specific startup callback
QF_INT_DISABLE();
QF_MEM_SYS();
#ifdef QV_START
QV_START(); // port-specific startup of the QV kernel
#endif
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
std::uint_fast8_t pprev = 0U; // previous prio.
2024-10-15 13:15:28 -04:00
#ifdef QF_ON_CONTEXT_SW
// officially switch to the idle cotext
QF_onContextSw(nullptr, nullptr);
#endif // def QF_ON_CONTEXT_SW
#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
for (;;) { // QV event loop...
// check internal integrity (duplicate inverse storage)
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(302,
QV::priv_.readySet.verify_(&amp;QV::priv_.readySet_dis));
// check internal integrity (duplicate inverse storage)
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(303, QV::priv_.schedCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QV::priv_.schedCeil_dis));
// find the maximum prio. AO ready to run
std::uint_fast8_t const p = (QV::priv_.readySet.notEmpty()
? QV::priv_.readySet.findMax()
: 0U);
if (p &gt; QV::priv_.schedCeil) { // is it above the sched ceiling?
QActive * const a = QActive::registry_[p];
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_SCHED_NEXT, p)
QS_TIME_PRE(); // timestamp
QS_2U8_PRE(static_cast&lt;std::uint8_t&gt;(p),
static_cast&lt;std::uint8_t&gt;(pprev));
2024-10-15 13:15:28 -04:00
QS_END_PRE()
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(((pprev != 0U)
? QActive::registry_[pprev]
: nullptr), a);
#endif // QF_ON_CONTEXT_SW
pprev = p; // update previous prio.
#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
QF_MEM_APP();
QF_INT_ENABLE();
QEvt const * const e = a-&gt;get_();
// NOTE QActive::get_() performs QF_MEM_APP() before return
// dispatch event (virtual call)
a-&gt;dispatch(e, a-&gt;getPrio());
#if (QF_MAX_EPOOL &gt; 0U)
gc(e);
#endif
QF_INT_DISABLE();
QF_MEM_SYS();
if (a-&gt;getEQueue().isEmpty()) { // empty queue?
QV::priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QV::priv_.readySet.update_(&amp;QV::priv_.readySet_dis);
#endif
}
}
else { // no AO ready to run --&gt; idle
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (pprev != 0U) {
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_SCHED_IDLE, pprev)
QS_TIME_PRE(); // timestamp
QS_U8_PRE(static_cast&lt;std::uint8_t&gt;(pprev));
QS_END_PRE()
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(QActive::registry_[pprev], nullptr);
#endif // QF_ON_CONTEXT_SW
pprev = 0U; // update previous prio
}
#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
QF_MEM_APP();
// QV::onIdle() must be called with interrupts DISABLED
// because the determination of the idle condition (all event
// queues empty) can change at any time by an interrupt posting
// events to a queue.
//
// NOTE: QV::onIdle() MUST enable interrupts internally,
// ideally at the same time as putting the CPU into a power-
// saving mode.
QV::onIdle();
QF_INT_DISABLE();
QF_MEM_SYS();
}
}
#ifdef __GNUC__ // GNU compiler?
return 0;
#endif</code>
</operation>
</package>
<!--${QV::QActive}-->
<class name="QActive" superclass="qpcpp::QAsm">
<!--${QV::QActive::start}-->
<operation name="start" type="void" visibility="0x00" properties="0x04">
<!--${QV::QActive::start::prioSpec}-->
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QV::QActive::start::qSto}-->
2024-10-15 13:15:28 -04:00
<parameter name="qSto" type="QEvtPtr * const"/>
<!--${QV::QActive::start::qLen}-->
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QV::QActive::start::stkSto}-->
<parameter name="stkSto" type="void * const"/>
<!--${QV::QActive::start::stkSize}-->
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QV::QActive::start::par}-->
<parameter name="par" type="void const * const"/>
<code>Q_UNUSED_PAR(stkSto); // not needed in QV
Q_UNUSED_PAR(stkSize); // not needed in QV
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, stkSto == nullptr);
QF_CRIT_EXIT();
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
m_pthre = 0U; // not used
register_(); // make QF aware of this AO
m_eQueue.init(qSto, qLen); // initialize QEQueue of this AO
this-&gt;init(par, m_prio); // take the top-most initial tran. (virtual)
QS_FLUSH(); // flush the trace buffer to the host</code>
</operation>
</class>
</package>
<!--${QV-impl}-->
<package name="QV-impl" stereotype="0x02">
<!--${QV-impl::QF_SCHED_STAT_}-->
<attribute name="QF_SCHED_STAT_" type="" visibility="0x03" properties="0x00"/>
<!--${QV-impl::QF_SCHED_LOCK_}-->
<operation name="QF_SCHED_LOCK_" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QF_SCHED_LOCK_::dummy}-->
<parameter name="dummy" type=""/>
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QV-impl::QF_SCHED_UNLOCK_}-->
<operation name="QF_SCHED_UNLOCK_" type="" visibility="0x03" properties="0x00">
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QV-impl::QACTIVE_EQUEUE_WAIT_}-->
<operation name="QACTIVE_EQUEUE_WAIT_" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QACTIVE_EQUEUE_W~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
2024-10-15 13:15:28 -04:00
<code>(static_cast&lt;void&gt;(0))</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QV-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?ndef Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
2022-08-11 15:36:19 -04:00
<code>\
QV::priv_.readySet.insert((me_)-&gt;m_prio); \
QV::priv_.readySet.update_(&amp;QV::priv_.readySet_dis)</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QV-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?def Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QV-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
2022-08-11 15:36:19 -04:00
<code>\
(QV::priv_.readySet.insert((me_)-&gt;m_prio))</code>
2022-08-11 15:36:19 -04:00
</operation>
</package>
<!--${QK}-->
<package name="QK" stereotype="0x05" namespace="QP::">
<!--${QK::QSchedStatus}-->
<attribute name="QSchedStatus" type="using" visibility="0x04" properties="0x00">
<code>= std::uint_fast8_t;</code>
</attribute>
<!--${QK::QK-base}-->
<package name="QK-base" stereotype="0x02" namespace="QK::">
<!--${QK::QK-base::schedLock}-->
<operation name="schedLock" type="QSchedStatus" visibility="0x00" properties="0x01">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QK::QK-base::schedLock::ceiling}-->
<parameter name="ceiling" type="std::uint_fast8_t const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
2022-08-11 15:36:19 -04:00
// first store the previous lock prio
QSchedStatus stat;
if (ceiling &gt; QK_priv_.lockCeil) { // raising the lock ceiling?
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_SCHED_LOCK, QK_priv_.actPrio)
QS_TIME_PRE(); // timestamp
// the previous lock ceiling &amp; new lock ceiling
2024-10-15 13:15:28 -04:00
QS_2U8_PRE(static_cast&lt;std::uint8_t&gt;(QK_priv_.lockCeil),
static_cast&lt;std::uint8_t&gt;(ceiling));
2024-10-15 13:15:28 -04:00
QS_END_PRE()
2022-08-11 15:36:19 -04:00
// previous status of the lock
stat = static_cast&lt;QSchedStatus&gt;(QK_priv_.lockCeil);
2022-08-11 15:36:19 -04:00
// new status of the lock
QK_priv_.lockCeil = ceiling;
#ifndef Q_UNSAFE
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~ceiling);
#endif
}
else {
stat = 0xFFU; // scheduler not locked
}
2022-08-11 15:36:19 -04:00
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-11 15:36:19 -04:00
return stat; // return the status to be saved in a stack variable</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QK::QK-base::schedUnlock}-->
<operation name="schedUnlock" type="void" visibility="0x00" properties="0x01">
2022-08-11 15:36:19 -04:00
<specifiers>noexcept</specifiers>
<!--${QK::QK-base::schedUnlock::prevCeil}-->
<parameter name="prevCeil" type="QSchedStatus const"/>
<code>// has the scheduler been actually locked by the last QK::schedLock()?
if (prevCeil != 0xFFU) {
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
2022-08-11 15:36:19 -04:00
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(202, QK_priv_.lockCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
&amp;&amp; (QK_priv_.lockCeil &gt; prevCeil));
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QS_SCHED_UNLOCK, QK_priv_.actPrio)
QS_TIME_PRE(); // timestamp
// current lock ceiling (old), previous lock ceiling (new)
2024-10-15 13:15:28 -04:00
QS_2U8_PRE(static_cast&lt;std::uint8_t&gt;(QK_priv_.lockCeil),
static_cast&lt;std::uint8_t&gt;(prevCeil));
2024-10-15 13:15:28 -04:00
QS_END_PRE()
// restore the previous lock ceiling
QK_priv_.lockCeil = prevCeil;
#ifndef Q_UNSAFE
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~prevCeil);
#endif
// find if any AOs should be run after unlocking the scheduler
if (QK_sched_() != 0U) { // preemption needed?
QK_activate_(); // activate any unlocked AOs
2022-08-28 22:12:27 -04:00
}
QF_MEM_APP();
QF_CRIT_EXIT();
2022-08-28 22:12:27 -04:00
}</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QK::QK-base::onIdle}-->
<operation name="onIdle" type="void" visibility="0x00" properties="0x01"/>
2022-08-28 22:12:27 -04:00
</package>
<!--${QK::QF-cust}-->
<package name="QF-cust" stereotype="0x02" namespace="QF::">
<!--${QK::QF-cust::init}-->
2022-08-28 22:12:27 -04:00
<operation name="init" type="void" visibility="0x00" properties="0x01">
<code>bzero_(&amp;QF::priv_, sizeof(QF::priv_));
bzero_(&amp;QK_priv_, sizeof(QK_priv_));
bzero_(&amp;QActive::registry_[0], sizeof(QActive::registry_));
// setup the QK scheduler as initially locked and not running
QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked
#ifndef Q_UNSAFE
QK_priv_.readySet.update_(&amp;QK_priv_.readySet_dis);
QK_priv_.actPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio);
QK_priv_.nextPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre);
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil);
#endif
#ifdef QK_INIT
QK_INIT(); // port-specific initialization of the QK kernel
#endif</code>
</operation>
<!--${QK::QF-cust::stop}-->
2022-08-11 15:36:19 -04:00
<operation name="stop" type="void" visibility="0x00" properties="0x01">
<code>onCleanup(); // cleanup callback
// nothing else to do for the QK preemptive kernel</code>
2022-08-11 15:36:19 -04:00
</operation>
<!--${QK::QF-cust::run}-->
2022-08-11 15:36:19 -04:00
<operation name="run" type="int_t" visibility="0x00" properties="0x01">
<code>#ifdef Q_SPY
2022-08-11 15:36:19 -04:00
// produce the QS_QF_RUN trace record
QF_INT_DISABLE();
QF_MEM_SYS();
QS::beginRec_(QS_REC_NUM_(QS_QF_RUN));
QS::endRec_();
QF_MEM_APP();
QF_INT_ENABLE();
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
onStartup(); // application-specific startup callback
QF_INT_DISABLE();
QF_MEM_SYS();
#ifdef QK_START
QK_START(); // port-specific startup of the QK kernel
#endif
QK_priv_.lockCeil = 0U; // unlock the QK scheduler
#ifndef Q_UNSAFE
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil);
#endif
2024-10-15 13:15:28 -04:00
#ifdef QF_ON_CONTEXT_SW
// officially switch to the idle context
QF_onContextSw(nullptr, QActive::registry_[QK_priv_.nextPrio]);
#endif
// activate AOs to process events posted so far
if (QK_sched_() != 0U) {
QK_activate_();
}
QF_MEM_APP();
QF_INT_ENABLE();
for (;;) { // QK idle loop...
QK::onIdle(); // application-specific QK on-idle callback
}
#ifdef __GNUC__ // GNU compiler?
return 0;
#endif</code>
2022-08-11 15:36:19 -04:00
</operation>
</package>
<!--${QK::QActive}-->
<class name="QActive" superclass="QEP::QAsm">
<!--${QK::QActive::start}-->
2022-08-11 15:36:19 -04:00
<operation name="start" type="void" visibility="0x00" properties="0x04">
<!--${QK::QActive::start::prioSpec}-->
2022-08-28 22:12:27 -04:00
<parameter name="prioSpec" type="QPrioSpec const"/>
<!--${QK::QActive::start::qSto}-->
2024-10-15 13:15:28 -04:00
<parameter name="qSto" type="QEvtPtr * const"/>
<!--${QK::QActive::start::qLen}-->
2022-08-11 15:36:19 -04:00
<parameter name="qLen" type="std::uint_fast16_t const"/>
<!--${QK::QActive::start::stkSto}-->
2022-08-11 15:36:19 -04:00
<parameter name="stkSto" type="void * const"/>
<!--${QK::QActive::start::stkSize}-->
2022-08-11 15:36:19 -04:00
<parameter name="stkSize" type="std::uint_fast16_t const"/>
<!--${QK::QActive::start::par}-->
2022-08-11 15:36:19 -04:00
<parameter name="par" type="void const * const"/>
<code>Q_UNUSED_PAR(stkSto); // not needed in QK
Q_UNUSED_PAR(stkSize); // not needed in QK
2022-08-11 15:36:19 -04:00
QF_CRIT_STAT
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_())
&amp;&amp; (stkSto == nullptr));
QF_MEM_APP();
QF_CRIT_EXIT();
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
2022-08-28 22:12:27 -04:00
m_pthre = static_cast&lt;std::uint8_t&gt;(prioSpec &gt;&gt; 8U); // preemption-thre.
register_(); // make QF aware of this AO
2022-08-11 15:36:19 -04:00
m_eQueue.init(qSto, qLen); // init the built-in queue
2022-08-11 15:36:19 -04:00
// top-most initial tran. (virtual call)
this-&gt;init(par, m_prio);
QS_FLUSH(); // flush the trace buffer to the host
// See if this AO needs to be scheduled if QK is already running
QF_CRIT_ENTRY();
QF_MEM_SYS();
if (QK_sched_() != 0U) { // activation needed?
QK_activate_();
}
QF_MEM_APP();
QF_CRIT_EXIT();</code>
2022-08-11 15:36:19 -04:00
</operation>
</class>
</package>
<!--${QK-extern-C}-->
<package name="QK-extern-C" stereotype="0x02">
<!--${QK-extern-C::QK_Attr}-->
<class name="QK_Attr">
<!--${QK-extern-C::QK_Attr::readySet}-->
<attribute name="readySet" type="QP::QPSet" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actPrio}-->
<attribute name="actPrio" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::nextPrio}-->
<attribute name="nextPrio" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actThre}-->
<attribute name="actThre" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::lockCeil}-->
<attribute name="lockCeil" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::intNest}-->
<attribute name="intNest" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::readySet_dis}-->
<attribute name="readySet_dis?ndef Q_UNSAFE" type="QP::QPSet" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actPrio_dis}-->
<attribute name="actPrio_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::nextPrio_dis}-->
<attribute name="nextPrio_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::actThre_dis}-->
<attribute name="actThre_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_Attr::lockCeil_dis}-->
<attribute name="lockCeil_dis?ndef Q_UNSAFE" type="std::uint_fast8_t" visibility="0x00" properties="0x00"/>
</class>
<!--${QK-extern-C::QK_priv_}-->
<attribute name="QK_priv_" type="QK_Attr" visibility="0x00" properties="0x00"/>
<!--${QK-extern-C::QK_sched_}-->
<operation name="QK_sched_" type="std::uint_fast8_t" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
2024-01-17 07:50:09 -05:00
<code>// NOTE: this function is entered with interrupts DISABLED
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(402,
QK_priv_.readySet.verify_(&amp;QK_priv_.readySet_dis));
2022-08-11 15:36:19 -04:00
std::uint_fast8_t p;
if (QK_priv_.readySet.isEmpty()) {
p = 0U; // no activation needed
}
else {
// find the highest-prio AO with non-empty event queue
p = QK_priv_.readySet.findMax();
2022-08-11 15:36:19 -04:00
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(412, QK_priv_.actThre
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre_dis));
// is the AO's prio. below the active preemption-threshold?
if (p &lt;= QK_priv_.actThre) {
p = 0U; // no activation needed
}
else {
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(422, QK_priv_.lockCeil
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
// is the AO's prio. below the lock-ceiling?
if (p &lt;= QK_priv_.lockCeil) {
p = 0U; // no activation needed
}
else {
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(432, QK_priv_.nextPrio
== static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio_dis));
QK_priv_.nextPrio = p; // next AO to run
#ifndef Q_UNSAFE
QK_priv_.nextPrio_dis
= static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio);
#endif
}
}
}
2022-08-11 15:36:19 -04:00
return p;</code>
</operation>
<!--${QK-extern-C::QK_activate_}-->
<operation name="QK_activate_" type="void" visibility="0x00" properties="0x00">
<specifiers>noexcept</specifiers>
2024-01-17 07:50:09 -05:00
<code>// NOTE: this function is entered with interrupts DISABLED
std::uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
std::uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
2022-08-11 15:36:19 -04:00
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(502,
(prio_in == static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio_dis))
&amp;&amp; (p == static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio_dis)));
Q_REQUIRE_INCRIT(510, (prio_in &lt;= QF_MAX_ACTIVE)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE));
2022-08-11 15:36:19 -04:00
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
std::uint_fast8_t pprev = prio_in;
#endif // QF_ON_CONTEXT_SW || Q_SPY
2022-08-11 15:36:19 -04:00
QK_priv_.nextPrio = 0U; // clear for the next time
#ifndef Q_UNSAFE
QK_priv_.nextPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio);
#endif
std::uint_fast8_t pthre_in;
QP::QActive *a;
if (prio_in == 0U) { // preempting the idle thread?
pthre_in = 0U;
}
else {
a = QP::QActive::registry_[prio_in];
Q_ASSERT_INCRIT(510, a != nullptr);
pthre_in = static_cast&lt;std::uint_fast8_t&gt;(a-&gt;getPThre());
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(511, pthre_in == static_cast&lt;std::uint_fast8_t&gt;(
~static_cast&lt;std::uint_fast8_t&gt;(a-&gt;m_pthre_dis) &amp; 0xFFU));
}
// loop until no more ready-to-run AOs of higher pthre than the initial
do {
a = QP::QActive::registry_[p]; // obtain the pointer to the AO
Q_ASSERT_INCRIT(520, a != nullptr); // the AO must be registered
std::uint_fast8_t const pthre
= static_cast&lt;std::uint_fast8_t&gt;(a-&gt;getPThre());
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(522, pthre == static_cast&lt;std::uint_fast8_t&gt;(
~static_cast&lt;std::uint_fast8_t&gt;(a-&gt;m_pthre_dis) &amp; 0xFFU));
2022-08-11 15:36:19 -04:00
// set new active prio. and preemption-threshold
QK_priv_.actPrio = p;
QK_priv_.actThre = pthre;
#ifndef Q_UNSAFE
QK_priv_.actPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~p);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~pthre);
#endif
2022-08-11 15:36:19 -04:00
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (p != pprev) { // changing threads?
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QP::QS_SCHED_NEXT, p)
QS_TIME_PRE(); // timestamp
QS_2U8_PRE(p, // prio. of the scheduled AO
pprev); // previous prio.
2024-10-15 13:15:28 -04:00
QS_END_PRE()
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(QP::QActive::registry_[pprev], a);
#endif // QF_ON_CONTEXT_SW
pprev = p; // update previous prio.
2022-08-11 15:36:19 -04:00
}
#endif // QF_ON_CONTEXT_SW || Q_SPY
2024-04-24 09:13:46 -04:00
QF_MEM_APP();
QF_INT_ENABLE(); // unconditionally enable interrupts
QP::QEvt const * const e = a-&gt;get_();
// NOTE QActive_get_() performs QF_MEM_APP() before return
// dispatch event (virtual call)
a-&gt;dispatch(e, a-&gt;getPrio());
#if (QF_MAX_EPOOL &gt; 0U)
QP::QF::gc(e);
#endif
// determine the next highest-prio. AO ready to run...
QF_INT_DISABLE(); // unconditionally disable interrupts
QF_MEM_SYS();
// internal integrity check (duplicate inverse storage)
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(532,
QK_priv_.readySet.verify_(&amp;QK_priv_.readySet_dis));
if (a-&gt;getEQueue().isEmpty()) { // empty queue?
QK_priv_.readySet.remove(p);
#ifndef Q_UNSAFE
QK_priv_.readySet.update_(&amp;QK_priv_.readySet_dis);
#endif
}
if (QK_priv_.readySet.isEmpty()) {
p = 0U; // no activation needed
}
else {
// find new highest-prio AO ready to run...
p = QK_priv_.readySet.findMax();
// is the new prio. below the initial preemption-threshold?
if (p &lt;= pthre_in) {
p = 0U; // no activation needed
}
else {
2024-04-24 09:13:46 -04:00
Q_INVARIANT_INCRIT(542,
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
// is the AO's prio. below the lock preemption-threshold?
if (p &lt;= QK_priv_.lockCeil) {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(550, p &lt;= QF_MAX_ACTIVE);
}
}
}
} while (p != 0U);
// restore the active prio. and preemption-threshold
QK_priv_.actPrio = prio_in;
QK_priv_.actThre = pthre_in;
#ifndef Q_UNSAFE
QK_priv_.actPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre);
#endif
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (prio_in != 0U) { // resuming an active object?
a = QP::QActive::registry_[prio_in]; // pointer to preempted AO
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QP::QS_SCHED_NEXT, prio_in)
QS_TIME_PRE(); // timestamp
// prio. of the resumed AO, previous prio.
2024-10-15 13:15:28 -04:00
QS_2U8_PRE(prio_in, pprev);
QS_END_PRE()
}
else { // resuming prio.==0 --&gt; idle
a = nullptr; // QK idle loop
2024-10-15 13:15:28 -04:00
QS_BEGIN_PRE(QP::QS_SCHED_IDLE, pprev)
QS_TIME_PRE(); // timestamp
QS_U8_PRE(pprev); // previous prio.
QS_END_PRE()
}
#ifdef QF_ON_CONTEXT_SW
QF_onContextSw(QP::QActive::registry_[pprev], a);
#endif // QF_ON_CONTEXT_SW
#endif // QF_ON_CONTEXT_SW || Q_SPY</code>
</operation>
</package>
<!--${QK-impl}-->
<package name="QK-impl" stereotype="0x02">
<!--${QK-impl::QF_SCHED_STAT_}-->
<attribute name="QF_SCHED_STAT_" type="" visibility="0x03" properties="0x00">
<code>QSchedStatus lockStat_;</code>
</attribute>
<!--${QK-impl::QF_SCHED_LOCK_}-->
<operation name="QF_SCHED_LOCK_" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QF_SCHED_LOCK_::ceil_}-->
<parameter name="ceil_" type="std::uint_fast8_t"/>
<code>do { \
if (QK_ISR_CONTEXT_()) { \
lockStat_ = 0xFFU; \
} else { \
lockStat_ = QK::schedLock((ceil_)); \
} \
} while (false)</code>
</operation>
<!--${QK-impl::QF_SCHED_UNLOCK_}-->
<operation name="QF_SCHED_UNLOCK_" type="" visibility="0x03" properties="0x00">
<code>do { \
if (lockStat_ != 0xFFU) { \
QK::schedUnlock(lockStat_); \
} \
} while (false)</code>
</operation>
<!--${QK-impl::QACTIVE_EQUEUE_WAIT_}-->
<operation name="QACTIVE_EQUEUE_WAIT_" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QACTIVE_EQUEUE_W~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
2024-10-15 13:15:28 -04:00
<code>(static_cast&lt;void&gt;(0))</code>
</operation>
<!--${QK-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?ndef Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>do { \
QK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
QK_priv_.readySet.update_(&amp;QK_priv_.readySet_dis); \
if (!QK_ISR_CONTEXT_()) { \
if (QK_sched_() != 0U) { \
QK_activate_(); \
} \
} \
} while (false)</code>
</operation>
<!--${QK-impl::QACTIVE_EQUEUE_SIGNAL_}-->
<operation name="QACTIVE_EQUEUE_SIGNAL_?def Q_UNSAFE" type="" visibility="0x03" properties="0x00">
<!--${QK-impl::QACTIVE_EQUEUE_S~::me_}-->
<parameter name="me_" type="QP::QActive *"/>
<code>do { \
QK_priv_.readySet.insert( \
static_cast&lt;std::uint_fast8_t&gt;((me_)-&gt;m_prio)); \
if (!QK_ISR_CONTEXT_()) { \
if (QK_sched_() != 0U) { \
QK_activate_(); \
} \
} \
} while (false)</code>
</operation>
</package>
2024-10-15 13:15:28 -04:00
<!--${include}-->
<directory name="include">
<!--${include::qp.hpp}-->
<file name="qp.hpp">
<text>#ifndef QP_HPP_
#define QP_HPP_
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
#define QP_VERSION_STR &quot;8.0.1&quot;
#define QP_VERSION 801U
#define QP_RELEASE 0x703931CEU
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
//! @cond INTERNAL
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifndef Q_SIGNAL_SIZE
#define Q_SIGNAL_SIZE 2U
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifndef QF_MAX_ACTIVE
#define QF_MAX_ACTIVE 32U
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#if (QF_MAX_ACTIVE &gt; 64U)
#error QF_MAX_ACTIVE exceeds the maximum of 64U;
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifndef QF_MAX_TICK_RATE
#define QF_MAX_TICK_RATE 1U
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#if (QF_MAX_TICK_RATE &gt; 15U)
#error QF_MAX_TICK_RATE exceeds the maximum of 15U;
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifndef QF_MAX_EPOOL
#define QF_MAX_EPOOL 3U
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#if (QF_MAX_EPOOL &gt; 15U)
#error QF_MAX_EPOOL exceeds the maximum of 15U;
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifndef QF_TIMEEVT_CTR_SIZE
#define QF_TIMEEVT_CTR_SIZE 4U
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#if (QF_TIMEEVT_CTR_SIZE &gt; 4U)
#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U;
#endif
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
#ifndef QF_EVENT_SIZ_SIZE
#define QF_EVENT_SIZ_SIZE 2U
#endif
2023-01-06 12:56:50 -05:00
2024-10-15 13:15:28 -04:00
#if (QF_EVENT_SIZ_SIZE &gt; 4U)
#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U;
#endif
2023-01-06 12:56:50 -05:00
2024-10-15 13:15:28 -04:00
//! @endcond
//============================================================================
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$declare ${glob-types}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QEP}
2024-10-15 13:15:28 -04:00
$declare ${QEP-macros}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::types}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::QActive}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::QMActive}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::QTimeEvt}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::QTicker}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::QF-base}
2024-10-15 13:15:28 -04:00
$declare ${QF::QF-dyn}
2024-10-15 13:15:28 -04:00
extern &quot;C&quot; {
$declare ${QF-extern-C}
} // extern &quot;C&quot;
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF-macros}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#endif // QP_HPP_</text>
</file>
<!--${include::qp_pkg.hpp}-->
<file name="qp_pkg.hpp">
<text>#ifndef QP_PKG_HPP_
#define QP_PKG_HPP_
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::QF-pkg}
2023-01-06 12:56:50 -05:00
2024-10-15 13:15:28 -04:00
#define QF_CONST_CAST_(type_, ptr_) const_cast&lt;type_&gt;(ptr_)
#define Q_PTR2UINT_CAST_(ptr_) (reinterpret_cast&lt;std::uintptr_t&gt;(ptr_))
#define QF_PTR_RANGE_(x_, min_, max_) (((min_) &lt;= (x_)) &amp;&amp; ((x_) &lt;= (max_)))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
namespace QP {
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// Bitmasks are for the QTimeEvt::flags attribute
constexpr std::uint8_t QTE_FLAG_IS_LINKED {1U &lt;&lt; 7U};
constexpr std::uint8_t QTE_FLAG_WAS_DISARMED {1U &lt;&lt; 6U};
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
inline void QEvt_refCtr_inc_(QEvt const * const e) noexcept {
std::uint8_t rc = e-&gt;refCtr_ + 1U;
(QF_CONST_CAST_(QEvt*, e))-&gt;refCtr_ = rc; // cast away 'const'
#ifndef Q_UNSAFE
(QF_CONST_CAST_(QEvt*, e))-&gt;evtTag_ = (e-&gt;evtTag_ &amp; 0xF0U) | ((~rc) &amp; 0x0FU);
#endif
}
2023-01-06 12:56:50 -05:00
2024-10-15 13:15:28 -04:00
inline void QEvt_refCtr_dec_(QEvt const * const e) noexcept {
std::uint8_t rc = e-&gt;refCtr_ - 1U;
(QF_CONST_CAST_(QEvt*, e))-&gt;refCtr_ = rc; // cast away 'const'
#ifndef Q_UNSAFE
(QF_CONST_CAST_(QEvt*, e))-&gt;evtTag_ = (e-&gt;evtTag_ &amp; 0xF0U) | ((~rc) &amp; 0x0FU);
#endif
}
2024-10-15 13:15:28 -04:00
} // namespace QP
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#endif // QP_PKG_HPP_</text>
</file>
<!--${include::qequeue.hpp}-->
<file name="qequeue.hpp">
<text>#ifndef QEQUEUE_HPP_
#define QEQUEUE_HPP_
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifndef QF_EQUEUE_CTR_SIZE
#define QF_EQUEUE_CTR_SIZE 1U
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
namespace QP {
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
#if (QF_EQUEUE_CTR_SIZE == 1U)
using QEQueueCtr = std::uint8_t;
#elif (QF_EQUEUE_CTR_SIZE == 2U)
using QEQueueCtr = std::uint16_t;
#else
#error &quot;QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U&quot;
#endif
2024-10-15 13:15:28 -04:00
class QEvt; // forward declaration
2024-10-15 13:15:28 -04:00
} // namespace QP
2024-10-15 13:15:28 -04:00
$declare ${QF::QEQueue}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#endif // QEQUEUE_HPP_</text>
</file>
<!--${include::qmpool.hpp}-->
<file name="qmpool.hpp">
<text>#ifndef QMPOOL_HPP_
#define QMPOOL_HPP_
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifndef QF_MPOOL_SIZ_SIZE
#define QF_MPOOL_SIZ_SIZE 2U
#endif
#ifndef QF_MPOOL_CTR_SIZE
#define QF_MPOOL_CTR_SIZE 2U
#endif
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
namespace QP {
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#if (QF_MPOOL_SIZ_SIZE == 1U)
using QMPoolSize = std::uint8_t;
#elif (QF_MPOOL_SIZ_SIZE == 2U)
using QMPoolSize = std::uint16_t;
#elif (QF_MPOOL_SIZ_SIZE == 4U)
using QMPoolSize = std::uint32_t;
#else
#error &quot;QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U&quot;
#endif
2024-10-15 13:15:28 -04:00
#if (QF_MPOOL_CTR_SIZE == 1U)
using QMPoolCtr = std::uint8_t;
#elif (QF_MPOOL_CTR_SIZE == 2U)
using QMPoolCtr = std::uint16_t;
#elif (QF_MPOOL_CTR_SIZE == 4U)
using QMPoolCtr = std::uint32_t;
#else
#error &quot;QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U&quot;
#endif
2024-10-15 13:15:28 -04:00
} // namespace QP
2024-10-15 13:15:28 -04:00
#define QF_MPOOL_EL(evType_) struct { \
QP::QFreeBlock sto_[((sizeof(evType_) - 1U) / (2U * sizeof(void *))) + 1U]; \
2022-08-11 15:36:19 -04:00
}
2024-10-15 13:15:28 -04:00
$declare ${QF::QFreeBlock}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF::QMPool}
2024-10-15 13:15:28 -04:00
#endif // QMPOOL_HPP_</text>
</file>
<!--${include::qv.hpp}-->
<file name="qv.hpp">
<text>#ifndef QV_HPP_
#define QV_HPP_
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QV::QV-base}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
// interface used only for internal implementation, but not in applications
#ifdef QP_IMPL
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QV-impl}
2022-11-14 18:50:37 -05:00
2024-10-15 13:15:28 -04:00
$declare ${QF_EPOOL-impl}
2024-10-15 13:15:28 -04:00
#endif // QP_IMPL
2024-10-15 13:15:28 -04:00
#endif // QV_HPP_</text>
</file>
<!--${include::qk.hpp}-->
<file name="qk.hpp">
<text>#ifndef QK_HPP_
#define QK_HPP_
2024-10-15 13:15:28 -04:00
$declare ${QK::QSchedStatus}
2024-10-15 13:15:28 -04:00
$declare ${QK::QK-base}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
extern &quot;C&quot; {
$declare ${QK-extern-C}
} // extern &quot;C&quot;
2023-01-06 12:56:50 -05:00
2024-10-15 13:15:28 -04:00
//============================================================================
// interface used only for internal implementation, but not in applications
#ifdef QP_IMPL
2023-01-06 12:56:50 -05:00
2024-10-15 13:15:28 -04:00
$declare ${QK-impl}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$declare ${QF_EPOOL-impl}
2024-10-15 13:15:28 -04:00
#endif // QP_IMPL
2024-10-15 13:15:28 -04:00
#endif // QK_HPP_</text>
</file>
<!--${include::qstamp.hpp}-->
<file name="qstamp.hpp">
<text>#ifndef QSTAMP_HPP_
#define QSTAMP_HPP_
2024-10-15 13:15:28 -04:00
namespace QP {
extern char const BUILD_DATE[12];
extern char const BUILD_TIME[9];
} // namespace QP
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#endif // QSTAMP_HPP_</text>
</file>
<!--${include::qpcpp.hpp}-->
<file name="qpcpp.hpp">
<text>#ifndef QPCPP_HPP_
#define QPCPP_HPP_
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
#include &quot;qp_port.hpp&quot; // QP port from the port directory
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS/C++ port from the port directory
#else
#include &quot;qs_dummy.hpp&quot; // QS/C++ dummy (inactive) interface
#endif
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
#ifndef QP_API_VERSION
#define QP_API_VERSION 0
#endif // QP_API_VERSION
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// QP API compatibility layer...
//============================================================================
#if (QP_API_VERSION &lt; 750)
2024-10-15 13:15:28 -04:00
#define QM_SM_STATE_DECL(subm_, state_) error &quot;submachines no longer supported&quot;
#define qm_super_sub(sm_state_) error &quot;submachines no longer supported&quot;
#define qm_tran_ep(tatbl_) error &quot;submachines no longer supported&quot;
#define qm_tran_xp(xp_, tatbl_) error &quot;submachines no longer supported&quot;
#define qm_sm_exit(sm_state_) error &quot;submachines no longer supported&quot;
2022-10-06 20:29:33 -04:00
2024-10-15 13:15:28 -04:00
#ifdef QEVT_DYN_CTOR
//! @deprecated #QEVT_DYN_CTOR, please use #QEVT_PAR_INIT
#define QEVT_PAR_INIT
#endif
2024-10-15 13:15:28 -04:00
//! @deprecated plain 'char' is no longer forbidden in MISRA/AUTOSAR-C++
using char_t = char;
2022-10-06 20:29:33 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated assertion failure handler
//! Use Q_onError() instead.
#define Q_onAssert(module_, id_) Q_onError(module_, id_)
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated #Q_NASSERT preprocessor switch to disable QP assertions
#ifdef Q_NASSERT
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// #Q_UNSAFE now replaces the functionality of Q_NASSERT
#define Q_UNSAFE
2022-10-06 20:29:33 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated general purpose assertion with user-specified ID
//! number that **always** evaluates the `expr_` expression.
#define Q_ALLEGE_ID(id_, expr_) (static_cast&lt;void&gt;(expr_))
2024-10-15 13:15:28 -04:00
#elif defined Q_UNSAFE
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated general purpose assertion with user-specified ID
//! number that **always** evaluates the `expr_` expression.
#define Q_ALLEGE_ID(id_, expr_) (static_cast&lt;void&gt;(expr_))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#else // QP FuSa Subsystem enabled
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated general purpose assertion with user-specified ID
//! number that **always** evaluates the `expr_` expression.
//! @note
//! The use of this macro is no longer recommended.
#define Q_ALLEGE_ID(id_, expr_) if (!(expr_)) { \
QF_CRIT_STAT \
QF_CRIT_ENTRY(); \
Q_onError(&amp;Q_this_module_[0], (id_)); \
QF_CRIT_EXIT(); \
} else ((void)0)
2022-08-11 15:36:19 -04:00
#endif
2024-10-15 13:15:28 -04:00
//! @deprecated general purpose assertion without ID number
//! that **always** evaluates the `expr_` expression.
//! Instead of ID number, this macro is based on the standard
//! `__LINE__` macro.
//!
//! @note The use of this macro is no longer recommended.
#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_))
2024-10-15 13:15:28 -04:00
//! Static (compile-time) assertion.
//!
//! @deprecated
//! Use Q_ASSERT_STATIC() or better yet `static_assert()` instead.
//!
#define Q_ASSERT_COMPILE(expr_) Q_ASSERT_STATIC(expr_)
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated use QP::QF::NO_MARGIN instead
#define QF_NO_MARGIN QP::QF::NO_MARGIN
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
#if (QP_API_VERSION &lt; 691)
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated enable the QS global filter
#define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated disable the QS global filter
#define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated enable the QS local filter for SM (state machine) object
#define QS_FILTER_SM_OBJ(obj_) (static_cast&lt;void&gt;(0))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated enable the QS local filter for AO (active objects)
#define QS_FILTER_AO_OBJ(obj_) (static_cast&lt;void&gt;(0))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated enable the QS local filter for MP (memory pool) object
#define QS_FILTER_MP_OBJ(obj_) (static_cast&lt;void&gt;(0))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated enable the QS local filter for EQ (event queue) object
#define QS_FILTER_EQ_OBJ(obj_) (static_cast&lt;void&gt;(0))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated enable the QS local filter for TE (time event) object
#define QS_FILTER_TE_OBJ(obj_) (static_cast&lt;void&gt;(0))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#ifdef Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated local Filter for a generic application object `obj_`.
#define QS_FILTER_AP_OBJ(obj_) \
(QP::QS::filt_.loc_AP = (obj_))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID()
#define QS_BEGIN(rec_, obj_) \
if (QS_GLB_FILTER_(rec_) &amp;&amp; \
((QP::QS::filt_.loc[QP::QS::AP_OBJ] == nullptr) \
|| (QP::QS::filt_.loc_AP == (obj_)))) \
{ \
QS_CRIT_STAT \
QS_CRIT_ENTRY(); \
QP::QS::beginRec_(static_cast&lt;std::uint_fast8_t&gt;(rec_)); \
QS_TIME_PRE();
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated output hex-formatted std::uint32_t to the QS record
#define QS_U32_HEX(width_, data_) \
(QP::QS::u32_fmt_(static_cast&lt;std::uint8_t&gt;( \
(static_cast&lt;std::uint8_t&gt;((width_) &lt;&lt; 4)) | QS_HEX_FMT), (data_)))
2024-10-15 13:15:28 -04:00
#else
2024-10-15 13:15:28 -04:00
#define QS_FILTER_AP_OBJ(obj_) (static_cast&lt;void&gt;(0))
#define QS_BEGIN(rec_, obj_) if (false) {
#define QS_U32_HEX(width_, data_) (Q_UNUSED_PAR(0))
2024-10-15 13:15:28 -04:00
#endif // def Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
#if (QP_API_VERSION &lt; 680)
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to specify a tran. in the &quot;me-&gt;&quot; impl-strategy.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! you call tran(Q_STATE_CAST(target_)).
#define Q_TRAN(target_) (me-&gt;tran(Q_STATE_CAST(target_)))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to specify a tran-to-history in the &quot;me-&gt;&quot; impl-strategy.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! you call tran_hist(Q_STATE_CAST(hist_)).
#define Q_TRAN_HIST(hist_) (me-&gt;tran_hist((hist_)))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to specify the superstate in the &quot;me-&gt;&quot; impl-strategy.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! you call super(state_)).
#define Q_SUPER(state_) (me-&gt;super(Q_STATE_CAST(state_)))
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to call in a QM state entry-handler. Applicable only to QMSMs.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_entry(Q_STATE_CAST(state_)).
#define QM_ENTRY(state_) (me-&gt;qm_entry((state_)))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to call in a QM state exit-handler. Applicable only to QMSMs.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_exit(Q_STATE_CAST(state_)).
#define QM_EXIT(state_) (me-&gt;qm_exit((state_)))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to call in a QM state-handler when it executes a tran.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran((tatbl_)).
#define QM_TRAN(tatbl_) (me-&gt;qm_tran((tatbl_)))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to call in a QM state-handler when it executes an initial tran.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran_init((tatbl_)).
#define QM_TRAN_INIT(tatbl_) (me-&gt;qm_tran_init((tatbl_)))
2024-10-15 13:15:28 -04:00
//! @deprecated
//! Macro to call in a QM state-handler when it executes a tran-to-history.
//! Instead use the new impl-strategy without the &quot;me-&gt;&quot; pointer, where
//! the QM-generated code calls qm_tran_hist((history_), (tatbl_)).
#define QM_TRAN_HIST(history_, tatbl_) \
(me-&gt;qm_tran_hist((history_), (tatbl_)))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#endif // QP_API_VERSION &lt; 680
#endif // QP_API_VERSION &lt; 691
#endif // QP_API_VERSION &lt; 750
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#endif // QPCPP_HPP_</text>
</file>
</directory>
<!--${src}-->
<directory name="src">
<!--${src::qf}-->
<directory name="qf">
<!--${src::qf::qep_hsm.cpp}-->
<file name="qep_hsm.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
//! @cond INTERNAL
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qep_hsm&quot;)
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// immutable events corresponding to the reserved signals.
static QP::QEvt const l_reservedEvt_[4] {
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_EMPTY_SIG)),
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_ENTRY_SIG)),
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_EXIT_SIG)),
QP::QEvt(static_cast&lt;QP::QSignal&gt;(QP::QHsm::Q_INIT_SIG))
};
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// maximum depth of state nesting in a QHsm (including the top level)
// must be &gt;= 3
static constexpr std::int_fast8_t QHSM_MAX_NEST_DEPTH_ {6};
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
} // unnamed namespace
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// helper macro to handle reserved event in an QHsm
#define QHSM_RESERVED_EVT_(state_, sig_) \
((*(state_))(this, &amp;l_reservedEvt_[(sig_)]))
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// helper macro to trace state entry
#define QS_STATE_ENTRY_(state_, qsId_) \
QS_CRIT_ENTRY(); \
QS_MEM_SYS(); \
QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, (qsId_)) \
QS_OBJ_PRE(this); \
QS_FUN_PRE(state_); \
QS_END_PRE() \
QS_MEM_APP(); \
QS_CRIT_EXIT()
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// helper macro to trace state exit
#define QS_STATE_EXIT_(state_, qsId_) \
QS_CRIT_ENTRY(); \
QS_MEM_SYS(); \
QS_BEGIN_PRE(QS_QEP_STATE_EXIT, (qsId_)) \
QS_OBJ_PRE(this); \
QS_FUN_PRE(state_); \
QS_END_PRE() \
QS_MEM_APP(); \
QS_CRIT_EXIT()
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @endcond
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QEP::versionStr[]}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QEP::QHsm}</text>
</file>
<!--${src::qf::qep_msm.cpp}-->
<file name="qep_msm.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//============================================================================
//! @cond INTERNAL
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
Q_DEFINE_THIS_MODULE(&quot;qep_msm&quot;)
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// top-state object for QMsm-style state machines
QP::QMState const l_msm_top_s = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
};
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// maximum depth of state nesting in a QMsm (including the top level)
static constexpr std::int_fast8_t QMSM_MAX_NEST_DEPTH_ {8};
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// maximum length of transition-action array
static constexpr std::int_fast8_t QMSM_MAX_TRAN_LENGTH_ {2*QMSM_MAX_NEST_DEPTH_};
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// maximum depth of entry levels in a MSM for tran. to history.
static constexpr std::int_fast8_t QMSM_MAX_ENTRY_DEPTH_ {4};
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
} // unnamed namespace
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
//! @endcond
//============================================================================
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QEP::QMsm}</text>
</file>
<!--${src::qf::qf_act.cpp}-->
<file name="qf_act.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
//Q_DEFINE_THIS_MODULE(&quot;qf_act&quot;)
} // unnamed namespace
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QF-pkg}
$define ${QF::types::QF_LOG2}
#ifndef Q_UNSAFE
$define ${QF::types::QPtrDis}
#endif</text>
</file>
<!--${src::qf::qf_actq.cpp}-->
<file name="qf_actq.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2024-10-15 13:15:28 -04:00
//============================================================================
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_actq&quot;)
} // unnamed namespace
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::post_}
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::postLIFO}
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::get_}
2024-10-15 13:15:28 -04:00
$define ${QF::QTicker}</text>
</file>
<!--${src::qf::qf_defer.cpp}-->
<file name="qf_defer.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_defer&quot;)
} // unnamed namespace
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::defer}
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::recall}
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::flushDeferred}</text>
</file>
<!--${src::qf::qf_dyn.cpp}-->
<file name="qf_dyn.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2024-10-15 13:15:28 -04:00
#if (QF_MAX_EPOOL &gt; 0U) // mutable events configured?
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_dyn&quot;)
} // unnamed namespace
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QF-dyn}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
#endif // (QF_MAX_EPOOL &gt; 0U) mutable events configured</text>
</file>
<!--${src::qf::qf_mem.cpp}-->
<file name="qf_mem.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_mem&quot;)
} // unnamed namespace
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QMPool}</text>
</file>
<!--${src::qf::qf_qact.cpp}-->
<file name="qf_qact.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_qact&quot;)
} // unnamed namespace
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::QActive}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::register_}
$define ${QF::QActive::unregister_}</text>
</file>
<!--${src::qf::qf_qmact.cpp}-->
<file name="qf_qmact.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
//Q_DEFINE_THIS_MODULE(&quot;qf_qmact&quot;)
} // unnamed namespace
2024-10-15 13:15:28 -04:00
$define ${QF::QMActive}</text>
2022-08-11 15:36:19 -04:00
</file>
2024-10-15 13:15:28 -04:00
<!--${src::qf::qf_qeq.cpp}-->
<file name="qf_qeq.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
2024-10-15 13:15:28 -04:00
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_qeq&quot;)
} // unnamed namespace
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QEQueue}</text>
</file>
<!--${src::qf::qf_ps.cpp}-->
<file name="qf_ps.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_ps&quot;)
} // unnamed namespace
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::subscrList_}
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::maxPubSignal_}
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::psInit}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::publish_}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::subscribe}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::unsubscribe}
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QActive::unsubscribeAll}</text>
</file>
<!--${src::qf::qf_time.cpp}-->
<file name="qf_time.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qf_time&quot;)
} // unnamed namespace
2022-08-11 15:36:19 -04:00
2024-10-15 13:15:28 -04:00
$define ${QF::QTimeEvt}</text>
</file>
</directory>
<!--${src::qv}-->
<directory name="qv">
<!--${src::qv::qv.cpp}-->
<file name="qv.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2024-10-15 13:15:28 -04:00
// protection against including this source file in a wrong project
#ifndef QV_HPP_
#error &quot;Source file included in a project NOT based on the QV kernel&quot;
#endif // QV_HPP_
// unnamed namespace for local definitions with internal linkage
namespace {
2024-10-15 13:15:28 -04:00
Q_DEFINE_THIS_MODULE(&quot;qv&quot;)
} // unnamed namespace
2024-10-15 13:15:28 -04:00
$define ${QV::QV-base}
2024-10-15 13:15:28 -04:00
$define ${QV::QF-cust}
2024-10-15 13:15:28 -04:00
$define ${QV::QActive}</text>
</file>
</directory>
<!--${src::qk}-->
<directory name="qk">
<!--${src::qk::qk.cpp}-->
<file name="qk.cpp">
<text>#define QP_IMPL // this is QP implementation
#include &quot;qp_port.hpp&quot; // QP port
#include &quot;qp_pkg.hpp&quot; // QP package-scope interface
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
#ifdef Q_SPY // QS software tracing enabled?
#include &quot;qs_port.hpp&quot; // QS port
#include &quot;qs_pkg.hpp&quot; // QS facilities for pre-defined trace records
#else
#include &quot;qs_dummy.hpp&quot; // disable the QS software tracing
#endif // Q_SPY
2024-10-15 13:15:28 -04:00
// protection against including this source file in a wrong project
#ifndef QK_HPP_
#error &quot;Source file included in a project NOT based on the QK kernel&quot;
#endif // QK_HPP_
2024-10-15 13:15:28 -04:00
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_MODULE(&quot;qk&quot;)
} // unnamed namespace
2024-10-15 13:15:28 -04:00
$define ${QK::QK-base}
2024-10-15 13:15:28 -04:00
extern &quot;C&quot; {
$define ${QK-extern-C}
} // extern &quot;C&quot;
2024-10-15 13:15:28 -04:00
$define ${QK::QF-cust}
2022-08-28 22:12:27 -04:00
2024-10-15 13:15:28 -04:00
$define ${QK::QActive}</text>
2022-08-11 15:36:19 -04:00
</file>
2024-10-15 13:15:28 -04:00
</directory>
<!--${src::qs}-->
<directory name="qs">
<!--${src::qs::qstamp.cpp}-->
<file name="qstamp.cpp">
<text>#include &quot;qstamp.hpp&quot;
namespace QP {
char const BUILD_DATE[12] = __DATE__;
char const BUILD_TIME[9] = __TIME__;
} // namespace QP</text>
</file>
2022-08-11 15:36:19 -04:00
</directory>
</directory>
</model>