bool GuiQMActive::post_(QEvt const * const e, uint_fast16_t const /*margin*/, void const * const sender) #endif { QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS::priv_.aoObjFilter, this) QS_TIME_(); // timestamp QS_OBJ_(sender); // the sender object QS_SIG_(e->sig); // the signal of the event QS_OBJ_(this); // this active object QS_2U8_(QF_EVT_POOL_ID_(e), /* the poolID of the event */ QF_EVT_REF_CTR_(e)); // the ref Ctr of the event QS_EQC_(0); // number of free entries (not used) QS_EQC_(0); // min number of free entries (not used) QS_END_NOCRIT_() // is it a dynamic event? if (QF_EVT_POOL_ID_(e) != static_cast<uint8_t>(0)) { QF_EVT_REF_CTR_INC_(e); // increment the reference counter } QF_CRIT_EXIT_(); // QCoreApplication::postEvent() is thread-safe per Qt documentation QCoreApplication::postEvent(QApplication::instance(), new QP_Event(e)); return true; }
QP_BEGIN_ //Q_DEFINE_THIS_MODULE("qeq_get") //............................................................................ QEvt const *QEQueue::get(void) { QEvt const *e; QF_CRIT_STAT_ QF_CRIT_ENTRY_(); if (m_frontEvt == null_evt) { // is the queue empty? e = null_evt; // no event available at this time } else { e = m_frontEvt; if (m_nFree != m_end) { // any events in the the ring buffer? m_frontEvt = QF_PTR_AT_(m_ring, m_tail); // remove from the tail if (m_tail == static_cast<QEQueueCtr>(0)) { // need to wrap? m_tail = m_end; // wrap around } --m_tail; ++m_nFree; // one more free event in the ring buffer QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET, QS::eqObj_, this) QS_TIME_(); // timestamp QS_SIG_(e->sig); // the signal of this event QS_OBJ_(this); // this queue 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_nFree); // number of free entries QS_END_NOCRIT_() } else {
/*..........................................................................*/ uint8_t QTimeEvt_rearm(QTimeEvt * const me, QTimeEvtCtr const nTicks) { uint8_t isArmed; QF_CRIT_STAT_ Q_REQUIRE((nTicks != (QTimeEvtCtr)0) /* cannot arm a timer with 0 ticks */ && (me->act != (QActive *)0) /* active object must be valid */ && (me->super.sig >= (QSignal)Q_USER_SIG)); /* valid signal */ QF_CRIT_ENTRY_(); if (me->ctr == (QTimeEvtCtr)0) { /* is the time evt disarmed? */ isArmed = (uint8_t)0; if (QF_EVT_REF_CTR_(&me->super) == (uint8_t)0) { /* not linked? */ me->next = QF_timeEvtListHead_; QF_timeEvtListHead_ = me; QF_EVT_REF_CTR_INC_(&me->super); /* mark as linked */ } } else { /* the time event is armed */ isArmed = (uint8_t)1; } me->ctr = nTicks; /* re-load the tick counter (shift the phasing) */ QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_REARM, QS_teObj_, me) QS_TIME_(); /* timestamp */ QS_OBJ_(me); /* this time event object */ QS_OBJ_(me->act); /* the active object */ QS_TEC_(me->ctr); /* the number of ticks */ QS_TEC_(me->interval); /* the interval */ QS_U8_(isArmed); /* was the timer armed? */ QS_END_NOCRIT_() QF_CRIT_EXIT_(); return isArmed; }
/*..........................................................................*/ QEvent const *QEQueue_get(QEQueue *me) { QEvent const *e; QF_CRIT_STAT_ QF_CRIT_ENTRY_(); if (me->frontEvt == (QEvent *)0) { /* is the queue empty? */ e = (QEvent *)0; /* no event available at this time */ } else { /* the queue is not empty */ e = me->frontEvt; if (me->nFree != me->end) { /* any events in the ring buffer? */ me->frontEvt = QF_PTR_AT_(me->ring, me->tail); /* get from tail */ if (me->tail == (QEQueueCtr)0) { /* need to wrap the tail? */ me->tail = me->end; /* wrap around */ } --me->tail; ++me->nFree; /* one more free event in the ring buffer */ QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_GET, QS_eqObj_, me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this queue 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_(me->nFree); /* number of free entries */ QS_END_NOCRIT_() } else {
/*..........................................................................*/ uint8_t QActive_recall(QActive *me, QEQueue *eq) { QEvent const *e = QEQueue_get(eq); /* get an event from deferred queue */ uint8_t recalled; if (e != (QEvent const *)0) { /* event available? */ QF_CRIT_STAT_ QActive_postLIFO(me, e); /* post it to the front of the AO's queue */ QF_CRIT_ENTRY_(); if (QF_EVT_POOL_ID_(e) != (uint8_t)0) { /* is it a dynamic event? */ /* after posting to the AO's queue the event must be referenced * at least twice: once in the deferred event queue (eq->get() * did NOT decrement the reference counter) and once in the * AO's event queue. */ Q_ASSERT(QF_EVT_REF_CTR_(e) > (uint8_t)1); /* we need to decrement the reference counter once, to account * for removing the event from the deferred event queue. */ QF_EVT_REF_CTR_DEC_(e); /* decrement the reference counter */ } QF_CRIT_EXIT_(); recalled = (uint8_t)1; } else { recalled = (uint8_t)0; } return recalled; }
//............................................................................ 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)); } } }
//............................................................................ 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_(); }
/*..........................................................................*/ void QEQueue_postLIFO(QEQueue *me, QEvent const *e) { QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_LIFO, QS_eqObj_, me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this queue 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_(me->nFree); /* number of free entries */ QS_EQC_(me->nMin); /* min number of free entries */ QS_END_NOCRIT_() if (QF_EVT_POOL_ID_(e) != (uint8_t)0) { /* is it a pool event? */ QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ } if (me->frontEvt != (QEvent *)0) { /* is the queue not empty? */ /* the queue must be able to accept the event (cannot overflow) */ Q_ASSERT(me->nFree != (QEQueueCtr)0); ++me->tail; if (me->tail == me->end) { /* need to wrap the tail? */ me->tail = (QEQueueCtr)0; /* wrap around */ } QF_PTR_AT_(me->ring, me->tail) = me->frontEvt;/* save old front evt */ --me->nFree; /* update number of free events */ if (me->nMin > me->nFree) { me->nMin = me->nFree; /* update minimum so far */ } } me->frontEvt = e; /* stick the new event to the front */ QF_CRIT_EXIT_(); }