void scheduler_schedule(void) { TID_t t; thread_table_t *current_thread; int this_cpu; this_cpu = _interrupt_getcpu(); spinlock_acquire(&thread_table_slock); current_thread = &(thread_table[scheduler_current_thread[this_cpu]]); if(current_thread->state == THREAD_DYING) { current_thread->state = THREAD_FREE; } else if(current_thread->sleeps_on != 0) { current_thread->state = THREAD_SLEEPING; } else { if(scheduler_current_thread[this_cpu] != IDLE_THREAD_TID) scheduler_add_to_ready_list(scheduler_current_thread[this_cpu]); current_thread->state = THREAD_READY; } t = scheduler_remove_first_ready(); thread_table[t].state = THREAD_RUNNING; spinlock_release(&thread_table_slock); scheduler_current_thread[this_cpu] = t; /* Schedule timer interrupt to occur after thread timeslice is spent */ timer_set_ticks(_get_rand(CONFIG_SCHEDULER_TIMESLICE) + CONFIG_SCHEDULER_TIMESLICE / 2); }
void scheduler_schedule(void) { TID_t t; TID_t lowestDL = -1; thread_table_t *current_thread; int this_cpu; this_cpu = _interrupt_getcpu(); spinlock_acquire(&thread_table_slock); current_thread = &(thread_table[scheduler_current_thread[this_cpu]]); if(current_thread->state == THREAD_DYING) { current_thread->state = THREAD_FREE; } else if(current_thread->sleeps_on != 0) { current_thread->state = THREAD_SLEEPING; } else { if(scheduler_current_thread[this_cpu] != IDLE_THREAD_TID) scheduler_add_to_ready_list(scheduler_current_thread[this_cpu]); current_thread->state = THREAD_READY; } t = scheduler_ready_to_run.head; /* Initialize the TID lowestDL to a thread with deadline larger than 0 */ /* if possible */ while (lowestDL == -1 && t != -1) { if (thread_table[t].deadline > 0) { lowestDL = t; break; } t = thread_table[t].next; } t = scheduler_ready_to_run.head; if (lowestDL != -1) { /* If a deadline was found, find the lowest deadline */ while (t != -1) { if (thread_table[t].deadline < thread_table[lowestDL].deadline && thread_table[t].deadline > 0) { lowestDL = t; } t = thread_table[t].next; } /* Set the thread with this deadline to the head */ if (lowestDL == scheduler_ready_to_run.tail && lowestDL != scheduler_ready_to_run.head) { scheduler_ready_to_run.tail = thread_table[lowestDL].previous; thread_table[scheduler_ready_to_run.tail].next = -1; thread_table[lowestDL].next = scheduler_ready_to_run.head; thread_table[scheduler_ready_to_run.head].previous = lowestDL; thread_table[lowestDL].previous = -1; scheduler_ready_to_run.head = lowestDL; } else if (lowestDL != scheduler_ready_to_run.head) { thread_table[thread_table[lowestDL].previous].next = thread_table[lowestDL].next; thread_table[thread_table[lowestDL].next].previous = thread_table[lowestDL].previous; thread_table[lowestDL].next = scheduler_ready_to_run.head; thread_table[scheduler_ready_to_run.head].previous = lowestDL; thread_table[lowestDL].previous = -1; scheduler_ready_to_run.head = lowestDL; } } /* Remove the head and run it */ t = scheduler_remove_first_ready(); thread_table[t].state = THREAD_RUNNING; spinlock_release(&thread_table_slock); scheduler_current_thread[this_cpu] = t; /* Schedule timer interrupt to occur after thread timeslice is spent */ timer_set_ticks(_get_rand(CONFIG_SCHEDULER_TIMESLICE) + CONFIG_SCHEDULER_TIMESLICE / 2); }