From 8c5a806c8e8f7a4c3b06631ddb9f03576682778e Mon Sep 17 00:00:00 2001 From: MMS Date: Wed, 11 Jan 2023 12:06:55 -0500 Subject: [PATCH] 7.2.1 Fixed bug in QXK activator --- doxygen/gen/metrics.txt | 2 +- include/qs.hpp | 33 +++++++++---------------- qpcpp.qm | 54 ++++++++++++++++------------------------- src/qk/qk.cpp | 3 ++- src/qxk/qxk.cpp | 16 ++++++------ 5 files changed, 42 insertions(+), 66 deletions(-) diff --git a/doxygen/gen/metrics.txt b/doxygen/gen/metrics.txt index 091a23a5..d5771db7 100644 --- a/doxygen/gen/metrics.txt +++ b/doxygen/gen/metrics.txt @@ -59,7 +59,7 @@ 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 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 11 0 3 QP::QXThread::getTimeEvt@208-210@..\include\qxk.hpp 9 1 49 5 9 QP::QXThread::start@310-318@..\include\qxk.hpp diff --git a/include/qs.hpp b/include/qs.hpp index 493077a4..c7c82bab 100644 --- a/include/qs.hpp +++ b/include/qs.hpp @@ -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 //! with the human-readable name of the signal. //! -//! Providing a signal dictionary QS record can vastly improve readability of -//! the QS log, because instead of dealing with cryptic machine addresses the -//! QSpy host utility can display human-readable names. +//! @param[in] sig_ event signal (typically enumerated, e.g. `TIMEOUT_SIG`) +//! @param[in] obj_ pointer to the associated state machine object +//! (might be `nullptr` for globally recognized signals) //! //! A signal dictionary entry is associated with both the signal value `sig_` //! 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 //! (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 //! in the initial transition of the Table active object. Please note that //! signals HUNGRY_SIG and DONE_SIG are associated with the Table state //! 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 //! -//! @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 //! generated from the Table initial transition and subsequent records that //! show human-readable names of the signals: //! @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_) \ (QP::QS::sig_dict_pre_((sig_), (obj_), #sig_)) //${QS-macros::QS_OBJ_DICTIONARY} ............................................ -//! Output object dictionary record +//! Output QS object dictionary record //! //! @details //! An object dictionary record associates the binary address of an 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 -//! the QS log, because instead of dealing with cryptic machine addresses the -//! QSpy host utility can display human-readable object names. +//! @param[in] obj_ pointer to the object (any object) //! //! The following example shows the definition of object dictionary entry //! 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_)) //${QS-macros::QS_OBJ_ARR_DICTIONARY} ........................................ -//! Output object-array dictionary record +//! Output QS object-array dictionary record //! //! @details //! An object array dictionary record associates the binary address of the //! object element in the target's memory with the human-readable name //! of the object. //! -//! Providing a dictionary QS record can vastly improve readability of -//! the QS log, because instead of dealing with cryptic machine addresses the -//! QSpy host utility can display human-readable object names. +//! @param[in] obj_ pointer to the object (any object) +//! @param[in] idx_ array index //! //! The following example shows the definition of object array dictionary //! 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_) \ (QP::QS::obj_arr_dict_pre_((obj_), (idx_), #obj_)) diff --git a/qpcpp.qm b/qpcpp.qm index b45aee17..90839d36 100644 --- a/qpcpp.qm +++ b/qpcpp.qm @@ -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 //! with the human-readable name of the signal. //! -//! Providing a signal dictionary QS record can vastly improve readability of -//! the QS log, because instead of dealing with cryptic machine addresses the -//! QSpy host utility can display human-readable names. +//! @param[in] sig_ event signal (typically enumerated, e.g. `TIMEOUT_SIG`) +//! @param[in] obj_ pointer to the associated state machine object +//! (might be `nullptr` for globally recognized signals) //! //! A signal dictionary entry is associated with both the signal value `sig_` //! 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 //! (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 //! in the initial transition of the Table active object. Please note that //! signals HUNGRY_SIG and DONE_SIG are associated with the Table state //! 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 //! -//! @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 //! generated from the Table initial transition and subsequent records that //! show human-readable names of the signals: -//! @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. +//! @include qs_sigLog.txt @@ -6389,15 +6381,13 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - //! Output object dictionary record + //! Output QS object dictionary record //! //! @details //! An object dictionary record associates the binary address of an 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 -//! the QS log, because instead of dealing with cryptic machine addresses the -//! QSpy host utility can display human-readable object names. +//! @param[in] obj_ pointer to the object (any object) //! //! The following example shows the definition of object dictionary entry //! for the Table active object: @@ -6409,20 +6399,19 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - //! Output object-array dictionary record + //! Output QS object-array dictionary record //! //! @details //! An object array dictionary record associates the binary address of the //! object element in the target's memory with the human-readable name //! of the object. //! -//! Providing a dictionary QS record can vastly improve readability of -//! the QS log, because instead of dealing with cryptic machine addresses the -//! QSpy host utility can display human-readable object names. +//! @param[in] obj_ pointer to the object (any object) +//! @param[in] idx_ array index //! //! The following example shows the definition of object array dictionary //! for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`: -//! @include qs_objDic.cpp +//! @include qs_objArrDic.cpp @@ -10038,10 +10027,11 @@ std::uint8_t pprev = prio_in; QP::QActive *a; do { 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 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 (p != pprev) { // changing threads? @@ -12113,22 +12103,20 @@ do { p = 0U; // no activation needed } 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()); - 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) { p = QXK_attr_.lockHolder; 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) { // is the next priority above the initial priority? if (p > QP::QActive::registry_[prio_in]->m_prio) { diff --git a/src/qk/qk.cpp b/src/qk/qk.cpp index f96dec25..e12b312d 100644 --- a/src/qk/qk.cpp +++ b/src/qk/qk.cpp @@ -314,10 +314,11 @@ void QK_activate_() noexcept { QP::QActive *a; do { 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 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 (p != pprev) { // changing threads? diff --git a/src/qxk/qxk.cpp b/src/qxk/qxk.cpp index 72b2f310..49bb9582 100644 --- a/src/qxk/qxk.cpp +++ b/src/qxk/qxk.cpp @@ -387,22 +387,20 @@ void QXK_activate_() noexcept { p = 0U; // no activation needed } else { - // find new highest-prio AO ready to run... + // find next highest-prio below the lock ceiling p = static_cast(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) { p = QXK_attr_.lockHolder; 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) { // is the next priority above the initial priority? if (p > QP::QActive::registry_[prio_in]->m_prio) {