Example #1
0
/*..........................................................................*/
void QF_tick(void) {                                          /* see NOTE01 */
    QTimeEvt *t;
    QF_INT_LOCK_KEY_

    QF_INT_LOCK_();

    QS_BEGIN_NOLOCK_(QS_QF_TICK, (void *)0, (void *)0)
        QS_TEC_(++QS_tickCtr_);                         /* the tick counter */
    QS_END_NOLOCK_()

    t = QF_timeEvtListHead_;
    while (t != (QTimeEvt *)0) {
        if (--t->ctr == (QTimeEvtCtr)0) {   /* is time evt about to expire? */
            if (t->interval != (QTimeEvtCtr)0) { /* is it periodic timeout? */
                t->ctr = t->interval;               /* rearm the time event */
            }
            else { /* one-shot timeout, disarm by removing it from the list */
                if (t == QF_timeEvtListHead_) {
                    QF_timeEvtListHead_ = t->next;
                }
                else {
                    if (t->next != (QTimeEvt *)0) {  /* not the last event? */
                        t->next->prev = t->prev;
                    }
                    t->prev->next = t->next;
                }
                t->prev = (QTimeEvt *)0;         /* mark the event disarmed */

                QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_AUTO_DISARM, QS_teObj_, t)
                    QS_OBJ_(t);                   /* this time event object */
                    QS_OBJ_(t->act);                   /* the active object */
                QS_END_NOLOCK_()
            }

            QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_POST, QS_teObj_, t)
                QS_TIME_();                                    /* timestamp */
                QS_OBJ_(t);                        /* the time event object */
                QS_SIG_(t->super.sig);         /* signal of this time event */
                QS_OBJ_(t->act);                       /* the active object */
            QS_END_NOLOCK_()

            QF_INT_UNLOCK_();/* unlock interrupts before calling QF service */

               /* postFIFO() asserts internally that the event was accepted */
            QActive_postFIFO(t->act, (QEvent *)t);
        }
        else {
            static uint8_t volatile dummy;
            QF_INT_UNLOCK_();
            dummy = (uint8_t)0;   /* execute a few instructions, see NOTE02 */
        }

        QF_INT_LOCK_();        /* lock interrupts again to advance the link */
        t = t->next;
    }
Example #2
0
//............................................................................
// NOTE: disarm a time evt (no harm in disarming an already disarmed time evt)
uint8_t QTimeEvt::disarm(void) {
    uint8_t wasArmed;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();
    if (m_prev != (QTimeEvt *)0) {        // is the time event actually armed?
        wasArmed = (uint8_t)1;
        if (this == QF_timeEvtListHead_) {
            QF_timeEvtListHead_ = m_next;
        }
        else {
            if (m_next != (QTimeEvt *)0) {        // not the last in the list?
                m_next->m_prev = m_prev;
            }
            m_prev->m_next = m_next;
        }
        m_prev = (QTimeEvt *)0;             // mark the time event as disarmed

        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM, QS::teObj_, this)
            QS_TIME_();                                           // timestamp
            QS_OBJ_(this);                           // this time event object
            QS_OBJ_(m_act);                               // the active object
            QS_TEC_(m_ctr);                             // the number of ticks
            QS_TEC_(m_interval);                               // the interval
        QS_END_NOLOCK_()
    }
Example #3
0
/*..........................................................................*/
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_()
    }
