示例#1
0
//****************************************************************************
/// @description
/// This function implements a simple garbage collector for dynamic events.
/// Only dynamic events are candidates for recycling. (A dynamic event is one
/// that is allocated from an event pool, which is determined as non-zero
/// e->poolId_ attribute.) Next, the function decrements the reference counter
/// of the event (e->refCtr_), and recycles the event only if the counter
/// drops to zero (meaning that no more references are outstanding for this
/// event). The dynamic event is recycled by returning it to the pool from
/// which it was originally allocated.
///
/// @param[in]  e  pointer to the event to recycle
///
/// @note
/// QF invokes the garbage collector at all appropriate contexts, when
/// an event can become garbage (automatic garbage collection), so the
/// application code should have no need to call QP::QF::gc() directly.
/// The QP::QF::gc() function is exposed only for special cases when your
/// application sends dynamic events to the "raw" thread-safe queues
/// (see QP::QEQueue). Such queues are processed outside of QF and the
/// automatic garbage collection is **NOT** performed for these events.
/// In this case you need to call QP::QF::gc() explicitly.
///
void QF::gc(QEvt const * const e) {
    // is it a dynamic event?
    if (QF_EVT_POOL_ID_(e) != static_cast<uint8_t>(0)) {
        QF_CRIT_STAT_
        QF_CRIT_ENTRY_();

        // isn't this the last reference?
        if (e->refCtr_ > static_cast<uint8_t>(1)) {
            QF_EVT_REF_CTR_DEC_(e); // decrement the ref counter

            QS_BEGIN_NOCRIT_(QS_QF_GC_ATTEMPT,
                static_cast<void *>(0), static_cast<void *>(0))
                QS_TIME_();        // timestamp
                QS_SIG_(e->sig);   // the signal of the event
                QS_2U8_(e->poolId_, e->refCtr_);// pool Id & refCtr of the evt
            QS_END_NOCRIT_()

            QF_CRIT_EXIT_();
        }
        // this is the last reference to this event, recycle it
        else {
            uint_fast8_t idx = static_cast<uint_fast8_t>(e->poolId_)
                               - static_cast<uint_fast8_t>(1);

            QS_BEGIN_NOCRIT_(QS_QF_GC,
                static_cast<void *>(0), static_cast<void *>(0))
                QS_TIME_();        // timestamp
                QS_SIG_(e->sig);   // the signal of the event
                QS_2U8_(e->poolId_, e->refCtr_);// pool Id & refCtr of the evt
            QS_END_NOCRIT_()

            QF_CRIT_EXIT_();

            // pool ID must be in range
            Q_ASSERT_ID(410, idx < QF_maxPool_);

#ifdef Q_EVT_VIRTUAL
            // explicitly exectute the destructor'
            // NOTE: casting 'const' away is legitimate,
            // because it's a pool event
            QF_EVT_CONST_CAST_(e)->~QEvt(); // xtor,
#endif
            // cast 'const' away, which is OK, because it's a pool event
            QF_EPOOL_PUT_(QF_pool_[idx], QF_EVT_CONST_CAST_(e));
        }
    }
}
示例#2
0
文件: qf_gc.cpp 项目: dongkc/rtu_drv
//............................................................................
void QF::gc(QEvt const * const e) {
    if (QF_EVT_POOL_ID_(e) != u8_0) {                // is it a dynamic event?
        QF_CRIT_STAT_
        QF_CRIT_ENTRY_();

        if (QF_EVT_REF_CTR_(e) > u8_1) {     // isn't this the last reference?
            QF_EVT_REF_CTR_DEC_(e);               // decrement the ref counter

            QS_BEGIN_NOCRIT_(QS_QF_GC_ATTEMPT, null_void, null_void)
                QS_TIME_();                                       // timestamp
                QS_SIG_(e->sig);                    // the signal of the event
                QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
                QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
            QS_END_NOCRIT_()

            QF_CRIT_EXIT_();
        }
        else {         // this is the last reference to this event, recycle it
            uint8_t idx = static_cast<uint8_t>(QF_EVT_POOL_ID_(e) - u8_1);

            QS_BEGIN_NOCRIT_(QS_QF_GC, null_void, null_void)
                QS_TIME_();                                       // timestamp
                QS_SIG_(e->sig);                    // the signal of the event
                QS_U8_(QF_EVT_POOL_ID_(e));        // the pool Id of the event
                QS_U8_(QF_EVT_REF_CTR_(e));      // the ref count of the event
            QS_END_NOCRIT_()

            QF_CRIT_EXIT_();

            Q_ASSERT(idx < QF_maxPool_);

#ifdef Q_EVT_VIRTUAL
            QF_EVT_CONST_CAST_(e)->~QEvt();        // xtor, cast 'const' away,
                             // which is legitimate, because it's a pool event
#endif
                  // cast 'const' away, which is OK, because it's a pool event
            QF_EPOOL_PUT_(QF_pool_[idx], QF_EVT_CONST_CAST_(e));
        }
    }
}
示例#3
0
//............................................................................
void QF::gc(QEvent const *e) {
    if (e->dynamic_ != (uint8_t)0) {                 // is it a dynamic event?
        QF_INT_LOCK_KEY_
        QF_INT_LOCK_();

        if ((e->dynamic_ & 0x3F) > 1) {      // isn't this the last reference?

            //lint -e1773                           Attempt to cast away const
            --((QEvent *)e)->dynamic_;      // decrement the reference counter
                   // NOTE: cast the 'const' away, which is legitimate because
                   // it's a dynamic event

            QS_BEGIN_NOLOCK_(QS_QF_GC_ATTEMPT, (void *)0, (void *)0)
                QS_TIME_();                                       // timestamp
                QS_SIG_(e->sig);                    // the signal of the event
                QS_U8_(e->dynamic_);    // the dynamic attributes of the event
            QS_END_NOLOCK_()

            QF_INT_UNLOCK_();
        }
        else {         // this is the last reference to this event, recycle it
            uint8_t idx = (uint8_t)((e->dynamic_ >> 6) - 1);

            QS_BEGIN_NOLOCK_(QS_QF_GC, (void *)0, (void *)0)
                QS_TIME_();                                       // timestamp
                QS_SIG_(e->sig);                    // the signal of the event
                QS_U8_(e->dynamic_);    // the dynamic attributes of the event
            QS_END_NOLOCK_()

            QF_INT_UNLOCK_();

            Q_ASSERT(idx < QF_maxPool_);

            //lint -e1773                           Attempt to cast away const
            QF_EPOOL_PUT_(QF_pool_[idx], (QEvent *)e);   // cast 'const' away,
                             // which is legitimate, because it's a pool event
        }
    }