mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-28 06:02:56 +08:00
7.2.1
Fixed bug in QXK activator
This commit is contained in:
parent
532d29c33d
commit
8c5a806c8e
@ -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
|
||||||
|
@ -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_))
|
||||||
|
|
||||||
|
54
qpcpp.qm
54
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
|
//! 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_) && 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_) && 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]->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?
|
||||||
@ -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<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) {
|
||||||
|
@ -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?
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user