Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

Guide to DECthreads


Previous Contents Index

B.8 Declaring an OpenVMS Condition Handler

This section discusses a restriction on declaring an OpenVMS condition handler while using DECthreads exceptions and DECthreads behavior when a condition is signaled.

The following are three ways to declare an OpenVMS condition handler:

Do not declare an OpenVMS condition handler within a DECthreads TRY/ENDTRY exception block. Doing so deletes without notification any handler that exists for the current procedure. If your code declares a condition handler within the TRY/ENDTRY block, DECthreads exceptions will not be handled correctly until the next TRY statement is executed. The TRY statement restores the DECthreads condition handler.

On OpenVMS VAX, you can declare a condition handler outside of a TRY/ENDTRY block with no restrictions. If a condition handler has already been declared when you execute a TRY statement, DECthreads saves the previous handler address. When DECthreads receives a condition it does not handle (including SS$_UNWIND, SS$_DEBUG, or a condition code that does not have a SEVERE severity), DECthreads invokes the saved condition handler. The condition handler will be reestablished when the TRY block exits.

B.9 Thread Cancelability of System Services

On OpenVMS Alpha, system calls are now cancelation points for threads created using the POSIX 1003.1c style interface. System calls are not cancelation points for threads in legacy multithreaded applications that were created using the Compaq proprietary CMA (or cma) or POSIX 1003.4a/Draft 4 (or d4) interfaces. None of the system calls should be called with asynchronous cancelation enabled. For more information, see Section 2.3.7.

B.10 Using OpenVMS Alpha 64-Bit Addressing

On OpenVMS Alpha, DECthreads supports the use of 64-bit addressing in the pthread interface only. When compiling with the following command, the pthread_join() function returns a 64-bit void * value as the result:


 
   $ CC/POINTER_SIZE=LONG 
 

You can also use pthread_join64() or pthread_join32() to specify the length in bits of the return value.

Note that no other DECthreads functions have special 64-bit versions because the OpenVMS Alpha calling standard always supports 64-bit arguments and return values.

B.11 DECthreads Condition Values

Table B-3 lists the DECthreads condition values for OpenVMS systems and provides an explanation and user action.

Table B-3 DECthreads Condition Values
Condition Value Explanation and User Action
CMA$_EXCCOP Exception raised; OpenVMS condition code follows.
  Explanation: One of the DECthreads exception commands (RAISE or RERAISE) raised or reraised an exception condition originating outside the DECthreads library. The secondary condition code in the signal vector will be the original code.
  User Action: See the documentation for the software that your program is calling to determine the reason for this exception.
   
CMA$_EXCCOPLOS Exception raised; some information lost.
  Explanation: CMA$_EXCCOPLOS is nearly the same as CMA$_EXCCOP except that DECthreads determined that the copied signal vector may contain address arguments. However, the address arguments may not be valid when the stack is unwound and the condition is resignaled. Therefore, DECthreads clears the condition codes' arguments in the resignaled vector. In most cases, DECthreads knows that SS$_ code arguments are "safe" and will not clear them. Most other codes with arguments will result in CMA$_EXCCOPLOS.
  User Action: See the documentation for the software that your program is calling to determine the reason for this exception.
   
CMA$_EXCEPTION Exception raised; address of exception object is object-address.
  Explanation: This condition is used as the primary condition to RAISE an address-type DECthreads exception. The condition is signaled with a single argument containing the address of the EXCEPTION structure. There is no support for interpreting this value. It is only meaningful to the facility that defined the EXCEPTION. It is not good programming practice to let an address exception propagate outside the facility that raised it. There is no support for getting message text, and it cannot be interpreted by other facilities.
  User Action: None.

B.12 Two-Level Scheduling on OpenVMS Alpha Systems

This section applies to OpenVMS Alpha systems only.

Under OpenVMS Alpha Version 7.0 and later, DECthreads implements a new scheduling model, referred to as two-level scheduling. This model is based on the concept of virtual processors. Virtual processors are implemented as a result of using kernel thread technology in the OpenVMS Alpha operating system.

DECthreads schedules threads onto virtual processors similar to the way that OpenVMS schedules processes onto the processors of a multiprocessing machine. Thus, to the DECthreads runtime environment, a scheduled thread is executed on a virtual processor until it blocks or until it exhausts its timeslice quantum; then DECthreads schedules a new thread to run.

While DECthreads schedules threads onto virtual processors, the OpenVMS scheduler also schedules virtual processors to run on physical processors. The term two-level scheduling derives from this relationship.

