Scheduling

Top  Previous  Next

The Diamond model for scheduling threads and tasks was outlined earlier. Here we shall go into a little more detail.

 

Scheduling is done by the microkernel based on the priority of the tasks in the application. There are eight levels of priority, numbered 0–7, level 0 being the highest priority and level 7 the lowest. Level 0 is referred to as urgent. The header thread.h defines the literals THREAD_URGENT and THREAD_NOTURG that correspond to priority levels 0 and 1 respectively. Unless otherwise specified, tasks and threads start at priority 1.

 

Once a thread is running, it is only suspended for one of the following reasons:

1.

It calls thread_deschedule, which voluntarily interrupts execution.

2.

It has to wait for some event external to the thread. This could be, for example:


waiting for input or output to end, whether via a channel or a link;

waiting for a semaphore to be signalled;

waiting for an event to be signalled or pulsed;

waiting for a timer event;

waiting for an alt_wait call to complete.

3.

It is pre-empted, that is, it is paused by the microkernel so that a higher priority thread which is now ready to execute can be started instead.

4.

It has used up its time-slice, that is, it has been executing without interruption for a certain length of time.

Urgent threads are only suspended for the first two of these reasons; they are never pre-empted or time-sliced.

 

Once a thread has been suspended, the highest-priority thread that is waiting to run is started. If a thread uses up its time-slice, another thread of the same priority is given a turn, if one is available, so that the time is shared evenly between threads of the same priority; if none is available, the time-sliced thread continues to run.

 

If there are no threads ready to be run at all, the idle thread runs. This executes the processor's IDLE instruction and waits for an interrupt.

 

When you create a new thread using one of the functions in this section, you have to specify the priority at which the thread is to run. You should resist the temptation to create every thread with URGENT priority, as urgent threads cannot be pre-empted or time-sliced. Once started, an urgent thread runs until it voluntarily deschedules itself or has to wait for an external service. This means that all other threads, including all other urgent threads, are prevented from executing at all. These 'locked out' threads may include parts of the communication software, and this could have a bad effect on the performance of the application as a whole.