Example #1
0
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 */
}
Example #2
0
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.
}