void sched_yield() { thread_t * thr = thr_current(); thr->state = Yielded; sysc_call(SysSchedule, 0, 0); return; }
void sched_schedule() { // find a thread to schedule. the scheduled thread is removed from the // queue, and the currently-run thread is re-added to the queue. spl_lock(&_sched_lock); thread_t* old = thr_current(); if(old) { switch(old->state) { case Runnable: // don't stop if the thread still has time! if(old->preempt_at > systime()) { goto done; } break; case Yielded: // timeslice is given up. old->state = Runnable; break; default: // not relevant here. break; } } // BUG: this algorithm will start to choose the idle thread when // only one other thread is remaining runnable. thread_t* thr = sched_choose(old); if(thr) { trace("switching: %d:%d (%d)\n", thr->parent->id, thr->id, thr->priority); thr->preempt_at = systime() + SCHED_TIMESLICE_US; thr_switch(thr); sched_remove_unlocked(thr); if(old) sched_add_unlocked(old); goto done; } // let things stay as they are if only one thread exists. if(old->state == Runnable) { goto done; } fatal("no thread left to schedule - this is bad!\n"); done: spl_unlock(&_sched_lock); }
void sched_yield() { thread_t * thr = thr_current(); thr->state = Yielded; sched_schedule(); }