Beispiel #1
0
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);
}
Beispiel #2
0
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);
}