Example #4
0
/* NOTE: disarm a timer (no harm in disarming an already disarmed timer)    */
uint8_t QTimeEvt_disarm(QTimeEvt *me) {
    uint8_t wasArmed;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();
    if (me->prev != (QTimeEvt *)0) {   /* is the time event actually armed? */
        wasArmed = (uint8_t)1;
        if (me == QF_timeEvtListHead_) {
            QF_timeEvtListHead_ = me->next;
        }
        else {
            if (me->next != (QTimeEvt *)0) {   /* not the last in the list? */
                me->next->prev = me->prev;
            }
            me->prev->next = me->next;
        }
        me->prev = (QTimeEvt *)0;        /* mark the time event as disarmed */

        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM, 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_END_NOLOCK_()
    }
Example #5
0
/*..........................................................................*/
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 {
Example #6
0
/*..........................................................................*/
void QTimeEvt_arm_(QTimeEvt *me, QActive *act, QTimeEvtCtr nTicks) {
    QF_INT_LOCK_KEY_
    Q_REQUIRE((nTicks > (QTimeEvtCtr)0)  /* cannot arm a timer with 0 ticks */
              && (((QEvent *)me)->sig >= (QSignal)Q_USER_SIG)/*valid signal */
              && (me->prev == (QTimeEvt *)0)   /* time evt must NOT be used */
              && (act != (QActive *)0));  /* active object must be provided */
    me->ctr = nTicks;
    me->prev = me;                                 /* mark the timer in use */
    me->act = act;

    QF_INT_LOCK_();

    QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_ARM, QS_teObj_, me)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(me);                              /* this time event object */
        QS_OBJ_(act);                                  /* the active object */
        QS_TEC_(nTicks);                             /* the number of ticks */
        QS_TEC_(me->interval);                              /* the interval */
    QS_END_NOLOCK_()

    me->next = QF_timeEvtListHead_;
    if (QF_timeEvtListHead_ != (QTimeEvt *)0) {
        QF_timeEvtListHead_->prev = me;
    }
    QF_timeEvtListHead_ = me;
    QF_INT_UNLOCK_();
}
Example #7
0
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);
}
Example #8
0
/*..........................................................................*/
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;
}
Example #9
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
        }
    }
