Rogue Wave banner
Previous fileTop of DocumentContentsIndexNext file

3.9 Thread Attributes

The threads produced using the mechanisms described in earlier examples can be sufficient for typical applications. These threads use default scheduling and stack management strategies defined by the Threading package and the underlying thread API. However, other situations might require more control over a thread's scheduling behavior and stack memory utilization.

For this additional control, the Threading package defines a set of thread attributes that allow you to choose various thread scheduling and stack management policies. Instances of the RWThreadAttribute class define the initial attributes for new classes. The RWThread and RWThreadSelf classes have methods for manipulating the scheduling attributes of an active thread.

To define the initial attributes for a thread, you create an RWThreadAttribute instance, set the desired attribute values, and supply this instance to a threaded runnable class instance. The threaded runnable uses the attribute values to configure each new thread created when start() is called. Once a threaded runnable is started, the scheduling attributes of its active thread can be manipulated using member functions included in the RWThread and RWThreadSelf classes.

3.9.1 Thread Attribute Families

The thread attributes supported by the Threading package can be divided into two families: thread scheduling attributes and thread stack management attributes.

3.9.1.1 Scheduling Attributes

The scheduling attributes include:

For more information on these attributes, see Section 3.9.9, "Scheduling Attributes."

3.9.1.2 Stack Management Attributes

The stack allocation attributes define one of two different stack management policies, either system-managed or user-managed.

If the system allocates and manages a thread's stack, the two significant attributes are:

If the user application allocates and manages a thread's stack, the relevant attributes include:

For more information on these attributes, see Section 3.9.10, "Stack Attributes."

3.9.2 Thread Attribute Portability

Thread attributes and attribute values are not uniformly supported across all environments. Some of the policies and attribute values described in this guide might be available only under specific operating systems.


NOTE: Once you begin using thread attributes, you risk compromising the cross-platform portability of your code.

This is largely due to the fact that scheduling and stack allocation policies tend to vary significantly between each of the environments supported by the Threading package. Rogue Wave has made every attempt to alleviate or hide these differences without prohibiting access to the platform-specific controls that some developers require. It is up to you to carefully review and understand the implementation differences between each platform that you plan to support.

To find out which attributes are supported:

If you attempt to access an unsupported attribute or use an illegal or unsupported attribute value:

The first two exceptions can always be avoided by using the feature-test functionality included by the library.

3.9.3 Testing For Support

As discussed earlier, the specific level of support for each thread attribute varies from platform to platform. The Threading package has several mechanisms and techniques you can use for testing that level of support.

3.9.3.1 Using Feature Test Macros

Use the following feature-test macros to determine, at compile-time, whether the current environment has any support for the corresponding thread attribute:

If a macro is not defined, attempts to query or set the corresponding attribute always produce an exception. If the macro is defined, then the current environment has some level of support or recognition for the attribute and might allow you to get or set the attribute value.

3.9.3.2 "Get" Test Functions

Use the following functions at run-time to determine whether the current environment allows you to query the corresponding thread attributes:

These functions follow several rules:

If the inheritance policy is RW_THR_INHERIT, the scheduling policy, priority, and time-slice quantum values cannot be queried for their default values. If these scheduling attributes are inherited, the "get min" and "get max" functions for these attributes will likely produce RWTHROperationNotAvailable exceptions because not enough information is available to determine the legal range of values.

Even if an attribute is supported in a particular environment, you might still be restricted from getting and setting that attribute as a consequence of other attribute values. As an example, the concurrency policy attribute might only be accessible when the contention scope is set for process-scope. Some attribute settings might also require specific security authorizations or privileges.

Once a thread has been created and is active, you can use the following RWThread or RWThreadSelf functions to test whether or not you can get the corresponding attribute value for an active thread:

3.9.3.3 "Set" Test Functions

Use the following functions at run-time to determine whether the current environment allows you to set the corresponding thread attribute value:

These functions return one of the following values:

Each of these functions that accepts a policy value produces an RWTHRBoundsError exception if the value specified as an argument is not legal policy value for that attribute. This exception can be avoided by making sure that you are using the appropriate enumerated value names for each attribute.

Once a thread has been created and is active, you can use the following RWThread or RWThreadSelf functions to test whether or not you can change the corresponding attribute value for an active thread:

3.9.3.4 "Is Set" Test Functions

