Threads Module User's Guide : PART II Concurrency Packages : Chapter 3 The Threading Package : Thread Attributes : Scheduling Attributes
Scheduling Attributes
The scheduling attributes are used to control the allocation of processing and synchronization among the various competing threads in an application or system.
The availability and allowable range for a particular scheduling attribute can vary with changes in other attribute values. The dependencies between scheduling attributes are hierarchical in nature and must be considered when getting or setting scheduling attribute values. A change in one attribute can force another previous attribute setting to be discarded. Figure 15 illustrates the structure of these dependency relationships.
Figure 15 – Structure of dependency relationships
To avoid unexpected loss of scheduling attribute settings and to ensure proper availability and validation, use the following sequence when setting these attributes:
1. Contention scope and inheritance policy.
2. Scheduling policy and concurrency policy
3. Priority and time-slice quantum.
The start-policy attribute can be set at any time.
This list is not meant to imply that you must set all or any of these attributes, only that you will probably have better success and suffer less confusion if you adhere to this sequence.
The following sections explain each of the scheduling attributes, their usage, and any interdependencies that might be imposed by the Threading package or the underlying thread API.
Start Policy
In the Threading package, new threads of execution are created by calling the start() member on an instance of a threaded runnable class. The start() function creates a new thread and immediately interrupts that thread in order to make any necessary adjustments to the thread’s scheduling attributes before the thread starts executing within its run() member.
The start policy attribute indicates whether or not to leave the newly created thread in the interrupted state upon return from start(). Normally, a new thread is released from this interrupt before start() returns. If requested using this attribute, though, the thread can be left in the interrupted state, where it can be released some time later by calling the releaseInterrupt() member of the threaded runnable instance.
The enumerated type, RWStartPolicy, defines these start policies as:
RW_THR_START_RUNNING — Specifies that a new thread is to be allowed after successful creation and initialization. This is the default start policy.
RW_THR_START_INTERRUPTED — Specifies that a new thread should be left interrupted following start-up and initialization. Interrupted threads can be released when convenient by calling the releaseInterrupt() member on the same threaded runnable class instance.
The RWThreadAttribute member functions that are used to manipulate the start policy attribute include:
canGetStartPolicy() — Indicates whether the start policy attribute is supported in the current environment and whether getStartPolicy() can currently return a legal value. This function always returns true and has been included for consistency.
isStartPolicySet() — Indicates whether the start policy attribute value is the value that was previously set by a call to setStartPolicy().
getStartPolicy() — Returns the default start policy value if the attribute value has not yet been set. Otherwise, it returns the value specified in the last call to setStartPolicy(). The default start policy is available under all circumstances, and is defined as RW_THR_START_RUNNING.
canSetStartPolicy() — Indicates whether the start policy attribute and attribute value passed as an argument are supported in the current environment. This function always return true for either of the start policies and has been included for consistency.
setStartPolicy() — Sets the start policy attribute to the value passed as an argument. This function only throws an exception if the value passed is not one of the two legal values.
resetStartPolicy() — Restores the start policy attribute to its default value.
No specific interdependencies exist between the start policy attribute and other scheduling attributes.
The start policy specified by an RWThreadAttribute can only be used at thread creation. To interrupt an active thread, use the RWThread member requestInterrupt() or the RWThreadSelf member interrupt().
Scheduling Contention Scope
The contention scope attribute is used to specify whether a thread is to compete for processing resources with other threads in the same process or with other processes in the same system.
A process-scope thread is multiplexed with other process-scope threads on one or more underlying kernel threads in a N:1 or N:M relationship. A system-scope thread is typically bound in a 1:1 relationship with a kernel thread. Figure 16 illustrates these relationships.
Figure 16 – Process-scope and system-scope relationships
Choosing between process-scope and system-scope. When choosing between process-scope and system-scope threads, consider the processing cost associated with scheduling and synchronizing them. Process-scope threads are generally scheduled and synchronized by code executing in the underlying threads library in user-space, while system-level threads are scheduled and synchronized by the kernel. Kernel-level synchronization and scheduling is, in general, significantly more expensive than user-level synchronization and scheduling. Because of this high processing cost, specify system contention scope only when system-wide scheduling issues must be addressed by your code, as when your application must include real-time behavior or operate under real-time constraints.
Using the feature test macro. The feature test macro for contention scope is RW_THR_HAS_CONTENTION_SCOPE. If this macro is not defined, attempts to query or set the contention scope attribute always produce an exception. If it is defined, then the current environment has some level of support or recognition for contention scope and might allow you to get or set the contention scope attribute.
The enumerated type, RWContentionScope, defines these contention scope policies as:
RW_THR_PROCESS_SCOPE
RW_THR_SYSTEM_SCOPE
The RWThreadAttribute member functions that manipulate the contention scope attribute value include:
canGetContentionScope() — Indicates whether the contention scope attribute is supported in the current environment and whether getContentionScope() can currently return a legal value.
isContentionScopeSet() — Indicates whether the contention scope attribute value is the value that was previously set by a call to setContentionScope(RWContentionScope).
getContentionScope() — Returns the default contention scope value if the attribute value has not yet been defined. Otherwise, it returns the value specified in the last call to setContentionScope(RWContentionScope). If the current environment does not support or define the contention scope attribute, then attempts to use this function result in exceptions.
canSetContentionScope() — Indicates whether the contention scope attribute and attribute value passed as an argument are supported in the current environment.
setContentionScope(RWContentionScope) — Sets the contention scope attribute to the value passed as an argument. If the current environment does not support the contention scope attribute or the specified attribute value, then attempts to use this function result in exceptions.
resetContentionScope() — Restores the contention scope value to its default value.
Specifying the contention scope. The contention scope of a thread can only be specified when a thread is created. You cannot change the contention scope of an active thread.
Changing the contention scope. Changing the contention scope value might cause a previous setting of the scheduling policy, priority, time-slice quantum, and concurrency attribute to be discarded. When you change the contention scope attribute, the Threading package validates these related attributes to ensure that any previous setting is compatible with the new scope, and if not, resets that attribute. The availability, default value, and supported range for these dependent attributes often vary in response to changes in the contention scope value. The specific dependencies and validation requirements are unique to each environment, and can be found in the appropriate user’s guide supplement.
Determining contention scope. To determine the contention scope of an active thread:
1. Acquire a handle to the thread’s runnable instance.
2. Use the getActiveAttribute() member in the handle class to retrieve a copy of the RWThreadAttribute instance used to create the thread.
3. Use the getContentionScope() member to query the attribute instance for the contention scope used.
Scheduling Inheritance Policy
The inheritance policy attribute is used to indicate whether the scheduling policy, priority, and time-slice quantum attributes for a new thread should be inherited from the creating thread or whether they should be based on the values defined within the RWThreadAttribute instance.
The enumerated type, RWInheritancePolicy, defines these inheritance policies as:
RW_THR_INHERIT — Specifies that the default scheduling policy, priority, and time-slice quantum attributes should be inherited from the creating thread, if each of those attribute values has been left unchanged or has been restored to the default value with a call to the appropriate “reset” function. This is the default inheritance policy.
RW_THR_EXPLICIT — Specifies that the default scheduling policy, priority, and time-slice quantum attributes should not be inherited, but should be included in the thread attribute instance.
The RWThreadAttribute member functions that manipulate the inheritance policy attribute value include:
canGetInheritancePolicy() — Indicates whether the inheritance policy attribute is supported in the current environment and whether getInheritancePolicy() can currently return a legal value. This function always returns true and is included for consistency.
isInheritancePolicySet() — Indicates whether the inheritance policy attribute value is the value that was previously set by a call to setInheritancePolicy(RWInheritancePolicy).
getInheritancePolicy() — Returns the default inheritance policy value if the attribute value has not yet been set. Otherwise, it returns the value specified in the last call to setInheritancePolicy(RWInheritancePolicy). The default inheritance policy is available under all circumstances and is defined as RW_THR_INHERIT.
canSetInheritancePolicy() — Indicates whether the inheritance policy attribute and attribute value passed as an argument are supported in the current environment. This function always returns true for either of the inheritance policies and is included for consistency.
setInheritancePolicy(RWInheritancePolicy) — Sets the inheritance policy attribute to the value passed as an argument. This function only throws an exception if the value passed is not one of the two legal values.
resetInheritancePolicy() — Restores the inheritance policy attribute to its default value.
Follow these rules when using this attribute:
If you should choose to set any one of the scheduling policy, priority, or time-slice attributes, the inheritance policy is forced to RW_THR_EXPLICIT.
Setting the inheritance policy to RW_THR_INHERIT causes the Threading package to discard any previous settings for the scheduling policy, priority, and time-slice attribute.
The Threading package does not allow you to mix inherited and explicitly-defined scheduling attributes by setting only those attributes that you do not wish inherit.
To determine the inheritance policy used to create an active thread:
1. Acquire a handle to the thread’s runnable instance.
2. Use the getActiveAttribute() member included by the handle class to retrieve a copy of the RWThreadAttribute instance that created the thread.
3. Use the getInheritancePolicy() member to query the attribute instance for the inheritance policy used at thread creation.
Concurrency Policy
As described in the previous section, some systems support N-to-M thread scheduling. In these systems, a process-scope thread is multiplexed with other process-scope threads on to one or more underlying kernel threads in N-to-M relationship. The concurrency policy attribute can be used to indicate whether or not the underlying threads system should increase the number of kernel threads when it creates a new process-scope thread, as illustrated in Figure 17.
Figure 17 – Concurrency policy
Issues to consider when requesting the creation of additional kernel threads:
You can increase the effective concurrency of the threads in your application because most systems can distribute kernel threads on separate processors and often use time-slicing when scheduling kernel threads on a single processor.
When increasing the effective concurrency level, consider the processing cost associated with creating new kernel threads and the higher cost of scheduling and synchronizing them.
Process-scope threads are generally scheduled and synchronized by code executing in the underlying threads library in user-space, while the underlying kernel threads are scheduled and synchronized by calls to the kernel.
Even though increasing the effective concurrency level can result in increased processing costs, this method is still preferable to choosing system-scope threads over process-scope threads.
The difference is that kernel threads added when the concurrency level is increased are still shared between process-level threads, while system-scope threads are permanently bound to kernel threads, thereby prohibiting their reuse during blocking waits.
Using the feature test macro. The feature test macro for concurrency policy is RW_THR_HAS_CONCURRENCY_POLICY. If this macro is not defined, attempts to query or set the concurrency policy attribute always produce an exception. If it is defined, then the current environment has some level of support or recognition for concurrency policy and might allow you to get or set the concurrency policy attribute.
The enumerated type, RWConcurrencyPolicy, defines these concurrency policies as:
RW_THR_NO_CHANGE — The creation of a new process-scope with this attribute value thread does not force the creation of a new underlying kernel thread. This value does not prohibit the threads system from choosing to create new kernel threads if its own policies dictate such a necessity.
RW_THR_INCREASE — Creation of a new process-scope thread forces the creation of a new underlying kernel thread.
The RWThreadAttribute member functions that manipulate the concurrency policy attribute value include:
canGetConcurrencyPolicy() — Indicates whether the concurrency policy attribute is supported in the current environment and whether getConcurrencyPolicy() can currently return a legal value.
isConcurrencyPolicySet() — Indicates whether the concurrency policy attribute value is the value that was previously set by a call to setConcurrencyPolicy(RWConcurrencyPolicy).
getConcurrencyPolicy() — Returns the default concurrency policy value if the attribute value has not yet been defined. Otherwise, it returns the value specified in the last call to setConcurrencyPolicy(RWConcurrencyPolicy). If the current environment does not support or define the concurrency policy attribute, then attempts to use this function result in exceptions.
canSetConcurrencyPolicy() — Indicates whether the concurrency policy attribute and attribute value passed as an argument are supported in the current environment.
setConcurrencyPolicy(RWConcurrencyPolicy) — Sets the concurrency policy attribute to the value passed as an argument. If the current environment does not support the concurrency policy attribute or the specified attribute value, then attempts to use this function result in exceptions.
resetConcurrencyPolicy() — Restores the concurrency policy value to its default value.
Changing the contention scope attribute value can cause a previous concurrency policy setting to be discarded and can affect the availability of this attribute, as indicated in the following table:
Contention Scope
Concurrency Policy
Process Scope(if available)
No Change or Increase(if available)
System Scope(if available)
Not Available
The concurrency change requested when creating a thread cannot be undone.
To determine the concurrency policy used when creating an active thread:
1. Acquire a handle to the thread’s runnable instance.
2. Use the getActiveAttribute() member in the handle class to retrieve a copy of the RWThreadAttribute instance used to create the thread.
3. Use the getConcurrencyPolicy() member to query the attribute instance for the concurrency policy used when creating the thread.
Scheduling Policy
Often in a multithreaded system, more threads exist than processors available to run them. The scheduling policy attribute contains the policy that the system uses in selecting threads to run on available processors.
Threads can exist in several states as explained below and illustrated in Figure 18.
A thread becomes runnable when created, unless explicitly created in a stopped state.
Eventually, a runnable thread is selected, or dispatched, for execution on a processor and becomes active.
While executing, a thread can block waiting on a synchronization resource such as a mutex or condition variable.
Once the synchronization resource releases the thread, it is awakened and again enters the runnable state.
If a higher-priority thread become runnable while a lower-priority thread is active, the lower-priority thread is preempted and returned to the runnable state so that the higher-priority thread can execute.
Threads can also be suspended, leaving them in a stopped stated until continued. A thread can voluntarily preempt itself by yielding execution and explicitly block itself by sleeping.
A thread usually exits at some point and, depending on the system, might enter an exited state where the thread waits to be joined or simply cease to exist.
Figure 18 – Thread states
A scheduling policy dictates how and when threads are to enter or leave the runnable, active, and blocked states. A scheduling policy defines:
The criteria for selecting the next runnable thread to dispatch when an active thread yields or blocks.
The conditions under which an active thread is to be preempted.
The criteria for selecting the next thread to awaken if more than one thread is waiting on the same synchronization resource. In some cases, this determination is made by the synchronization mechanism and occurs regardless of scheduling policy.
The scheduling policy is system dependent. In some systems, each thread can be assigned a different scheduling policy, allowing the developer to choose the policy that best meets the requirements for that thread. In other systems, the scheduling policies are defined at the process level, or fixed according to a thread’s contention scope.
Possible scheduling policy values. The enumerated type, RWSchedulingPolicy, defines the set of all possible scheduling policy values supported by the Threading package as:
RW_THR_OTHER — Included as a catch-all for scheduling policies that can’t be categorized as one of the policies defined by the remaining RWSchedulingPolicy values. This policy is usually mapped to the default policy of the underlying thread’s API, but is seldom returned by the getSchedulingPolicy() function, which generally returns the one of the policies (listed below) that most closely describes the default policy.
RW_THR_PREEMPTIVE — In preemptive scheduling, threads run until preempted by a thread of higher-priority or until blocked. Thread priorities are set by the application; the system does not dynamically change a thread’s priority.
RW_THR_TIME_SLICED_DYNAMIC — In systems with dynamic time-sliced scheduling, threads still run either until they are preempted by a thread of higher priority, until some time-quantum has elapsed, or until blocked. The difference is that the priority and/or time-slice quantum assigned to a thread can be altered dynamically by the system to give some level of fairness and optimization.
RW_THR_TIME_SLICED_FIXED — Under a fixed, time-sliced scheduling policy, threads are still time-sliced, but the thread priorities are not altered by the system.
Using the feature test macro. The feature test macro for scheduling policy is RW_THR_HAS_SCHEDULING_POLICY. If this macro is not defined, attempts to query or set the scheduling policy attribute always produce an exception. If it is defined, then the current environment has some level of support or recognition for scheduling policy and might allow you to get or set the scheduling policy attribute.
Member functions. The RWThreadAttribute member functions that manipulate the scheduling policy attribute include:
canGetSchedulingPolicy() — Indicates whether the scheduling policy attribute is supported in the current environment and whether getSchedulingPolicy() can currently return a legal value.
isSchedulingPolicySet() — Indicates whether the scheduling policy attribute value is the value that was previously set by a call to setSchedulingPolicy(RWSchedulingPolicy).
getSchedulingPolicy() — Returns the default scheduling policy value if the attribute value has not yet been defined. Otherwise, it returns the value specified in the last call to setSchedulingPolicy(RWSchedulingPolicy). If the current environment does not support or define the scheduling policy attribute, then attempts to use this function result in exceptions.
canSetSchedulingPolicy() — Indicates whether the scheduling policy attribute and attribute value passed as an argument are supported in the current environment.
setSchedulingPolicy(RWSchedulingPolicy) — Sets the scheduling policy attribute to the value passed as an argument. If the current environment does not support the scheduling policy attribute or the specified attribute value, then attempts to use this function result in exceptions.
resetSchedulingPolicy() — Restores the scheduling policy attribute to its default value. The default value can vary according to the current value of other attributes.
Changing the contention scope. In addition to any environment-specific restrictions, the availability of individual scheduling policies often depends on the current contention scope. Changing the contention scope attribute value can cause a previous scheduling policy setting to be discarded and can affect the availability of specific scheduling policies.
Changing the scheduling policy. Similarly, changing the scheduling policy value can cause a previous setting of the priority and time-slice quantum attributes to be discarded. When you change the scheduling policy attribute, the Threading package validates these related attributes to insure that any previous setting is compatible with the new policy, and if not, resets that attribute. The default value and supported range for these dependent attributes often vary in response to changes in the scheduling policy value. The specific dependencies and validation requirements are unique to each environment.
Inheriting a scheduling policy. Scheduling policy 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 policy appropriate for the current settings and environment.
Setting the scheduling policy. Setting the scheduling policy attribute value when the current inheritance policy is RW_THR_INHERIT forces the inheritance policy attribute to be changed to RW_THR_EXPLICIT.
Using the scheduling policy. The scheduling policy specified by an RWThreadAttribute can only be used when the thread is created. To manipulate the scheduling policy for an active thread, use the following RWThread and RWThreadSelf member functions:
canGetSchedulingPolicy()
getSchedulingPolicy()
canSetSchedulingPolicy()
setSchedulingPolicy(RWSchedulingPolicy)
Exceptions. In addition to throwing the same exceptions as their RWThreadAttribute counterparts, an RWTHRThreadNotActive exception is thrown if you attempt to query or set the scheduling policy on a threaded runnable that does not possess an active thread.
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.
Scheduling Time-Slice Quantum
The time-slice quantum attribute is used to define the maximum amount of time that a thread is allowed to execute before forcibly preempting it to allow another thread to execute. A time-slice quantum is typically associated with a scheduling policy of RW_THR_TIME_SLICED_FIXED.
Using the feature test macro. The feature test macro for scheduling time-slice quantum is RW_THR_HAS_TIME_SLICE_QUANTUM. If this macro is not defined, attempts to query or set the time-slice quantum attribute always produce an exception. If it is defined, then the current environment has some level of support or recognition for time-slice quantum and might allow you to get or set this attribute. A time-slice quantum is defined in terms of milliseconds using an unsigned long value.
Member functions. The RWThreadAttribute member functions that are used to manipulate the scheduling time-slice quantum include:
canGetTimeSliceQuantum() — Indicates whether the time-slice quantum is supported in the current environment and whether getTimeSliceQuantum() can currently return a legal value.
isTimeSliceQuantumSet() — Indicates whether the time-slice quantum value is the value that was previously set by a call to setTimeSliceQuantum(unsigned long).
getTimeSliceQuantum() — Returns the default time-slice quantum value if the attribute value has not yet been defined. Otherwise, it returns the value specified in the last call to setTimeSliceQuantum(unsigned long). If the current environment or circumstances do not allow interrogation of the time-slice quantum, then attempts to use this function result in exceptions.
canSetTimeSliceQuantum() — Indicates whether the time-slice quantum attribute is supported and can be set in the current environment.
setTimeSliceQuantum(unsigned long) — Sets the time-slice quantum attribute to the value passed as an argument. If the current environment does not support the adjustments to the time-slice quantum or if the specified attribute value is outside the legal range, then the function produces an exception.
resetTimeSliceQuantum() — Restores the time-slice quantum attribute to its default value. The default value can vary according to the current value of other attributes, such as priority.
getMinTimeSliceQuantum() — Returns the minimum priority value supported by the current contention scope and scheduling policy.
getMaxTimeSliceQuantum() — Returns the maximum priority value supported by the current contention scope and scheduling policy.
Changing the inheritance or scheduling policy attributes. Adjustment of the time-slice quantum is not supported by many platforms and can be safely ignored because this attribute assumes an appropriate default value. Changing the inheritance or scheduling policy attributes, either directly or as the result of a change in contention scope, can cause a previous time-slice quantum setting to be discarded and can affect the availability and allowable range of values for this attribute, as shown in the next table.
Inheritance Policy
Scheduling Policy
Time-Slice Quantum
N/A
N/A
Not Available
Inherit
[Inherited]
[Inherited] (if available)
Explicit
Preemptive (if available)
Not Available
Fixed Time-Slicing (if available)
Policy-Dependent Range (if available)
Dynamic Time-Slicing(if available)
Not Available
NOTE >> The specific dependencies and validation requirements for the time-slice quantum attribute are unique to each environment, and can be found in the appropriate section of the Platform Guide supplement.
Inheriting the time-slice quantum. The time-slice quantum 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 policy appropriate for the current settings and environment. Setting the time-slice quantum attribute value when the current inheritance policy is RW_THR_INHERIT forces the inheritance policy attribute to be changed to RW_THR_EXPLICIT.
Using the time-slice quantum. The time-slice quantum specified by an RWThreadAttribute can only be used at thread creation. To manipulate the time-slice quantum for an active thread, use the following RWThread and RWThreadSelf member functions:
canGetTimeSliceQuantum()
getTimeSliceQuantum()
canSetTimeSliceQuantum()
setTimeSliceQuantum(unsigned long)
getMinTimeSliceQuantum()
getMaxTimeSliceQuantum()
Exceptions. In addition to throwing the same exceptions as their RWThreadAttribute counterparts, an RWTHRThreadNotActive exception is thrown if you attempt to query or set the time-slice quantum on a threaded runnable that does not possess an active thread.