Example #10
0
/* NOTE: disarm a timer (no harm in disarming an already disarmed timer)    */
uint8_t QTimeEvt_disarm(QTimeEvt *me) {
    uint8_t wasArmed;
    QF_INT_LOCK_KEY_
    QF_INT_LOCK_();
    if (me->prev__ != (QTimeEvt *)0) { /* is the time event actually armed? */
        wasArmed = (uint8_t)1;
        if (me == QF_timeEvtListHead_) {
            QF_timeEvtListHead_ = me->next__;
        }
        else {
            if (me->next__ != (QTimeEvt *)0) { /* not the last in the list? */
                me->next__->prev__ = me->prev__;
            }
            me->prev__->next__ = me->next__;
        }
        me->prev__ = (QTimeEvt *)0;      /* mark the time event as disarmed */

        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM, 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_END_NOLOCK_();
    }
    else {                                  /* the time event was not armed */
        wasArmed = (uint8_t)0;

        QS_BEGIN_NOLOCK_(QS_QF_TIMEEVT_DISARM_ATTEMPT, QS_teObj_, me);
            QS_TIME_();                                        /* timestamp */
            QS_OBJ_(me);                          /* this time event object */
            QS_OBJ_(me->act__);                        /* the active object */
        QS_END_NOLOCK_();
    }
    QF_INT_UNLOCK_();
    return wasArmed;
}
Example #11
0
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_();
}
Example #12
0
/*..........................................................................*/
void QF_add_(QActive *a) {
    uint8_t p = a->prio;
    QF_INT_LOCK_KEY_

    Q_REQUIRE(((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
              && (QF_active_[p] == (QActive *)0));

    QF_INT_LOCK_();

    QF_active_[p] = a;      /* registger the active object at this priority */

    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_ADD, QS_aoObj_, a)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(a);                                    /* the active object */
        QS_U8_(p);                     /* the priority of the active object */
    QS_END_NOLOCK_()

    QF_INT_UNLOCK_();
}
Example #13
0
/*..........................................................................*/
void QF_remove_(QActive const *a) {
    uint8_t p = a->prio;
    QF_INT_LOCK_KEY_

    Q_REQUIRE(((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
              && (QF_active_[p] == a));

    QF_INT_LOCK_();

    QF_active_[p] = (QActive *)0;             /* free-up the priority level */

    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_REMOVE, QS_aoObj_, a)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(a);                                    /* the active object */
        QS_U8_(p);                     /* the priority of the active object */
    QS_END_NOLOCK_()

    QF_INT_UNLOCK_();
}
Example #14
0
/*..........................................................................*/
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_();
}
Example #15
0
/*..........................................................................*/
void QActive_subscribe(QActive const *me, QSignal sig) {
    uint8_t p = me->prio;
    uint8_t i = Q_ROM_BYTE(QF_div8Lkup[p]);
    QF_INT_LOCK_KEY_

    Q_REQUIRE(((QSignal)Q_USER_SIG <= sig)
              && (sig < QF_maxSignal_)
              && ((uint8_t)0 < p) && (p <= (uint8_t)QF_MAX_ACTIVE)
              && (QF_active_[p] == me));

    QF_INT_LOCK_();

    QS_BEGIN_NOLOCK_(QS_QF_ACTIVE_SUBSCRIBE, QS_aoObj_, me)
        QS_TIME_();                                            /* timestamp */
        QS_SIG_(sig);                           /* the signal of this event */
        QS_OBJ_(me);                                  /* this active object */
    QS_END_NOLOCK_()
                                                    /* set the priority bit */
    QF_subscrList_[sig].bits[i] |= Q_ROM_BYTE(QF_pwr2Lkup[p]);
    QF_INT_UNLOCK_();
}
Example #16
0
/*..........................................................................*/
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_();
}
Example #17
0
/*..........................................................................*/
void *QMPool_get(QMPool *me) {
    QFreeBlock *fb;
    QF_INT_LOCK_KEY_

    QF_INT_LOCK_();
    fb = (QFreeBlock *)me->free;                /* get a free block or NULL */
    if (fb != (QFreeBlock *)0) {                   /* free block available? */
        me->free = fb->next;     /* adjust list head to the next free block */
        --me->nFree;                                 /* one less free block */
        if (me->nMin > me->nFree) {
            me->nMin = me->nFree;            /* remember the minimum so far */
        }
    }

    QS_BEGIN_NOLOCK_(QS_QF_MPOOL_GET, QS_mpObj_, me->start)
        QS_TIME_();                                            /* timestamp */
        QS_OBJ_(me->start);              /* the memory managed by this pool */
        QS_MPC_(me->nFree);        /* the number of free blocks in the pool */
        QS_MPC_(me->nMin);    /* min number of free blocks ever in the pool */
    QS_END_NOLOCK_()

    QF_INT_UNLOCK_();
    return fb;            /* return the block or NULL pointer to the caller */
}
Example #18
0
void QK_scheduleExt_(void) {
#else
void QK_scheduleExt_(QF_INT_KEY_TYPE intLockKey_) {
#endif
                         // the QK scheduler must be called at task level only
    Q_REQUIRE(QK_intNest_ == (uint8_t)0);

           // determine the priority of the highest-priority task ready to run
    uint8_t p = QK_readySet_.findMax();

#ifdef QK_NO_MUTEX
    if (p > QK_currPrio_) {                        // do we have a preemption?
#else                                   // QK priority-ceiling mutexes allowed
    if ((p > QK_currPrio_) && (p > QK_ceilingPrio_)) {
#endif
        uint8_t pin = QK_currPrio_;               // save the initial priority
        QActive *a;
#ifdef QK_TLS                                    // thread-local storage used?
        uint8_t pprev = pin;
#endif
#ifdef QK_EXT_SAVE                            // extended context-switch used?
        if (pin != (uint8_t)0) {      // no extended context for the idle loop
            a = QF::active_[pin];           // the pointer to the preempted AO
            QK_EXT_SAVE(a);                       // save the extended context
        }
#endif
        do {
            QEvent const *e;
            a = QF::active_[p];                // obtain the pointer to the AO
            QK_currPrio_ = p;        // this becomes the current task priority

#ifdef QK_TLS                                    // thread-local storage used?
            if (p != pprev) {                      // are we changing threads?
                QK_TLS(a);                  // switch new thread-local storage
                pprev = p;
            }
#endif
            QS_BEGIN_NOLOCK_(QS_QK_SCHEDULE, QS::aoObj_, a)
                QS_TIME_();                                       // timestamp
                QS_U8_(p);                // the priority of the active object
                QS_U8_(pin);                         // the preempted priority
            QS_END_NOLOCK_()

            QK_INT_UNLOCK_();                         // unlock the interrupts

            e = a->get_();        // get the next event for this active object
            a->dispatch(e);                 // dispatch e to the active object
            QF::gc(e);              // garbage collect the event, if necessary

            QK_INT_LOCK_();
                             // determine the highest-priority AO ready to run
            p = QK_readySet_.findMax();

#ifdef QK_NO_MUTEX
        } while (p > pin);         // is the new priority higher than initial?
#else                                   // QK priority-ceiling mutexes allowed
        } while ((p > pin) && (p > QK_ceilingPrio_));
#endif
        QK_currPrio_ = pin;                    // restore the initial priority

#if defined(QK_TLS) || defined(QK_EXT_RESTORE)
        if (pin != (uint8_t)0) {      // no extended context for the idle loop
            a = QF::active_[pin];           // the pointer to the preempted AO
    #ifdef QK_TLS                                // thread-local storage used?
            QK_TLS(a);                             // restore the original TLS
    #endif
    #ifdef QK_EXT_RESTORE                     // extended context-switch used?
            QK_EXT_RESTORE(a);                 // restore the extended context
    #endif
        }
#endif
    }
}
Example #19
0
void QK_schedule_(void) {
#else
void QK_schedule_(QF_INT_KEY_TYPE intLockKey_) {
#endif
    uint8_t p;
                      /* the QK scheduler must be called at task level only */
    Q_REQUIRE(QK_intNest_ == (uint8_t)0);

#if (QF_MAX_ACTIVE <= 8)
    if (QPSet8_notEmpty(&QK_readySet_)) {
        /* determine the priority of the highest-priority task ready to run */
        QPSet8_findMax(&QK_readySet_, p);
#else
    if (QPSet64_notEmpty(&QK_readySet_)) {
        /* determine the priority of the highest-priority task ready to run */
        QPSet64_findMax(&QK_readySet_, p);
#endif

#ifdef QK_NO_MUTEX
        if (p > QK_currPrio_) {                 /* do we have a preemption? */
#else                                /* QK priority-ceiling mutexes allowed */
        if ((p > QK_currPrio_) && (p > QK_ceilingPrio_)) {
#endif
            uint8_t pin = QK_currPrio_;        /* save the initial priority */
            QActive *a;
#ifdef QK_TLS                                 /* thread-local storage used? */
            uint8_t pprev = pin;
#endif
            do {
                QEvent const *e;
                a = QF_active_[p];          /* obtain the pointer to the AO */

                QK_currPrio_ = p; /* this becomes the current task priority */

#ifdef QK_TLS                                 /* thread-local storage used? */
                if (p != pprev) {               /* are we changing threads? */
                    QK_TLS(a);           /* switch new thread-local storage */
                    pprev = p;
                }
#endif
                QS_BEGIN_NOLOCK_(QS_QK_SCHEDULE, QS_aoObj_, a)
                    QS_TIME_();                                /* timestamp */
                    QS_U8_(p);                    /* the priority of the AO */
                    QS_U8_(pin);                  /* the preempted priority */
                QS_END_NOLOCK_()

                QK_INT_UNLOCK_();                  /* unlock the interrupts */

                e = QActive_get_(a);      /* get the next event for this AO */
                QF_ACTIVE_DISPATCH_(&a->super, e);    /* dispatch to the AO */
                QF_gc(e);        /* garbage collect the event, if necessary */

                QK_INT_LOCK_();
                          /* determine the highest-priority AO ready to run */
#if (QF_MAX_ACTIVE <= 8)
                if (QPSet8_notEmpty(&QK_readySet_)) {
                    QPSet8_findMax(&QK_readySet_, p);
#else
                if (QPSet64_notEmpty(&QK_readySet_)) {
                    QPSet64_findMax(&QK_readySet_, p);
#endif
                }
                else {
                    p = (uint8_t)0;
                }
#ifdef QK_NO_MUTEX
            } while (p > pin);  /* is the new priority higher than initial? */
#else                                /* QK priority-ceiling mutexes allowed */
            } while ((p > pin) && (p > QK_ceilingPrio_));
#endif
            QK_currPrio_ = pin;             /* restore the initial priority */

#ifdef QK_TLS                                 /* thread-local storage used? */
            if (pin != (uint8_t)0) {/*no extended context for the idle loop */
                a = QF_active_[pin];     /* the pointer to the preempted AO */
                QK_TLS(a);                      /* restore the original TLS */
            }
#endif
        }
    }
}