Exemple #1
0
//****************************************************************************
//! 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_()
        }
Exemple #2
0
void QF_tickX_(uint_fast8_t const tickRate, void const * const sender)
#endif
{
    QTimeEvt *prev = &QF_timeEvtHead_[tickRate];
    QF_CRIT_STAT_

    QF_CRIT_ENTRY_();

    QS_BEGIN_NOCRIT_(QS_QF_TICK, (void *)0, (void *)0)
        QS_TEC_((QTimeEvtCtr)(++prev->ctr)); /* tick ctr */
        QS_U8_((uint8_t)tickRate);           /* tick rate */
    QS_END_NOCRIT_()

    /* scan the linked-list of time events at this rate... */
    for (;;) {
        QTimeEvt *t = prev->next;  /* advance down the time evt. list */

        /* end of the list? */
        if (t == (QTimeEvt *)0) {

            /* any new time events armed since the last run of QF_tickX_()? */
            if (QF_timeEvtHead_[tickRate].act != (void *)0) {

                /* sanity check */
                Q_ASSERT_ID(110, prev != (QTimeEvt *)0);
                prev->next = (QTimeEvt *)QF_timeEvtHead_[tickRate].act;
                QF_timeEvtHead_[tickRate].act = (void *)0;
                t = prev->next;  /* switch to the new list */
            }
            else {
                break; /* all currently armed time evts. processed */
            }
        }

        /* time event scheduled for removal? */
        if (t->ctr == (QTimeEvtCtr)0) {
            prev->next = t->next;
            t->super.refCtr_ &= (uint8_t)0x7F; /* mark as unlinked */
            /* do NOT advance the prev pointer */
            QF_CRIT_EXIT_(); /* exit crit. section to reduce latency */

            /* prevent merging critical sections, see NOTE1 below  */
            QF_CRIT_EXIT_NOP();
        }
        else {
            --t->ctr;

            /* is time event about to expire? */
            if (t->ctr == (QTimeEvtCtr)0) {
                QMActive *act = (QMActive *)t->act; /* temp. for volatile */

                /* periodic time evt? */
                if (t->interval != (QTimeEvtCtr)0) {
                    t->ctr = t->interval; /* rearm the time event */
                    prev = t; /* advance to this time event */
                }
                /* one-shot time event: automatically disarm */
                else {
                    prev->next = t->next;
                    t->super.refCtr_ &= (uint8_t)0x7F; /* mark as unlinked */
                    /* do NOT advance the prev pointer */

                    QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_AUTO_DISARM,
                                     QS_priv_.teObjFilter, t)
                        QS_OBJ_(t);            /* this time event object */
                        QS_OBJ_(act);          /* the target AO */
                        QS_U8_((uint8_t)tickRate); /* tick rate */
                    QS_END_NOCRIT_()
                }

                QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_POST, QS_priv_.teObjFilter, t)
                    QS_TIME_();                /* timestamp */
                    QS_OBJ_(t);                /* the time event object */
                    QS_SIG_(t->super.sig);     /* signal of this time event */
                    QS_OBJ_(act);              /* the target AO */
                    QS_U8_((uint8_t)tickRate); /* tick rate */
                QS_END_NOCRIT_()

                QF_CRIT_EXIT_(); /* exit critical section before posting */

                /* QACTIVE_POST() asserts internally if the queue overflows */
                QACTIVE_POST(act, &t->super, sender);
            }
            else {
                prev = t;         /* advance to this time event */
                QF_CRIT_EXIT_();  /* exit crit. section to reduce latency */

                /* prevent merging critical sections, see NOTE1 below  */
                QF_CRIT_EXIT_NOP();
            }
        }