Scheduling

Top  Previous  Next

Many tasks can be run on one CPU, and tasks themselves are made up of one or more concurrently-executing threads. The microkernel arranges for the available processor time to be shared amongst these various threads using a process known as scheduling. Each thread has an associated priority, a number in the range 0–7, that determines its importance with respect to other threads executing on the same processor; the smaller the number, the higher the priority of the thread. Threads at the highest level of priority (priority 0) are referred to as urgent threads.

 

Dragons003It is extremely rare for an application to need more than three priorities (0, 1, and 2). Profligate use of multiple priorities can reduce the efficiency of an application.

 

An executing thread can be suspended (descheduled) and another thread resumed when one of a number of events occurs:


The thread explicitly requests to be descheduled by calling thread_deschedule;

The thread has to wait for something (a channel communication, a semaphore, an event, or a timer event);

The thread is pre-empted by a more important (i.e., higher priority) thread that has become ready to execute;

The thread is timesliced, descheduled because it has been running for some timeits time slicewithout interruption. The time slice is computed from the thread’s priority: priority*100ms.

Urgent threads are of the highest priority, priority 0, and so can never be pre-empted, even by another urgent thread. Similarly, urgent threads are considered to have an infinite time slice and execute forever without being descheduled; lower priority threads, and even other urgent threads, are 'locked out' entirely. Careful use of urgent threads can dramatically improve the performance of an application; injudicious use can equally dramatically degrade performance. For this reason, you should use urgent threads with care. A general rule of thumb is that threads whose primary purpose is communication are good candidates for being urgent.

 

Once a thread is descheduled, the highest-priority thread that is ready to execute will run. Hence lower-priority threads only ever execute when all threads of a higher priority are waiting (for example, for a semaphore or a link transfer). Within any priority level except the urgent level, the microkernel divides the time amongst the threads on a round-robin basis (first come, first served).

 

Switching from one thread to another because of an interrupt (including a time-slice) is slightly more expensive than switching for any other reason.