next up previous contents
Next: Semaphores: Implementation Up: Thread Library Functions Previous: Thread Init Function   Contents

Schedule function

This function is one of the most important tricky functions of the whole code. This function is responsible for scheduling the next ready thread. The following is the broad description of what it does.

void schedule(void)
{

.....................
Check the Bottom Half 
.....................

 do_Context_Switch = 0;
 spin_lock(&(scheduler->sched_lock)); -------------(1)
  heir_thread=scheduler->heir_thread(curr_thread);
  if (!heir_thread) 
    {
      heir_thread=idle_thread;
    }
#ifdef DEBUG0
  assert(heir_thread->magic_key==MAGIC_KEY);
#endif
  if (heir_thread!=curr_thread)
    {
      struct tcb *out_thread=curr_thread;
      curr_thread=heir_thread;
      CPU_Context_Switch(&(out_thread->thread_context),
                         &(heir_thread->thread_context));
     }
  spin_unlock(&(scheduler->sched_lock)); ----------(2)
  do_Context_Switch=1;
}

schedule() finds the next thread to execute, by querying the scheduler object. If the next thread is not the same as the current thread, it then calls H/W dependent routine CPU_Context_Switch() for executing the context switch.

As with any other thread library function, this function also locks a variable (statement 1), and disables context switch before calling the scheduler API function hier_thread(). So when a thread is switched out of CPU it carries the lock with it. This however is not a problem if the thread which comes next onto the CPU was also switced out from the same point. That thread, when resumed, continues after the CPU_Context_Switch() function and hence unlocks the global variable at statement 2.

This is OK for all threads except for a thread which is going to execute for the first time, since then it does not start it's execution ast statement 2, but from the thread_init_function. Hence we have put a unlock and do_Context_Switch instruction at the start of thread_init_function.

void *thread_init_function(void *(*start_add)(void *),void *param)
{
  spin_unlock(&(scheduler->sched_lock));
  do_Context_Switch=1;
	  
  start_add(param);  /* Call the function from which the thread starts */
  
 ............... 
 
  
}

next up previous contents
Next: Semaphores: Implementation Up: Thread Library Functions Previous: Thread Init Function   Contents
Soumyadeb Mitra 2002-08-07