Use the following functions to determine whether the corresponding attribute still has the value specified by an earlier call to the matching "set" function:

These functions return one of the following values:

3.9.4 Querying Attribute Values

Use the following functions to query the corresponding attribute value:

These functions throw the following exceptions:

The process-scope and system-scope priority functions can be substituted for getPriority(), and vice-versa, as long as you define the appropriate contention scope.

Once a thread has been created and is active, you can use the following RWThread or RWThreadSelf functions to set the corresponding thread attribute value:

In addition to the exceptions produced by their RWTHRThreadAttribute counterparts, these functions throw an RWTHRThreadNotActive exception if the threaded runnable instance being manipulated does not have an active thread.

3.9.5 Setting Attribute Values

Use the following functions to set the corresponding attribute value:

These functions throw the following exceptions:

The process-scope and system-scope priority functions can be substituted for setPriority(RWPriority) and vice-versa, as long as the appropriate contention scope has been defined.

Once a thread has been created and is active, you can use the following RWThread and RWThreadSelf functions to set the corresponding thread attribute value:

In addition to the exceptions produced by their RWThreadAttribute counterparts, these functions can throw an RWTHRThreadNotActive exception if the threaded runnable instance being manipulated does not have an active thread.

3.9.6 Default Attribute Values

If you do not specify a value for an attribute, then the values are supplied by one of the following:

For some attributes, you can query an RWThreadAttribute instance for default attribute values by using the appropriate "get" function prior to setting the corresponding attribute. Before attempting to get the value, though, make sure that a default value is available by calling the appropriate "can get" function, as shown in Example 27.

Example 27 -- Querying for default thread attribute values

The default values for some attributes might change in response to changes in other attribute values. For example, the range of legal priority values often varies according to the scheduling policy attribute value.

The default values for many of the attributes vary from environment to environment. You can find a description of the default values for attributes in the Threads.h++ Platform User's Guide.

3.9.7 Restoring Default Attribute Values

Use the following functions to restore the default value, if any, for the corresponding attribute:

These functions always succeed. If the target attribute is not supported, these functions clear any previous setting, and the appropriate default value is supplied by the underlying API.

3.9.8 Determining the Legal Range For An Attribute

To determine the current limits for the priority, stack size, and time-slice quantum attributes, use the following RWThreadAttribute member functions:

Once a thread has been created and is active, you can use a similar set of functions included in the RWThread and RWThreadSelf classes.

In addition to throwing the same exceptions as their RWThreadAttribute counterparts, these functions might also produce an RWTHRThreadNotActive exception if you attempt to query the current limits on a threaded runnable that does not possess an active thread.

3.9.9 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.

3.9.9.1 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:

The RWThreadAttribute member functions that are used to manipulate the start policy attribute include:

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().

3.9.9.2 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:

The RWThreadAttribute member functions that manipulate the contention scope attribute value include:

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.

3.9.9.3 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:

The RWThreadAttribute member functions that manipulate the inheritance policy attribute value include:

Follow these rules when using this attribute:

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.

3.9.9.4 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:

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:

The RWThreadAttribute member functions that manipulate the concurrency policy attribute value include:

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 ScopeConcurrency 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.

3.9.9.5 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 scheduling policy dictates how and when threads are to enter or leave the runnable, active, and blocked states. A scheduling policy defines:

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:

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:

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:

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.

3.9.9.6 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:

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:

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:

Requirement for two priority values. Some platforms, such as Solaris, require the use of two separate priority values for threads with system contention scope;

Requirement for a separate process-scope priority. You should only need to define a separate process-scope priority for a system-scope thread when:

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.

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 PolicyScheduling PolicyPriority
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 ScopeRequires
Dual Priorities
Inheritance PolicyScheduling PolicyProcess-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 ScopeInheritance PolicyScheduling PolicySystem-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:

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.

3.9.9.7 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:

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 PolicyScheduling PolicyTime-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 User's 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:

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.

3.9.10 Stack Attributes

In single-threaded processes, the size of the stack is usually limited only by the amount of free memory space because the stack can continue to grow until it runs into the memory space allocated for the heap.

In a multithreaded application, each thread's stack must be limited because each thread has its own stack, and every thread stack must be allocated in the same address space. To allocate a stack, each thread must reserve some fixed-sized portion of the address space. The growth of these stacks is now limited by their allocation size and the presence of other thread stacks in the same address space. Stack allocation is demonstrated in Figure 20.

