Scheduling Priority
Thread priority is the key factor considered by most scheduling policies when choosing the next thread to execute on a processor. Priority values define a numerical rank or ordering of the threads that a thread scheduler can use to resolve simultaneous contention for processing resources.
In a typical implementation, any threads in the runnable state are represented in an ordered list of queues with one list entry, or queue, per priority level. This is demonstrated in Figure 19.
Figure 19 – Queues and priorities
Range of priority values. In the Threading package, threads with numerically higher priority values receive scheduling preference over threads with lower priorities. The legal range for priority values tends to vary significantly between thread APIs, different contention scopes, and different scheduling policies.
Using the feature test macro. The feature test macro for scheduling priority is RW_THR_HAS_PRIORITY. If this macro is not defined, attempts to query or set a priority attribute always produce an exception. If it is defined, then the current environment has some level of support or recognition for scheduling priorities and might allow you to get or set a scheduling priority attribute.
The macro RW_THR_HAS_DUAL_PRIORITY indicates whether the current environment requires two separate priority values for threads with system contention scope:
*One for resolving contention for thread-level synchronization objects within a process.
*One for scheduling the thread relative to other threads in the system.
RW_THR_HAS_DUAL_PRIORITY can be used to choose between use of the single priority attribute functions and the process-scope and system-scope priority functions. If this macro is defined, then:
*The macro RW_THR_HAS_PROCESS_SCOPE_PRIORITY is defined.
*The macro RW_THR_HAS_SYSTEM_SCOPE_PRIORITY is defined.
Typedef for all priority values. The typedef RWPriority is the type for all priority values in the Threading package. The declaration of this typedef varies from one environment to the next, but is always based on one of the intrinsic integer types.
Member functions. The RWThreadAttribute member functions that manipulate the scheduling priority attribute value include:
*canGetPriority() — Indicates whether the scheduling priority attribute is supported in the current environment and whether getPriority() can currently return a legal value.
*isPrioritySet() — Indicates whether the scheduling policy attribute value is the value that was previously set by a call to setPriority(RWPriority).
*getPriority() — Returns the default scheduling priority value if the attribute value has not yet been defined. Otherwise, it returns the value specified in the last call to setPriority(RWPriority). If the current environment or circumstances do not support priority scheduling, then attempts to use this function result in exceptions.
*canSetPriority() — Indicates whether the scheduling priority attribute is supported and can be set in the current environment.
*setPriority(RWPriority) — Sets the scheduling priority attribute to the value passed as an argument. If the current environment does not support the scheduling priority attribute or the specified attribute value is outside the legal range, then the function produces an exception.
*resetPriority() — Restores the scheduling priority attribute to its default value. The default value can vary according to the current value of other attributes.
*getMinPriority() — Returns the minimum priority value supported by the current contention scope and scheduling policy.
*getMaxPriority() — Returns the maximum priority value supported by the current contention scope and scheduling policy.
Requirement for two priority values. Some platforms, such as Solaris, require the use of two separate priority values for threads with system contention scope;
*One sets the system-level scheduling priority or system-scope priority for the thread.
*The other is a process-scope priority used to control access to any thread-level synchronization resources shared with other threads in the same process.
Requirement for a separate process-scope priority. You should only need to define a separate process-scope priority for a system-scope thread when:
*You have used more than one priority value for your process-scope threads.
*The possibility exists that your system-scope thread can deadlock as a result of priority inversion. Priority inversion occurs because a thread has assumed an inappropriate default process-scope priority value.
Support for two priorities. To support this dual priority scheme, the RWThreadAttribute class includes two sets of functions that are specialized versions of the normal priority function listed above. These functions should only be required when defining attributes for threads that have system contention scope.
*The first set defines a thread priority for use in resolving multithread contention for intra-process synchronization resources. These functions can be used interchangeably with the normal priority functions, as long as the thread attribute instance defines the contention scope as RW_THR_PROCESS_SCOPE or when the environment supports or requires dual-priorities for system-scope threads.
*canGetProcessScopePriority()
*isProcessScopePrioritySet()
*getProcessScopePriority()
*canSetProcessScopePriority()
*setProcessScopePriority()
*resetProcessScopePriority()
*getMinProcessScopePriority()
*getMaxProcessScopePriority()
*The second set of functions defines a thread priority for use in scheduling system-scope threads relative to other system-scope threads in the system. These functions can be used interchangeably with the normal priority functions, as long as the thread attribute instance defines the contention scope as RW_THR_SYSTEM_SCOPE:
*canGetSystemScopePriority()
*isSystemScopePrioritySet()
*getSystemScopePriority()
*canSetSystemScopePriority()
*setSystemScopePriority()
*resetSystemScopePriority()
*getMinSystemScopePriority()
*getMaxSystemScopePriority()
Changing the inheritance or scheduling policy attributes. Changing the inheritance or scheduling policy attributes, either directly or as the result of a change in contention scope, can cause a previous priority setting to be discarded and can affect the range of allowable priority values, in accordance with the following table:
Inheritance Policy
Scheduling Policy
Priority
Inherit
[Inherited]
[Inherited]
Explicit
Preemptive(if available)
Policy-Dependent Range
Fixed Time-Slicing(if available)
Policy-Dependent Range
Dynamic Time-Slicing(if available)
Policy-Dependent Range
Availability of the process-scope priority attributes. The availability of the process-scope priority attributes might be affected by the current setting of the contention scope attribute, as shown in the next table.
Contention Scope
Requires Dual Priorities
Inheritance Policy
Scheduling Policy
Process-Scope Priority
Process Scope(if available)
N/A
Inherit
[Inherited]
[Inherited]
Explicit
Preemptive (if available)
Policy-Dependent Range
Fixed Time-Slicing (if available)
Policy-Dependent Range
Dynamic Time-Slicing (if available)
Policy-Dependent Range
System Scope(if available)
No
N/A
N/A
Not Available
Yes
Inherit
[Inherited]
[Inherited]
Explicit
N/A
System-Dependent Range
Availability of the system-scope priority attributes. The availability of the system-scope priority attributes might be affected by the current setting of the contention scope attribute, as shown in the next table.
Contention Scope
Inheritance Policy
Scheduling Policy
System-Scope Priority
Process Scope(if available)
N/A
N/A
Not Available
System-Scope(if available)
Inherit
[Inherited]
[Inherited]
Explicit
Preemptive (if available)
Policy-Dependent Range
Fixed Time-Slicing (if available)
Policy-Dependent Range
Dynamic Time-Slicing (if available)
Policy-Dependent Range
NOTE: The specific dependencies and validation requirements for the priority attributes are unique to each environment.
Inheriting a priority value. A priority value can be inherited from the creating thread if the inheritance policy attribute is defined as RW_THR_INHERIT. If the inheritance attribute is RW_THR_EXPLICIT, the Threading package chooses a default value appropriate for the current settings and environment. Setting a priority attribute value when the current inheritance policy is RW_THR_INHERIT forces the inheritance policy attribute to be changed to RW_THR_EXPLICIT.
Using a priority value. The priority specified by an RWThreadAttribute can only be used at thread creation. To manipulate the priority value of an active thread, use the following RWThread and RWThreadSelf functions:
*canGetPriority()
*getPriority()
*canSetPriority()
*setPriority(RWPriority)
*getMinPriority()
*getMaxPriority()
*canGetProcessScopePriority()
*getProcessScopePriority()
*canSetProcessScopePriority()
*setProcessScopePriority()
*getMinProcessScopePriority()
*getMaxProcessScopePriority()
*canGetSystemScopePriority()
*getSystemScopePriority()
*canSetSystemScopePriority()
*setSystemScopePriority()
*getMinSystemScopePriority()
*getMaxSystemScopePriority()
Exceptions. In addition to throwing the same exceptions as their RWThreadAttribute counterparts, an RWTHRThreadNotActive exception is thrown should you attempt to query or set the priority on a threaded runnable that does not possess an active thread.