/*..........................................................................*/ 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; }
//............................................................................ // 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_() }
/*..........................................................................*/ 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_() }
/* 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_() }
/*..........................................................................*/ 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 {
/*..........................................................................*/ 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_(); }
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_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; }
//............................................................................ 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 } }
/* 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; }
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 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_(); }
/*..........................................................................*/ 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_(); }
/*..........................................................................*/ 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 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_(); }
/*..........................................................................*/ 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_(); }
/*..........................................................................*/ 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 */ }
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 } }
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 } } }