/* Must be called with nklock locked, interrupts off. */ void xnsched_track_policy(struct xnthread *thread, struct xnthread *target) { union xnsched_policy_param param; if (xnthread_test_state(thread, XNREADY)) xnsched_dequeue(thread); /* * Self-targeting means to reset the scheduling policy and * parameters to the base ones. Otherwise, make thread inherit * the scheduling data from target. */ if (target == thread) { thread->sched_class = thread->base_class; xnsched_trackprio(thread, NULL); } else { xnsched_getparam(target, ¶m); thread->sched_class = target->sched_class; xnsched_trackprio(thread, ¶m); } if (xnthread_test_state(thread, XNREADY)) xnsched_enqueue(thread); xnsched_set_resched(thread->sched); }
/* Must be called with nklock locked, interrupts off. */ void xnsched_putback(struct xnthread *thread) { if (xnthread_test_state(thread, XNREADY)) xnsched_dequeue(thread); else xnthread_set_state(thread, XNREADY); xnsched_enqueue(thread); xnsched_set_resched(thread->sched); }
/* Must be called with nklock locked, interrupts off. */ int xnsched_set_policy(struct xnthread *thread, struct xnsched_class *sched_class, const union xnsched_policy_param *p) { int ret; /* * Declaring a thread to a new scheduling class may fail, so * we do that early, while the thread is still a member of the * previous class. However, this also means that the * declaration callback shall not do anything that might * affect the previous class (such as touching thread->rlink * for instance). */ if (sched_class != thread->base_class) { if (sched_class->sched_declare) { ret = sched_class->sched_declare(thread, p); if (ret) return ret; } sched_class->nthreads++; } /* * As a special case, we may be called from xnthread_init() * with no previous scheduling class at all. */ if (likely(thread->base_class != NULL)) { if (xnthread_test_state(thread, XNREADY)) xnsched_dequeue(thread); if (sched_class != thread->base_class) xnsched_forget(thread); } thread->sched_class = sched_class; thread->base_class = sched_class; xnsched_setparam(thread, p); thread->bprio = thread->cprio; if (xnthread_test_state(thread, XNREADY)) xnsched_enqueue(thread); if (xnthread_test_state(thread, XNSTARTED)) xnsched_set_resched(thread->sched); return 0; }