void QF_publish_(QEvt const * const e, void const * const sender) #endif { QF_CRIT_STAT_ /* make sure that the published signal is within the configured range */ Q_REQUIRE(e->sig < (QSignal)QF_maxSignal_); QF_CRIT_ENTRY_(); QS_BEGIN_NOCRIT_(QS_QF_PUBLISH, (void *)0, (void *)0) QS_TIME_(); /* the timestamp */ QS_OBJ_(sender); /* the sender object */ QS_SIG_(e->sig); /* the signal of the event */ QS_2U8_(e->poolId_, e->refCtr_);/* pool Id & ref Count of the event */ QS_END_NOCRIT_() if (e->poolId_ != (uint8_t)0) { /* is it a dynamic event? */ QF_EVT_REF_CTR_INC_(e); /* increment reference counter, NOTE01 */ } QF_CRIT_EXIT_(); #if (QF_MAX_ACTIVE <= 8) { uint8_t tmp = QF_subscrList_[e->sig].bits[0]; while (tmp != (uint8_t)0) { uint8_t p = QF_LOG2(tmp); tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]); /* clear subscriber bit */ Q_ASSERT(QF_active_[p] != (QActive *)0); /* must be registered */ /* QACTIVE_POST() asserts internally if the queue overflows */ QACTIVE_POST(QF_active_[p], e, sender); } } #else { uint_t i = (uint_t)Q_DIM(QF_subscrList_[0].bits); do { /* go through all bytes in the subscription list */ uint8_t tmp; --i; tmp = QF_PTR_AT_(QF_subscrList_, e->sig).bits[i]; while (tmp != (uint8_t)0) { uint8_t p = QF_LOG2(tmp); tmp &= Q_ROM_BYTE(QF_invPwr2Lkup[p]);/*clear subscriber bit */ p = (uint8_t)(p + (uint8_t)(i << 3));/* adjust the priority */ Q_ASSERT(QF_active_[p] != (QActive *)0);/*must be registered*/ /* QACTIVE_POST() asserts internally if the queue overflows */ QACTIVE_POST(QF_active_[p], e, sender); } } while (i != (uint_t)0); } #endif QF_gc(e); /* run the garbage collector, see NOTE01 */ }
void QF::publish_(QEvt const * const e) { #else void QF::publish_(QEvt const * const e, void const * const sender) { #endif /// @pre the published signal must be within the configured range Q_REQUIRE_ID(100, static_cast<enum_t>(e->sig) < QF_maxSignal_); QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QS_BEGIN_NOCRIT_(QS_QF_PUBLISH, static_cast<void *>(0), static_cast<void *>(0)) QS_TIME_(); // the timestamp QS_OBJ_(sender); // the sender object QS_SIG_(e->sig); // the signal of the event QS_2U8_(e->poolId_, e->refCtr_); // pool Id & refCtr of the evt QS_END_NOCRIT_() // is it a dynamic event? if (e->poolId_ != static_cast<uint8_t>(0)) { QF_EVT_REF_CTR_INC_(e); // increment the reference counter, NOTE01 } QF_CRIT_EXIT_(); QF_SCHED_STAT_TYPE_ lockStat; lockStat.m_lockPrio = static_cast<uint_fast8_t>(0xFF); // uninitialized #if (QF_MAX_ACTIVE <= 8) uint_fast8_t tmp = static_cast<uint_fast8_t>( QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[0]); while (tmp != static_cast<uint8_t>(0)) { uint_fast8_t p = static_cast<uint_fast8_t>(QF_LOG2(tmp)); // clear the subscriber bit tmp &= static_cast<uint_fast8_t>(QF_invPwr2Lkup[p]); // has the scheduler been locked yet? if (lockStat.m_lockPrio == static_cast<uint_fast8_t>(0xFF)) { QF_SCHED_LOCK_(&lockStat, p); } // the priority of the AO must be registered with the framework Q_ASSERT_ID(110, active_[p] != static_cast<QMActive *>(0)); // POST() asserts internally if the queue overflows (void)active_[p]->POST(e, sender); } #else uint_fast8_t i = static_cast<uint_fast8_t>(QF_SUBSCR_LIST_SIZE); // go through all bytes in the subscription list do { --i; uint_fast8_t tmp = static_cast<uint_fast8_t>( QF_PTR_AT_(QF_subscrList_, e->sig).m_bits[i]); while (tmp != static_cast<uint_fast8_t>(0)) { uint_fast8_t p = static_cast<uint_fast8_t>(QF_LOG2(tmp)); // clear the subscriber bit tmp &= static_cast<uint_fast8_t>(QF_invPwr2Lkup[p]); // adjust the priority p += static_cast<uint_fast8_t>(i << 3); // has the scheduler been locked yet? if (lockStat.m_lockPrio == static_cast<uint_fast8_t>(0xFF)) { QF_SCHED_LOCK_(&lockStat, p); } // the priority level be registered with the framework Q_ASSERT(active_[p] != static_cast<QMActive *>(0)); // POST() asserts internally if the queue overflows (void)active_[p]->POST(e, sender); } } while (i != static_cast<uint_fast8_t>(0)); #endif // was the scheduler locked? if (lockStat.m_lockPrio <= static_cast<uint_fast8_t>(QF_MAX_ACTIVE)) { QF_SCHED_UNLOCK_(&lockStat); // unlock the scheduler } // run the garbage collector gc(e); // NOTE: QP::QF::publish_() increments the reference counter to prevent // premature recycling of the event while the multicasting is still // in progress. At the end of the function, the garbage collector step // 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. }