Fixed bug in QXK activator
This commit is contained in:
MMS 2023-01-11 12:06:55 -05:00
parent 532d29c33d
commit 8c5a806c8e
5 changed files with 42 additions and 66 deletions

View File

@ -59,7 +59,7 @@
3 1 18 0 3 QP::QSpyId::getPrio@335-337@..\include\qs.hpp 3 1 18 0 3 QP::QSpyId::getPrio@335-337@..\include\qs.hpp
7 1 28 1 7 QP::QS::force_cast@417-423@..\include\qs.hpp 7 1 28 1 7 QP::QS::force_cast@417-423@..\include\qs.hpp
14 3 70 1 14 QP::QS::rxPut@831-844@..\include\qs.hpp 14 3 70 1 14 QP::QS::rxPut@831-844@..\include\qs.hpp
9 1 49 5 9 QP::QActiveDummy::start@1573-1581@..\include\qs.hpp 9 1 49 5 9 QP::QActiveDummy::start@1562-1570@..\include\qs.hpp
3 1 18 0 3 QP::QSpyId::getPrio@137-139@..\include\qs_dummy.hpp 3 1 18 0 3 QP::QSpyId::getPrio@137-139@..\include\qs_dummy.hpp
3 1 11 0 3 QP::QXThread::getTimeEvt@208-210@..\include\qxk.hpp 3 1 11 0 3 QP::QXThread::getTimeEvt@208-210@..\include\qxk.hpp
9 1 49 5 9 QP::QXThread::start@310-318@..\include\qxk.hpp 9 1 49 5 9 QP::QXThread::start@310-318@..\include\qxk.hpp

View File

