/* * Must be called with nklock locked, interrupts off. Thread may be * blocked. */ void xnsched_migrate_passive(struct xnthread *thread, struct xnsched *sched) { migrate_thread(thread, sched); if (!xnthread_test_state(thread, XNTHREAD_BLOCK_BITS)) { xnsched_requeue(thread); xnthread_set_state(thread, XNREADY); } }
/* Must be called with nklock locked, interrupts off. */ struct xnthread *xnsched_pick_next(struct xnsched *sched) { struct xnthread *curr = sched->curr; struct xnsched_class *p; struct xnthread *thread; if (!xnthread_test_state(curr, XNTHREAD_BLOCK_BITS | XNZOMBIE)) { /* * Do not preempt the current thread if it holds the * scheduler lock. */ if (xnthread_test_state(curr, XNLOCK)) { xnsched_set_self_resched(sched); return curr; } /* * Push the current thread back to the runnable queue * of the scheduling class it belongs to, if not yet * linked to it (XNREADY tells us if it is). */ if (!xnthread_test_state(curr, XNREADY)) { xnsched_requeue(curr); xnthread_set_state(curr, XNREADY); } #ifdef __XENO_SIM__ if (nkpod->schedhook) nkpod->schedhook(curr, XNREADY); #endif /* __XENO_SIM__ */ } /* * Find the runnable thread having the highest priority among * all scheduling classes, scanned by decreasing priority. */ #ifdef CONFIG_XENO_OPT_SCHED_CLASSES for_each_xnsched_class(p) { thread = p->sched_pick(sched); if (thread) { xnthread_clear_state(thread, XNREADY); return thread; } } return NULL; /* Never executed because of the idle class. */ #else /* !CONFIG_XENO_OPT_SCHED_CLASSES */ thread = __xnsched_rt_pick(sched); (void)p; if (unlikely(thread == NULL)) thread = &sched->rootcb; xnthread_clear_state(thread, XNREADY); return thread; #endif /* CONFIG_XENO_OPT_SCHED_CLASSES */ }
/* Must be called with nklock locked, interrupts off. thread may be * blocked. */ void xnsched_migrate_passive(struct xnthread *thread, struct xnsched *sched) { struct xnsched_class *sched_class = thread->sched_class; if (xnthread_test_state(thread, XNREADY)) { xnsched_dequeue(thread); xnthread_clear_state(thread, XNREADY); } if (sched_class->sched_migrate) sched_class->sched_migrate(thread, sched); /* * WARNING: the scheduling class may have just changed as a * result of calling the per-class migration hook. */ xnsched_set_resched(thread->sched); thread->sched = sched; if (!xnthread_test_state(thread, XNTHREAD_BLOCK_BITS)) { xnsched_requeue(thread); xnthread_set_state(thread, XNREADY); } }