bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) #endif /* Q_SPY */ { uint_fast16_t nFree; bool status; QF_CRIT_STAT_ QF_CRIT_ENTRY_(); nFree = (uint_fast16_t)(me->eQueue.maxMsg - me->eQueue.nofMsg); if (nFree > margin) { QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS_priv_.aoObjFilter, 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_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_EQC_((QEQueueCtr)nFree); /* # free entries available */ QS_EQC_((QEQueueCtr)0); /* min # free entries (unknown) */ QS_END_NOCRIT_() if (e->poolId_ != (uint8_t)0) { /* is it a pool event? */ QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ } /* posting to the embOS mailbox must succeed, see NOTE3 */ Q_ALLEGE(OS_PutMailCond(&me->eQueue, (OS_CONST_PTR void *)&e) == (char)0); status = true; /* return success */ }
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; }
bool QMActive::post_(QEvt const * const e, uint_fast16_t const margin, void const * const sender) #endif { uint_fast16_t nFree; bool status; QF_CRIT_STAT_ QF_CRIT_ENTRY_(); nFree = static_cast<uint_fast16_t>(m_eQueue.maxMsg - m_eQueue.nofMsg); if (nFree > margin) { 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 (recipient) QS_2U8_(e->poolId_, e->refCtr_); // pool Id & ref Count QS_EQC_(static_cast<QEQueueCtr>(nFree)); // # free entries QS_EQC_(static_cast<QEQueueCtr>(0)); // min # free (unknown) QS_END_NOCRIT_() if (e->poolId_ != static_cast<uint8_t>(0)) { // is it a pool event? QF_EVT_REF_CTR_INC_(e); // increment the reference counter } // posting to the embOS mailbox must succeed, see NOTE3 Q_ALLEGE_ID(710, OS_PutMailCond(&m_eQueue, static_cast<OS_CONST_PTR void *>(&e)) == static_cast<char>(0)); status = true; // return success }
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_(0); /* number of free entries (unknown) */ QS_EQC_(0); /* min number of free entries (unknown) */ 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 */ } QF_INT_UNLOCK_(); Q_ALLEGE(OSQPost((OS_EVENT *)me->eQueue, (void *)e) == OS_NO_ERR); }
/*..........................................................................*/ QEvent const *QActive_get_(QActive *me) { QEvent const *e; QF_INT_LOCK_KEY_ QF_INT_LOCK_(); QACTIVE_EQUEUE_WAIT_(me); /* wait for event to arrive directly ^#defined as: Q_ASSERT((me_)->eQueue.frontEvt != (QEvent *)0) */ e = me->eQueue.frontEvt; if (me->eQueue.nFree != me->eQueue.end) { /* any events in the buffer? */ /* remove event from the tail */ me->eQueue.frontEvt = me->eQueue.ring[me->eQueue.tail]; if (me->eQueue.tail == (QEQueueCtr)0) { /* need to wrap the tail? */ me->eQueue.tail = me->eQueue.end; /* wrap around */ } --me->eQueue.tail; ++me->eQueue.nFree; /* one more free event in the ring buffer */ QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET, QS_aoObj_, me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this active object */ QS_U8_(e->dynamic_); /* the dynamic attribute of the event */ QS_EQC_(me->eQueue.nFree); /* number of free entries */ QS_END_NOLOCK_() }
/*..........................................................................*/ QEvent const *QEQueue_get(QEQueue *me) { QEvent const *e; QF_INT_LOCK_KEY_ QF_INT_LOCK_(); if (me->frontEvt == (QEvent *)0) { /* is the queue empty? */ e = (QEvent const *)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 = me->ring[me->tail]; /* remove from the 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_NOLOCK_(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_(e->dynamic_); /* the dynamic attribute of the event */ QS_EQC_(me->nFree); /* number of free entries */ QS_END_NOLOCK_() } else {
/*..........................................................................*/ 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 {
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 {
/*..........................................................................*/ QEvt const *QActive_get_(QActive * const me) { QEQueueCtr nFree; QEvt const *e; QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QACTIVE_EQUEUE_WAIT_(me); /* wait for event to arrive directly */ e = me->eQueue.frontEvt; /* always remove event from the front location */ nFree= me->eQueue.nFree + (QEQueueCtr)1; /* get volatile into tmp */ me->eQueue.nFree = nFree; /* upate the number of free */ if (nFree <= me->eQueue.end) { /* any events in the ring buffer? */ /* remove event from the tail */ me->eQueue.frontEvt = QF_PTR_AT_(me->eQueue.ring, me->eQueue.tail); if (me->eQueue.tail == (QEQueueCtr)0) { /* need to wrap the tail? */ me->eQueue.tail = me->eQueue.end; /* wrap around */ } --me->eQueue.tail; QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET, QS_priv_.aoObjFilter, me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this active object */ QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_EQC_(nFree); /* number of free entries */ QS_END_NOCRIT_() }
/*..........................................................................*/ uint8_t QEQueue_post(QEQueue * const me, QEvt const * const e, uint16_t const margin) { QEQueueCtr nFree; /* temporary to avoid UB for volatile access */ uint8_t status; QF_CRIT_STAT_ Q_REQUIRE(e != (QEvt const *)0); /* event must be valid */ QF_CRIT_ENTRY_(); nFree = me->nFree; /* get volatile into the temporary */ if (nFree > (QEQueueCtr)margin) { /* required margin available? */ QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_FIFO, QS_priv_.eqObjFilter, me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this queue object */ QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_EQC_(nFree); /* number of free entries */ QS_EQC_(me->nMin); /* min number of free entries */ QS_END_NOCRIT_() if (e->poolId_ != (uint8_t)0) { /* is it a pool event? */ QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ } --nFree; /* one free entry just used up */ me->nFree = nFree; /* update the volatile */ if (me->nMin > nFree) { me->nMin = nFree; /* update minimum so far */ } if (me->frontEvt == (QEvt const *)0) { /* was the queue empty? */ me->frontEvt = e; /* deliver event directly */ } else { /* queue was not empty, insert event into the ring-buffer */ /* insert event into the ring buffer (FIFO) */ QF_PTR_AT_(me->ring, me->head) = e; /* insert e into buffer */ if (me->head == (QEQueueCtr)0) { /* need to wrap the head? */ me->head = me->end; /* wrap around */ } --me->head; } status = (uint8_t)1; /* event posted successfully */ }
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_(); }
/*..........................................................................*/ void QEQueue_postLIFO(QEQueue *me, QEvent const *e) { QF_INT_LOCK_KEY_ QF_INT_LOCK_(); QS_BEGIN_NOLOCK_(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_(e->dynamic_); /* the dynamic attribute of the event */ QS_EQC_(me->nFree); /* number of free entries */ QS_EQC_(me->nMin); /* min number of free entries */ QS_END_NOLOCK_() if (e->dynamic_ != (uint8_t)0) { /* is it a pool event? */ ++((QEvent *)e)->dynamic_; /* increment the reference counter */ /* NOTE: cast the 'const' away, which is legitimate because * it's a dynamic event */ } 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 */ } me->ring[me->tail] = me->frontEvt; /* buffer the 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_INT_UNLOCK_(); }
/*..........................................................................*/ void QEQueue_postFIFO(QEQueue *me, QEvent const *e) { QF_INT_LOCK_KEY_ QF_INT_LOCK_(); QS_BEGIN_NOLOCK_(QS_QF_EQUEUE_POST_FIFO, QS_eqObj_, me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this queue object */ QS_U8_(e->dynamic_); /* the dynamic attribute of the event */ QS_EQC_(me->nFree); /* number of free entries */ QS_EQC_(me->nMin); /* min number of free entries */ QS_END_NOLOCK_() if (e->dynamic_ != (uint8_t)0) { /* is it a pool event? */ ++((QEvent *)e)->dynamic_; /* increment the reference counter */ /* NOTE: cast the 'const' away, which is legitimate because * it's a dynamic event */ } if (me->frontEvt == (QEvent *)0) { /* is the queue empty? */ me->frontEvt = e; /* deliver event directly */ } else { /* queue is not empty, leave event in the ring-buffer */ /* the queue must be able to accept the event (cannot overflow) */ Q_ASSERT(me->nFree != (QEQueueCtr)0); me->ring[me->head] = e; /* insert event into the buffer (FIFO) */ if (me->head == (QEQueueCtr)0) { /* need to wrap the head? */ me->head = me->end; /* wrap around */ } --me->head; --me->nFree; /* update number of free events */ if (me->nMin > me->nFree) { me->nMin = me->nFree; /* update minimum so far */ } } QF_INT_UNLOCK_(); }
//**************************************************************************** //! obtain a message from the private message queue (block if no messages) void const *QXThread::queueGet(uint_fast16_t const nTicks, uint_fast8_t const tickRate) { QEQueueCtr nFree; QEvt const *e; QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr); Q_REQUIRE_ID(900, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */ /* this must be a "naked" thread (no state) */ && (thr->m_state.act == (QActionHandler)0)); // is the queue empty? -- block and wait for event(s) if (thr->m_eQueue.m_frontEvt == static_cast<QEvt *>(0)) { thr->m_temp.obj = reinterpret_cast<QMState const *>(&thr->m_eQueue); thr->teArm_(static_cast<enum_t>(QXK_QUEUE_SIG), nTicks, tickRate); QXK_attr_.readySet.remove(thr->m_prio); QXK_sched_(); QF_CRIT_EXIT_(); QF_CRIT_EXIT_NOP(); QF_CRIT_ENTRY_(); } // is the queue not empty? if (thr->m_eQueue.m_frontEvt != static_cast<QEvt *>(0)) { e = thr->m_eQueue.m_frontEvt; // always remove from the front // volatile into tmp nFree= thr->m_eQueue.m_nFree + static_cast<QEQueueCtr>(1); thr->m_eQueue.m_nFree = nFree; // update the number of free // any events in the ring buffer? if (nFree <= thr->m_eQueue.m_end) { // remove event from the tail thr->m_eQueue.m_frontEvt = QF_PTR_AT_(thr->m_eQueue.m_ring, thr->m_eQueue.m_tail); if (thr->m_eQueue.m_tail == static_cast<QEQueueCtr>(0)) { thr->m_eQueue.m_tail = thr->m_eQueue.m_end; // wrap } --thr->m_eQueue.m_tail; QS_BEGIN_NOCRIT_(QP::QS_QF_ACTIVE_GET, QP::QS::priv_.aoObjFilter, thr) QS_TIME_(); // timestamp QS_SIG_(e->sig); // the signal of this event QS_OBJ_(&thr); // this active object QS_2U8_(e->poolId_, e->refCtr_); // pool Id & ref Count QS_EQC_(nFree); // number of free entries QS_END_NOCRIT_() }
/*..........................................................................*/ 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_(); }
/*..........................................................................*/ QEvent const *QActive_get_(QActive *me) { INT8U err; QEvent const *e = (QEvent *)OSQPend((OS_EVENT *)me->eQueue, 0, &err); QS_INT_LOCK_KEY_ Q_ASSERT(err == OS_NO_ERR); QS_BEGIN_(QS_QF_ACTIVE_GET, QS_aoObj_, me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this active object */ 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_(0); /* number of free entries (unknown) */ QS_END_() return e; }
/*..........................................................................*/ void QEQueue_init(QEQueue * const me, QEvt const *qSto[], QEQueueCtr const qLen) { QS_CRIT_STAT_ me->frontEvt = (QEvt const *)0; /* no events in the queue */ me->ring = &qSto[0]; /* the beginning of the ring buffer */ me->end = qLen; me->head = (QEQueueCtr)0; me->tail = (QEQueueCtr)0; me->nFree = qLen; me->nMin = qLen; QS_BEGIN_(QS_QF_EQUEUE_INIT, QS_eqObj_, me) QS_OBJ_(qSto); /* this QEQueue object */ QS_EQC_(qLen); /* the length of the queue */ QS_END_() }
/*..........................................................................*/ QEvent const *QActive_get_(QActive *me) { QEvent const *e; QF_INT_LOCK_KEY_ QF_INT_LOCK_(); QACTIVE_OSOBJECT_WAIT_(me); /* wait for event to arrive directly */ e = me->eQueue__.frontEvt__; if (me->eQueue__.nUsed__ != (QEQueueCtr)0) {/*any events in the buffer? */ /* remove from the tail */ me->eQueue__.frontEvt__ = me->eQueue__.ring__[me->eQueue__.tail__]; ++me->eQueue__.tail__; if (me->eQueue__.tail__ == me->eQueue__.end__) { /* wrap around? */ me->eQueue__.tail__ = (QEQueueCtr)0; /* wrap the tail */ } --me->eQueue__.nUsed__; /* one less event in the ring buffer */ QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET, QS_aoObj_, me); QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this active object */ QS_U8_(e->attrQF__); /* the QF attribute of the event */ QS_EQC_(me->eQueue__.nUsed__); /* number of used entries */ QS_END_NOLOCK_(); } else { me->eQueue__.frontEvt__ = (QEvent const *)0; /* queue becomes empty */ QACTIVE_OSOBJECT_ONIDLE_(me); QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_GET_LAST, QS_aoObj_, me); QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ QS_OBJ_(me); /* this active object */ QS_U8_(e->attrQF__); /* the QF attribute of the event */ QS_END_NOLOCK_(); } QF_INT_UNLOCK_(); return e; }