@ -1228,9 +1228,9 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
//! and the binary address of the state machine that consumes that signal //! and the binary address of the state machine that consumes that signal
//! with the human-readable name of the signal. //! with the human-readable name of the signal.
//! //!
//! Providing a signal dictionary QS record can vastly improve readability of //! @param[in] sig_ event signal (typically enumerated, e.g. `TIMEOUT_SIG`)
//! the QS log, because instead of dealing with cryptic machine addresses the //! @param[in] obj_ pointer to the associated state machine object
//! QSpy host utility can display human-readable names. //! (might be `nullptr` for globally recognized signals)
//! //!
//! A signal dictionary entry is associated with both the signal value `sig_` //! A signal dictionary entry is associated with both the signal value `sig_`
//! and the state machine `obj_`, because signals are required to be unique //! and the state machine `obj_`, because signals are required to be unique
@ -1239,40 +1239,30 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
//! //!
//! For the "global" signals that have the same meaning in all state machines //! For the "global" signals that have the same meaning in all state machines
//! (such as globally published signals), you can specify a signal dictionary //! (such as globally published signals), you can specify a signal dictionary
//! entry with the `obj_` parameter set to NULL. //! entry with the `obj_` parameter set to `nullptr`.
//! //!
//! The following example shows the definition of signal dictionary entries //! The following example shows the definition of signal dictionary entries
//! in the initial transition of the Table active object. Please note that //! in the initial transition of the Table active object. Please note that
//! signals HUNGRY_SIG and DONE_SIG are associated with the Table state //! signals HUNGRY_SIG and DONE_SIG are associated with the Table state
//! machine only ("me" `obj_` pointer). The EAT_SIG signal, on the other //! machine only ("me" `obj_` pointer). The EAT_SIG signal, on the other
//! hand, is global (0 `obj_` pointer): //! hand, is global (`obj_ == nullptr`):
//! @include qs_sigDic.cpp //! @include qs_sigDic.cpp
//! //!
//! @note The QSpy log utility must capture the signal dictionary record
//! in order to use the human-readable information. You need to connect to
//! the target before the dictionary entries have been transmitted.
//!
//! The following QSpy log example shows the signal dictionary records //! The following QSpy log example shows the signal dictionary records
//! generated from the Table initial transition and subsequent records that //! generated from the Table initial transition and subsequent records that
//! show human-readable names of the signals: //! show human-readable names of the signals:
//! @include qs_sigLog.txt //! @include qs_sigLog.txt
//!
//! The following QSpy log example shows the same sequence of records, but
//! with dictionary records removed. The human-readable signal names are not
//! available.
#define QS_SIG_DICTIONARY(sig_, obj_) \ #define QS_SIG_DICTIONARY(sig_, obj_) \
(QP::QS::sig_dict_pre_((sig_), (obj_), #sig_)) (QP::QS::sig_dict_pre_((sig_), (obj_), #sig_))
//${QS-macros::QS_OBJ_DICTIONARY} ............................................ //${QS-macros::QS_OBJ_DICTIONARY} ............................................
//! Output object dictionary record //! Output QS object dictionary record
//! //!
//! @details //! @details
//! An object dictionary record associates the binary address of an object //! An object dictionary record associates the binary address of an object
//! in the target's memory with the human-readable name of the object. //! in the target's memory with the human-readable name of the object.
//! //!
//! Providing an object dictionary QS record can vastly improve readability of //! @param[in] obj_ pointer to the object (any object)
//! the QS log, because instead of dealing with cryptic machine addresses the
//! QSpy host utility can display human-readable object names.
//! //!
//! The following example shows the definition of object dictionary entry //! The following example shows the definition of object dictionary entry
//! for the Table active object: //! for the Table active object:
@ -1281,20 +1271,19 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
(QP::QS::obj_dict_pre_((obj_), #obj_)) (QP::QS::obj_dict_pre_((obj_), #obj_))
//${QS-macros::QS_OBJ_ARR_DICTIONARY} ........................................ //${QS-macros::QS_OBJ_ARR_DICTIONARY} ........................................
//! Output object-array dictionary record //! Output QS object-array dictionary record
//! //!
//! @details //! @details
//! An object array dictionary record associates the binary address of the //! An object array dictionary record associates the binary address of the
//! object element in the target's memory with the human-readable name //! object element in the target's memory with the human-readable name
//! of the object. //! of the object.
//! //!
//! Providing a dictionary QS record can vastly improve readability of //! @param[in] obj_ pointer to the object (any object)
//! the QS log, because instead of dealing with cryptic machine addresses the //! @param[in] idx_ array index
//! QSpy host utility can display human-readable object names.
//! //!
//! The following example shows the definition of object array dictionary //! The following example shows the definition of object array dictionary
//! for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`: //! for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`:
//! @include qs_objDic.cpp //! @include qs_objArrDic.cpp
#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \ #define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \
(QP::QS::obj_arr_dict_pre_((obj_), (idx_), #obj_)) (QP::QS::obj_arr_dict_pre_((obj_), (idx_), #obj_))

View File

@ -6348,9 +6348,9 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
//! and the binary address of the state machine that consumes that signal //! and the binary address of the state machine that consumes that signal
//! with the human-readable name of the signal. //! with the human-readable name of the signal.
//! //!
//! Providing a signal dictionary QS record can vastly improve readability of //! @param[in] sig_ event signal (typically enumerated, e.g. `TIMEOUT_SIG`)
//! the QS log, because instead of dealing with cryptic machine addresses the //! @param[in] obj_ pointer to the associated state machine object
//! QSpy host utility can display human-readable names. //! (might be `nullptr` for globally recognized signals)
//! //!
//! A signal dictionary entry is associated with both the signal value `sig_` //! A signal dictionary entry is associated with both the signal value `sig_`
//! and the state machine `obj_`, because signals are required to be unique //! and the state machine `obj_`, because signals are required to be unique
@ -6359,27 +6359,19 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
//! //!
//! For the "global" signals that have the same meaning in all state machines //! For the "global" signals that have the same meaning in all state machines
//! (such as globally published signals), you can specify a signal dictionary //! (such as globally published signals), you can specify a signal dictionary
//! entry with the `obj_` parameter set to NULL. //! entry with the `obj_` parameter set to `nullptr`.
//! //!
//! The following example shows the definition of signal dictionary entries //! The following example shows the definition of signal dictionary entries
//! in the initial transition of the Table active object. Please note that //! in the initial transition of the Table active object. Please note that
//! signals HUNGRY_SIG and DONE_SIG are associated with the Table state //! signals HUNGRY_SIG and DONE_SIG are associated with the Table state
//! machine only ("me" `obj_` pointer). The EAT_SIG signal, on the other //! machine only ("me" `obj_` pointer). The EAT_SIG signal, on the other
//! hand, is global (0 `obj_` pointer): //! hand, is global (`obj_ == nullptr`):
//! @include qs_sigDic.cpp //! @include qs_sigDic.cpp
//! //!
//! @note The QSpy log utility must capture the signal dictionary record
//! in order to use the human-readable information. You need to connect to
//! the target before the dictionary entries have been transmitted.
//!
//! The following QSpy log example shows the signal dictionary records //! The following QSpy log example shows the signal dictionary records
//! generated from the Table initial transition and subsequent records that //! generated from the Table initial transition and subsequent records that
//! show human-readable names of the signals: //! show human-readable names of the signals:
//! @include qs_sigLog.txt //! @include qs_sigLog.txt</documentation>
//!
//! The following QSpy log example shows the same sequence of records, but
//! with dictionary records removed. The human-readable signal names are not
//! available.</documentation>
<!--${QS-macros::QS_SIG_DICTIONAR~::sig_}--> <!--${QS-macros::QS_SIG_DICTIONAR~::sig_}-->
<parameter name="sig_" type="QP::QSignal"/> <parameter name="sig_" type="QP::QSignal"/>
<!--${QS-macros::QS_SIG_DICTIONAR~::obj_}--> <!--${QS-macros::QS_SIG_DICTIONAR~::obj_}-->
@ -6389,15 +6381,13 @@ if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qs_id_)) { \
</operation> </operation>
<!--${QS-macros::QS_OBJ_DICTIONARY}--> <!--${QS-macros::QS_OBJ_DICTIONARY}-->
<operation name="QS_OBJ_DICTIONARY" type="void" visibility="0x03" properties="0x00"> <operation name="QS_OBJ_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<documentation>//! Output object dictionary record <documentation>//! Output QS object dictionary record
//! //!
//! @details //! @details
//! An object dictionary record associates the binary address of an object //! An object dictionary record associates the binary address of an object
//! in the target's memory with the human-readable name of the object. //! in the target's memory with the human-readable name of the object.
//! //!
//! Providing an object dictionary QS record can vastly improve readability of //! @param[in] obj_ pointer to the object (any object)
//! the QS log, because instead of dealing with cryptic machine addresses the
//! QSpy host utility can display human-readable object names.
//! //!
//! The following example shows the definition of object dictionary entry //! The following example shows the definition of object dictionary entry
//! for the Table active object: //! for the Table active object:
@ -6409,20 +6399,19 @@ if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qs_id_)) { \
</operation> </operation>
<!--${QS-macros::QS_OBJ_ARR_DICTIONARY}--> <!--${QS-macros::QS_OBJ_ARR_DICTIONARY}-->
<operation name="QS_OBJ_ARR_DICTIONARY" type="void" visibility="0x03" properties="0x00"> <operation name="QS_OBJ_ARR_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<documentation>//! Output object-array dictionary record <documentation>//! Output QS object-array dictionary record
//! //!
//! @details //! @details
//! An object array dictionary record associates the binary address of the //! An object array dictionary record associates the binary address of the
//! object element in the target's memory with the human-readable name //! object element in the target's memory with the human-readable name
//! of the object. //! of the object.
//! //!
//! Providing a dictionary QS record can vastly improve readability of //! @param[in] obj_ pointer to the object (any object)
//! the QS log, because instead of dealing with cryptic machine addresses the //! @param[in] idx_ array index
//! QSpy host utility can display human-readable object names.
//! //!
//! The following example shows the definition of object array dictionary //! The following example shows the definition of object array dictionary
//! for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`: //! for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`:
//! @include qs_objDic.cpp</documentation> //! @include qs_objArrDic.cpp</documentation>
<!--${QS-macros::QS_OBJ_ARR_DICTI~::obj_}--> <!--${QS-macros::QS_OBJ_ARR_DICTI~::obj_}-->
<parameter name="obj_" type="void const *"/> <parameter name="obj_" type="void const *"/>
<!--${QS-macros::QS_OBJ_ARR_DICTI~::idx_}--> <!--${QS-macros::QS_OBJ_ARR_DICTI~::idx_}-->
@ -10038,10 +10027,11 @@ std::uint8_t pprev = prio_in;
QP::QActive *a; QP::QActive *a;
do { do {
a = QP::QActive::registry_[p]; // obtain the pointer to the AO a = QP::QActive::registry_[p]; // obtain the pointer to the AO
Q_ASSERT_ID(505, a != nullptr); // the AO must be registered
// set new active priority and preemption-ceiling // set new active priority and preemption-ceiling
QK_attr_.actPrio = p; QK_attr_.actPrio = p;
QK_attr_.actThre = QP::QActive::registry_[p]-&gt;m_pthre; QK_attr_.actThre = a-&gt;m_pthre;
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (p != pprev) { // changing threads? if (p != pprev) { // changing threads?
@ -12113,22 +12103,20 @@ do {
p = 0U; // no activation needed p = 0U; // no activation needed
} }
else { else {
// find new highest-prio AO ready to run... // find next highest-prio below the lock ceiling
p = static_cast&lt;std::uint8_t&gt;(QP::QF::readySet_.findMax()); p = static_cast&lt;std::uint8_t&gt;(QP::QF::readySet_.findMax());
next = QP::QActive::registry_[p];
// the AO must be registered in QF
Q_ASSERT_ID(710, next != nullptr);
// is the new priority below the lock ceiling?
if (p &lt;= QXK_attr_.lockCeil) { if (p &lt;= QXK_attr_.lockCeil) {
p = QXK_attr_.lockHolder; p = QXK_attr_.lockHolder;
if (p != 0U) { if (p != 0U) {
Q_ASSERT_ID(720, QP::QF::readySet_.hasElement(p)); Q_ASSERT_ID(710, QP::QF::readySet_.hasElement(p));
} }
} }
// is the next a basic thread? // set the next thread and ensure that it is registered
next = QP::QActive::registry_[p];
Q_ASSERT_ID(720, next != nullptr);
// is next a basic thread?
if (next-&gt;m_osObject == nullptr) { if (next-&gt;m_osObject == nullptr) {
// is the next priority above the initial priority? // is the next priority above the initial priority?
if (p &gt; QP::QActive::registry_[prio_in]-&gt;m_prio) { if (p &gt; QP::QActive::registry_[prio_in]-&gt;m_prio) {

View File

@ -314,10 +314,11 @@ void QK_activate_() noexcept {
QP::QActive *a; QP::QActive *a;
do { do {
a = QP::QActive::registry_[p]; // obtain the pointer to the AO a = QP::QActive::registry_[p]; // obtain the pointer to the AO
Q_ASSERT_ID(505, a != nullptr); // the AO must be registered
// set new active priority and preemption-ceiling // set new active priority and preemption-ceiling
QK_attr_.actPrio = p; QK_attr_.actPrio = p;
QK_attr_.actThre = QP::QActive::registry_[p]->m_pthre; QK_attr_.actThre = a->m_pthre;
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (p != pprev) { // changing threads? if (p != pprev) { // changing threads?

View File

@ -387,22 +387,20 @@ void QXK_activate_() noexcept {
p = 0U; // no activation needed p = 0U; // no activation needed
} }
else { else {
// find new highest-prio AO ready to run... // find next highest-prio below the lock ceiling
p = static_cast<std::uint8_t>(QP::QF::readySet_.findMax()); p = static_cast<std::uint8_t>(QP::QF::readySet_.findMax());
next = QP::QActive::registry_[p];
// the AO must be registered in QF
Q_ASSERT_ID(710, next != nullptr);
// is the new priority below the lock ceiling?
if (p <= QXK_attr_.lockCeil) { if (p <= QXK_attr_.lockCeil) {
p = QXK_attr_.lockHolder; p = QXK_attr_.lockHolder;
if (p != 0U) { if (p != 0U) {
Q_ASSERT_ID(720, QP::QF::readySet_.hasElement(p)); Q_ASSERT_ID(710, QP::QF::readySet_.hasElement(p));
} }
} }
// is the next a basic thread? // set the next thread and ensure that it is registered
next = QP::QActive::registry_[p];
Q_ASSERT_ID(720, next != nullptr);
// is next a basic thread?
if (next->m_osObject == nullptr) { if (next->m_osObject == nullptr) {
// is the next priority above the initial priority? // is the next priority above the initial priority?
if (p > QP::QActive::registry_[prio_in]->m_prio) { if (p > QP::QActive::registry_[prio_in]->m_prio) {