void QActive_postFIFO(QActive *me, QEvent const *e) { #else void QActive_postFIFO(QActive *me, QEvent const *e, void const *sender) { #endif QF_INT_LOCK_KEY_ QF_INT_LOCK_(); QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_POST_FIFO, QS_aoObj_, me) QS_TIME_(); /* timestamp */ QS_OBJ_(sender); /* the sender object */ QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this active object (recipient) */ QS_U8_(EVT_POOL_ID(e)); /* the pool Id of the event */ QS_U8_(EVT_REF_CTR(e)); /* the ref count of the event */ QS_EQC_(me->eQueue.nFree); /* number of free entries */ QS_EQC_(me->eQueue.nMin); /* min number of free entries */ QS_END_NOLOCK_() if (EVT_POOL_ID(e) != (uint8_t)0) { /* is it a pool event? */ EVT_INC_REF_CTR(e); /* increment the reference counter */ } if (me->eQueue.frontEvt == (QEvent *)0) { /* empty queue? */ me->eQueue.frontEvt = e; /* deliver event directly */ QACTIVE_EQUEUE_SIGNAL_(me); /* signal the event queue */ } else { /* queue is not empty, insert event into the ring-buffer */ /* the queue must be able to accept the event (cannot overflow) */ Q_ASSERT(me->eQueue.nFree != (QEQueueCtr)0); /* insert event into the ring buffer (FIFO) */ me->eQueue.ring[me->eQueue.head] = e; if (me->eQueue.head == (QEQueueCtr)0) { /* need to wrap the head? */ me->eQueue.head = me->eQueue.end; /* wrap around */ } --me->eQueue.head; --me->eQueue.nFree; /* update number of free events */ if (me->eQueue.nMin > me->eQueue.nFree) { me->eQueue.nMin = me->eQueue.nFree; /* update min so far */ } } QF_INT_UNLOCK_(); }
//............................................................................ void QActive::postLIFO(QEvt const * const e) { QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QEQueueCtr nFree = m_eQueue.m_nFree;// tmp to avoid UB for volatile access // the queue must be able to accept the event (cannot overflow) Q_ASSERT(nFree != static_cast<QEQueueCtr>(0)); QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, QS::priv_.aoObjFilter, this) QS_TIME_(); // timestamp QS_SIG_(e->sig); // the signal of this event QS_OBJ_(this); // this active object QS_2U8_(e->poolId_, e->refCtr_); // pool Id & refCtr of the evt QS_EQC_(nFree); // number of free entries QS_EQC_(m_eQueue.m_nMin); // min number of free entries QS_END_NOCRIT_() if (e->poolId_ != u8_0) { // is it a dynamic event? QF_EVT_REF_CTR_INC_(e); // increment the reference counter } --nFree; // one free entry just used up m_eQueue.m_nFree = nFree; // update the volatile if (m_eQueue.m_nMin > nFree) { m_eQueue.m_nMin = nFree; // update minimum so far } QEvt const *frontEvt = m_eQueue.m_frontEvt;// read volatile into temporary m_eQueue.m_frontEvt = e; // deliver the event directly to the front if (frontEvt == null_evt) { // is the queue empty? QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue } else { // queue is not empty, leave event in the ring-buffer ++m_eQueue.m_tail; if (m_eQueue.m_tail == m_eQueue.m_end) { // need to wrap the tail? m_eQueue.m_tail = static_cast<QEQueueCtr>(0); // wrap around } QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail) = frontEvt; } QF_CRIT_EXIT_(); }
//............................................................................ void QActive::postLIFO(QEvt const * const e) { QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, QS::aoObj_, this) QS_TIME_(); // timestamp QS_SIG_(e->sig); // the signal of this event QS_OBJ_(this); // this active object 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_EQC_(m_eQueue.m_nFree); // number of free entries QS_EQC_(m_eQueue.m_nMin); // min number of free entries QS_END_NOCRIT_() if (QF_EVT_POOL_ID_(e) != u8_0) { // is it a dynamic event? QF_EVT_REF_CTR_INC_(e); // increment the reference counter } if (m_eQueue.m_frontEvt == null_evt) { // is the queue empty? m_eQueue.m_frontEvt = e; // deliver event directly QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue } else { // queue is not empty, leave event in the ring-buffer // queue must accept all posted events Q_ASSERT(m_eQueue.m_nFree != static_cast<QEQueueCtr>(0)); ++m_eQueue.m_tail; if (m_eQueue.m_tail == m_eQueue.m_end) { // need to wrap the tail? m_eQueue.m_tail = static_cast<QEQueueCtr>(0); // wrap around } QF_PTR_AT_(m_eQueue.m_ring, m_eQueue.m_tail) = m_eQueue.m_frontEvt; m_eQueue.m_frontEvt = e; // put event to front --m_eQueue.m_nFree; // update number of free events if (m_eQueue.m_nMin > m_eQueue.m_nFree) { m_eQueue.m_nMin = m_eQueue.m_nFree; // update minimum so far } } QF_CRIT_EXIT_(); }