The two-level scheduling model provides these advantages:

The key to making the two-level scheduling model work is the upcall mechanism. An upcall is a communication between the OpenVMS scheduler and the DECthreads scheduler. When an event occurs that affects the scheduling of a thread, such as blocking for a system service, the OpenVMS scheduler calls "up" to the DECthreads scheduler to notify it of the change in the thread's status.

This upcall gives DECthreads the opportunity to schedule another thread to run on the virtual processor in place of the blocking thread, rather than to allow the virtual processor itself to block, which would deny that resource to other threads in the process.

Upcalls are typically arranged in pairs, with an "unblock" upcall corresponding to each "block" upcall. The unblock upcall notifies DECthreads that a previously blocked thread is now eligible to run again. DECthreads schedules that thread to run when it is appropriate, given the thread's scheduling policy and priority.

B.12.1 Linker Options to Specify Image's Use of Kernel Threads

In OpenVMS Alpha Version 7.1 and later, the linker supports the /THREADS_ENABLE (or /NOTHREADS_ENABLE) qualifier for specifying the role of kernel threads in the resulting image. Use this qualifier to specify that the image controls whether the process can create multiple kernel threads and whether the OpenVMS Alpha kernel's support for DECthreads upcalls is enabled. If this qualifier is not specified, the default linker setting is /NOTHREADS_ENABLE, which results in an image that behaves as under OpenVMS Alpha Version 6.

The /THREADS_ENABLE qualifier takes two keyword arguments, MULTIPLE_KERNEL_THREADS and UPCALLS. Table B-4 summarizes the allowable combinations of these keywords and their effects.

Table B-4 Results of Keyword Arguments to /THREADS_ENABLE Qualifier
Keywords Specified Result
/NOTHREADS_ENABLE No kernel threads support for DECthreads
   
/THREADS_ENABLE
or:
/THREADS_ENABLE=(MULTIPLE_KERNEL_THREADS,UPCALLS)
Full kernel threads support for DECthreads, including the ability to run multiple use threads simultaneously on different CPUs on a multiprocessor machine
   
/THREADS_ENABLE=MULTIPLE_KERNEL_THREADS Same behavior as if /NOTHREADS_ENABLE is specified (without support for upcalls, DECthreads cannot reliably use multiple kernel threads)
   
/THREADS_ENABLE=UPCALLS Upcall support for DECthreads (such as making system calls thread-synchronous), but restricts the process's threads to one CPU on a multiprocessor machine

Note

Under no circumstances should a process explicitly create kernel threads. DECthreads creates them as needed when allowed to do so. Explicit creation of kernel threads by an application disrupts the operation of the DECthreads runtime environment and causes incorrect and/or unreliable application behavior.

B.12.2 Setting Kernel Threads Support in Existing Images

Under OpenVMS Alpha only, use the THREADCP tool to set or show the kernel threads features described above for an existing image. The tool provides the ability to enable, disable, and show the state of the thread control bits in an image's header.

The THREADCP command verb is not part of the normal set of DCL commands. To use the tool, you must define the command verb before invoking it.

In a THREADCP command, an image file name is a required parameter for use with all supported qualifiers. THREADCP supports abbreviations to the first character for all qualifiers and parameters. When the SHOW qualifier is used alone with the THREADCP command, the file name can contain wildcard characters.

After you define the THREADCP command verb, an image's thread control bits can be set or cleared using the /ENABLE and /DISABLE qualifiers, respectively. To do so, specify the name of each thread control bit to be enabled, disabled, or shown. One or both thread control bits can be specified. The user must have write access to the image file.

If no thread control bit is specified, the THREADCP default is to operate on both bits. If the image is currently being executed or is installed, it cannot be modified.

B.12.2.1 Examples

This command defines the THREADCP command verb:


 
   $ SET COMMAND SYS$UPDATE:THREADCP.CLD 
 

This command displays the current settings of both thread control bits for the image TEST.EXE:


 
   $ THREADCP/SHOW TEST.EXE 
 

This command displays the current settings of both thread control bits for all SYS$SYSTEM images:


 
   $ THREADCP/SHOW SYS$SYSTEM:* 
 

This command sets both thread control bits explicitly for the image TEST.EXE:


 
   $ THREADCP/ENABLE=(MULTIPLE_KERNEL_THREADS, UPCALLS) TEST.EXE 
 

This command clears both thread control bits explicitly for the image TEST.EXE:


 
   $ THREADCP/DISABLE=(MULTIPLE_KERNEL_THREADS, UPCALLS) TEST.EXE 
 

