/*..........................................................................*/ void QF_run(void) { uint8_t p; QActive *a; QEvent const *e; QF_INT_LOCK_KEY_ QF_onStartup(); /* startup callback */ for (;;) { /* the background loop */ QF_INT_LOCK_(); #if (QF_MAX_ACTIVE <= 8) if (QPSet8_notEmpty(&QF_readySet_)) { QPSet8_findMax(&QF_readySet_, p); #else if (QPSet64_notEmpty(&QF_readySet_)) { QPSet64_findMax(&QF_readySet_, p); #endif a = QF_active_[p]; QF_INT_UNLOCK_(); e = QActive_get_(a); /* get the next event for this AO */ QF_ACTIVE_DISPATCH_(&a->super, e); /* dispatch to the AO */ QF_gc(e); /* determine if event is garbage and collect it if so */ } else { #ifndef QF_INT_KEY_TYPE QF_onIdle(); /* see NOTE01 */ #else QF_onIdle(intLockKey_); /* see NOTE01 */ #endif /* QF_INT_KEY_TYPE */ } } } /*..........................................................................*/ void QActive_start(QActive *me, uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvent const *ie) { Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE) && (stkSto == (void *)0)); /* does not need per-actor stack */ (void)stkSize; /* avoid the "unused parameter" compiler warning */ QEQueue_init(&me->eQueue, qSto, (QEQueueCtr)qLen);/* initialize QEQueue */ me->prio = prio; /* set the QF priority of this active object */ QF_add_(me); /* make QF aware of this active object */ QF_ACTIVE_INIT_(&me->super, ie); /* execute initial transition */ QS_FLUSH(); /* flush the trace buffer to the host */ }
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 } } }