Thread Priority Scheme

Explains the factors involved in allocating thread priority.

At any given time, the thread running on Symbian platform is the one with the highest priority that is ready to run. The priority of a thread is simply a number; the value determines the priority; the greater the number, the higher the priority. We call this the true or absolute priority of the thread.

The Kernel schedules a fixed amount of time called a quantum for a thread to run on the CPU, and the scheduler chooses the highest priority thread that is ready to run. Threads of equal priority are executed on a round robin basis.

The true priority values range from 0 (lowest) to 63 (highest).

The priority range divides into four broad categories:

0

This is reserved for the null thread, which puts the processor into idle mode to save power when no other threads are ready to run.

1 - 23

Used by kernel side threads and user-side applications and servers

24 -31

Used by kernel side threads and protected system servers, i.e. servers with the ProtServ capability.

32 - 63

Reserved for real-time threads running on the kernel side.

Priority scheme for general user-side threads

User-side threads do not allocate true priority values directly. Instead, they allocate priorities using symbolic values defined by enums. Symbian platform maps these values to the true value.

There are two priority allocation schemes:

Process-relative scheme

This scheme bases the true priority of a thread on the priority of its owning process and the priority of the thread relative to the process. This means that changing the process priority results in a change to the true priority of the thread.

A process can be assigned one of eight discrete priorities represented by the individual enumerators of TProcessPriority, and range from EPriorityLow, the lowest, to EPrioritySupervisor, the highest.

In practice, user processes can only be assigned priorities that are one of the values:

  • EPriorityLow

  • EPriorityBackground

  • EPriorityForeGround

  • EPriorityHigh

There are a further four process priorities that a user process is not permitted to set: EPriorityWindowServer, EPriorityFileServer, EPriorityRealTimeServer and EPrioritySupervisor.

A process priority can be assigned:

  • when the associated .exe is built; this is done by specifying the value in the .mmp file that defines the project.

  • by calling RProcess::SetPriority() and passing one of the TProcessPriority enum values.

The priority of a thread relative to a process is assigned by calling RThread::SetPriority() and passing one of the five TThreadPriority enum values:

  • EPriorityMuchLess

  • EPriorityLess

  • EPriorityNormal

  • EPriorityMore

  • EPriorityMuchMore

The thread priority value mapping table shows the true priority of a thread based on the combination of process priority and process-relative thread priority

Process-independent scheme for general user threads

In this scheme, the true priority of a thread is independent of the priority of its owning process. Changing the priority of the underlying process has no effect on the true priority of the thread.

The priority of a thread is assigned by calling RThread::SetPriority() and passing one of the TThreadPriority enum values listed below. Note that the set of enum values splits into two logical groupings based on their equivalence to process-relative values. See the thread priority value mapping table.

Group 1

Group 2

  • EPriorityAbsoluteVeryLow

  • EPriorityAbsoluteLow

  • EPriorityAbsoluteBackground

  • EPriorityAbsoluteForeground

  • EPriorityAbsoluteHigh

  • EPriorityAbsoluteLowNormal

  • EPriorityAbsoluteBackgroundNormal

  • EPriorityAbsoluteForegroundNormal

  • EPriorityAbsoluteHighNormal

The thread priority value mapping table shows the resulting true priority of the thread.

Priority scheme for real-time user-side threads

This scheme is the same as the process-independent scheme for general user threads, but with one essential difference - the range of TThreadPriority enum values to be passed to RThread::SetPriority() is as shown below. These priorities map to the true priority values in the range 24 -31, and can only be set by executables having the ProtServ capability. This range is referred to as the real time range.

  • EPriorityAbsoluteRealTime1

  • EPriorityAbsoluteRealTime2

  • EPriorityAbsoluteRealTime3

  • EPriorityAbsoluteRealTime4

  • EPriorityAbsoluteRealTime5

  • EPriorityAbsoluteRealTime6

  • EPriorityAbsoluteRealTime7

  • EPriorityAbsoluteRealTime8

The thread priority value mapping table shows the resulting true priority of the thread.

Thread priority value mapping table

This table shows the effect of setting priorities, and the resulting true priority values. You need to be aware that this may change in the future, and you should never synchronise threads on the basis of thread priorities. If you need to synchronise threads, use mutexes or semaphores.

Notes

  • True priority values in the shaded region can only be accessed by threads running in processes with the ProtServ capability.

  • The process-priority values : EPriorityWindowServer, EPriorityFileServer and EPrioritySupervisor all map to the same range of priorities. Along with EPriorityRealTimeServer, these have historically been used for system servers and other processes needing access to high priorities suitable for real-time tasks, and their use requires ProtServ capability.

  • Note that ProtServ capability will not be granted to general applications for the purpose of gaining access to the very high thread priorities. This risks breaking important system functionality.

Note that we have used E' as an abbreviation for EPriority in this diagram.

Platform security notes

Platform security restrictions prevent thread and process priorities from being modified by another user process. There is one exception: by default, applications have “Priority Control” enabled for them which allows the window server to switch them between foreground and background process priorities depending on which has foreground focus.