B.12.3 Querying and Setting Kernel Threads Features

On OpenVMS Alpha systems, a program can call the $GETJPI system service and specify the appropriate MULTITHREAD item code to determine whether kernel threads are in use. The return values have the same meanings as are defined for the MULTITHREAD system parameter, as summarized in Table B-5.

Table B-5 Return Values from$GETJPI System Service
Value Description
0 Both Thread Manager upcalls and the creation of multiple kernel threads are disabled.
1 Thread Manager upcalls are enabled; the creation of multiple kernel threads is disabled.
2 through 16 Both Thread Manager upcalls and the creation of multiple kernel threads are enabled. The number specified represents the maximum number of kernel threads that can be created for a single process.

B.12.4 Creation of Virtual Processors

Virtual processors are created as they are needed by the application. For a multithreaded application, the number of virtual processors that DECthreads creates is limited by the SYSGEN parameter MULTITHREAD. This parameter is typically set to the number of processors present in the system.

In general, there is no reason to create more virtual processors than there are physical processors; that is, the virtual processors would contend with each other for the physical processors and cause unnecessary overhead. Regardless of the value of the MULTITHREAD parameter, DECthreads creates no more virtual processors than there are user threads (excluding DECthreads internal threads).

DECthreads does not delete virtual processors or let them terminate. They are retained in the HIB idle state until they are needed again. During image rundown, they are deleted by OpenVMS.

The DECthreads scheduler can schedule any user thread onto any virtual processor. Therefore, a user thread can run on different kernel threads at different times. Normally, this should pose no problem; however, for example, a user thread's PID (as retrieved by querying the system) can change from time to time.

B.12.5 Delivery of ASTs

When a user mode AST becomes deliverable to a DECthreads process, the OpenVMS scheduler makes an upcall to DECthreads, passing the information that is required to deliver the AST (service routine address, argument, and target user thread ID). DECthreads stores this information and queues the AST to be delivered to the appropriate user thread. That thread is made runnable (if it is not already), and executes the AST routine the next time it is scheduled to run. This means the following:

In addition to per-thread ASTs, there are also user mode ASTs that are directed to the process as a whole, or to no thread in particular, or to a thread that has since terminated. These "process" ASTs are queued to the initial thread, making the thread runnable in a fashion similar to per-thread ASTs. They are executed in the context of the initial thread, for the following reasons:

Note

In OpenVMS Version 7.0 and later, all ASTs are directed to the process as a whole. In future releases, AST delivery will be made per thread as individual services are updated.

The following implications must be considered for application development:

B.12.6 Blocking System Services

In OpenVMS Alpha Version 7.0 and later, with few exceptions a blocking system service call is thread synchronous---that is, only the calling thread is blocked. The exceptions are services that don't block in user mode and services that set common event flags. (See also Section B.12.8.)

When a thread calls a system service that must block, the OpenVMS scheduler makes an upcall to allow DECthreads to schedule another user thread to execute. Therefore, only the calling thread is blocked, all other threads are unaffected, and the process continues running. When the service completes, the thread is awakened by means of another upcall, and DECthreads schedules it to run again at the thread's next opportunity.

This applies to all "W" forms of system services. For example, $QIOW, $END_TRANSW, and $GETJPIW. Additionally, this applies to the following event flag services: $WAITFR, $WFLAND, and $WFLOR.

B.12.7 $HIBER and $WAKE

$HIBER and $WAKE result in upcalls to DECthreads. When a user thread calls $HIBER, only that thread is blocked; all other threads continue running. The blocking thread is immediately unscheduled and another thread is scheduled to run instead. When a thread (or another process) calls $WAKE, all hibernating threads are awakened.

Prior to OpenVMS Version 7.0, a thread that called a $HIBER (or called a library routine that eventually resulted in a call to $HIBER) would cause the whole process to hibernate for a brief period whenever that thread was scheduled to "run." Also, with multiple threads in calls to $HIBER simultaneously, there was no reliable way to wake the threads (or a specific thread); the next hibernating thread to be scheduled would awaken, and any other threads would continue to sleep.

In OpenVMS Alpha Version 7.0 and later, these problems have been resolved. However, this new behavior has some other effects. For instance, hibernation-based services, such as LIB$WAIT and the C RTL sleep() routine, may be prone to premature completion. If the service does not validate its wakeup (that is, ensure that enough time has passed or that there is some other reason for it to return), then it will be prone to this problem, as are the above services, since they do not perform such wake-up validation.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
6101PRO_030.HTML