Figure 20 -- Stack allocation

3.9.10.1 Allocating and Managing a Thread Stack

The responsibility for allocating and managing a thread stack is usually left to the system, but some environments allow users to create and manage their own stack space.

If the system is given the responsibility for allocating and managing the stack, then you might also have the opportunity to choose whether to commit physical memory and pagefile space to the stack at the time of its creation or to commit memory on-demand as the stack grows.

To support each of these variations, the Threading package defines several attributes that can be used to select and define the desired stack allocation policy:

   
Thread Stack Attributes
Stack Allocation PolicyStack
Reserve Size
Stack
Commit Size
User Stack Address
and Size
System Allocated
Commit On Demand
X
   
Commit At Creation
  X
 
Mixed
X
X
 
User Allocated
    X

Issues to consider when using stack attributes:

3.9.10.2 System-Managed Stack Attributes

The default choice for stack management policy is to let the system allocate and manage the stack, but the final choice between system-managed and user-managed stack allocation is determined by which attributes were most recently set. If the user-stack attributes were the last stack attributes changed prior to thread creation, then user-management of the stack is assumed.

The following attributes control system-managed stack allocation:

The macro RW_THR_HAS_PARTIAL_STACK_COMMITMENT indicates whether the current environment allows the user to specify that some amount of the memory space allocated for thread stack is to be committed to physical memory at creation.

If RW_THR_HAS_PARTIAL_STACK_COMMITMENT is defined, then the macro RW_THR_HAS_STACK_COMMIT_SIZE is defined. If RW_THR_HAS_STACK_COMMIT_SIZE is defined, but RW_THR_HAS_PARTIAL_STACK_COMMITMENT is not, then the commit size also specifies the amount of memory to reserve for the stack.

3.9.10.3 User-Managed Stack Attributes

If you want to allocate and manage a thread's stack, the relevant attributes include the user stack address and user stack size.

Using the feature test macro. The feature test macro for user stack support is RW_THR_HAS_USER_STACK. If this macro is not defined, attempts to query or set the user stack attributes always produce an exception. If it is defined, then the current environment has support for user stack attributes and allows you to get or set these attributes.

Member functions. The RWThreadAttribute member functions that define and manipulate the user stack attributes include:

Exceptions. Any attempt to read the default values for these attributes produces an RWTHRInternalError exception. These attributes have no default values.

For additional information on user stack management support, see the appropriate chapters in the Threads.h++ Platform User's Guide.

3.9.11 Initializing Threaded Runnables

Every threaded runnable instance contains a thread attribute instance that defines the thread attributes to use when creating a new thread during a call to start(). The Threading package allows you to change or query the thread attribute instances associated with any threaded runnable.

3.9.11.1 Supplying RWThreadAttribute Instances To Threaded Runnables

RWThreadAttribute instances can be supplied to threaded runnable objects at one of two times:

RWThreadAttribute objects can be supplied to and shared between any number of threaded runnable objects. Changes made to the values of a shared thread attribute instance can be seen by all runnables that have been given a handle to that attribute instance.

The thread attribute instance referenced by each threaded runnable is only used or evaluated at the time the thread is created. A threaded runnable makes a local copy of its current thread attribute instance each time start() is called. This prevents the attribute values that were present when a thread was created from being lost as a result of future changes in a runnable's thread attribute instance or the attribute's values.

Changing a runnable's thread attribute instance or values of that attribute instance does not affect the active thread, if any, possessed by the runnable object. Attribute changes can only affect the next thread created as result of a call to start().

3.9.11.2 Supplying RWThreadAttribute Instances At Construction

RWThreadAttribute instances can be supplied to threaded runnable objects if the runnables are constructed using the appropriate static make() functions. If a thread attribute instance is not specified when a threaded runnable is constructed, then that runnable is initialized with its own RWThreadAttribute instance initialized with default values.

The following list identifies the make() functions for each threaded runnable class that accepts an RWThreadAttribute instance:

3.9.11.3 Supplying RWThreadAttribute Instances After Construction

To set the thread attributes for threaded runnables already constructed or for those created using the rwtMakeThreadXXX() functions, you must use the following accessor functions:

3.9.12 Querying Threaded Runnables For Thread Creation Attributes

The thread attribute instance associated with a threaded runnable can be queried at any time.



Previous fileTop of DocumentContentsIndexNext file

©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.