| Previous | Contents | Index |
For the signals traditionally representing synchronous errors in the program, DECthreads catches the signal and converts it into an equivalent exception. This exception is then propagated up the call stack in the current thread and can be caught and handled using the normal exception catching mechanisms.
Table A-3 lists Tru64 UNIX signals that are reported as DECthreads exceptions by default. If any thread declares an action for one of these signals (using sigaction(2) or equivalent), no thread in the process can receive the exception.
| Signal | Exception |
|---|---|
| SIGILL | pthread_exc_illinstr_e |
| SIGIOT | pthread_exc_SIGIOT_e |
| SIGEMT | pthread_exc_SIGEMT_e |
| SIGFPE | pthread_exc_aritherr_e |
| SIGBUS | pthread_exc_illaddr_e |
| SIGSEGV | pthread_exc_illaddr_e |
| SIGSYS | pthread_exc_SIGSYS_e |
| SIGPIPE | pthread_exc_SIGPIPE_e |
When creating a thread based on a thread attributes object, DECthreads
potentially rounds up the value specified in the object's guardsize
attribute. DECthreads does so based on the value of the configurable
system variable PAGESIZE (see <sys/mman.h>. The
default value of the guardsize attribute in a thread attributes object
is a number of bytes equal to setting of PAGESIZE.
A.7 Thread Stack and Backing Store Allocation
Starting in Version 5.0, for threads that accept the default stack address attribute, DECthreads allocates a thread's writable stack area from uncommitted virtual memory, then commits predefined increments of the writable stack area to the thread only as it is needed. The stack's corresponding backing store is also reserved incrementally as the stack is committed. In this way, no more backing store is reserved than the stack actually requires.
Because Tru64 UNIX 5.0 does not commit backing store (or physical
pages) for stacks until the pages are used by the program, the default
stack size has been increased. The previous default of about 24Kb (3
pages) has been increased to 5Mb.
A.8 Dynamic Activation
Dynamic activation of the DECthreads run-time environment, or of code
that depends on DECthreads, is currently not supported.
A.9 Pagefaults and Realtime Scheduling
Like normal file I/O operations, pagefaults are "thread synchronous". A thread that incurs a "hard" pagefault (reading the page from backing store) will be blocked while other threads continue to run on the "virtual processor" (or on others). This has implications for realtime scheduling, especially of SCHED_FIFO policy threads, that do not expect to block except for explicit I/O synchronization. To write a SCHED_FIFO thread that cannot block unexpectedly, you must use mlockall to lock the application into memory, preventing pagefaults.
This appendix discusses DECthreads issues and restrictions specific to
the OpenVMS operating system.
B.1 Overview
The OpenVMS Alpha operating system supports multiple concurrent
"execution contexts" within a process. DECthreads uses these
kernel execution contexts to implement user threads. One important
benefit of this is that user threads can run simultaneously on separate
processors in a multiprocessor system. Review Section 3.1 for tips
for ensuring that your application will work correctly with kernel
threads and multiprocessing. Even without kernel threads, OpenVMS Alpha
"upcalls" support smooth integration between the DECthreads
and kernel scheduler. See Section B.12 for more information, including
how to enable kernel threads and upcalls in your application. OpenVMS
VAX supports neither kernel threads nor upcalls.
B.2 Compiling Under OpenVMS
The DECthreads C language header files shown in Table B-1 provide interface definitions for the DECthreads pthread and tis interfaces.
| Header File | Interface |
|---|---|
| pthread.h | POSIX.1 style routines |
| tis.h | Compaq proprietary thread-independent services routines |
Include only one of these header files in your module.
Special compiler definitions are not required when compiling threaded
applications that use the pthread interface or the
tis interface.
B.3 Linking OpenVMS Images
DECthreads is supplied only as shareable images. It is not supplied as object libraries.
When you link an image that calls DECthreads routines, you must link against the appropriate images listed in Table B-2.
| Image | Routine Library |
|---|---|
| PTHREAD$RTL.EXE | POSIX.1 style interface |
| CMA$TIS_SHR.EXE | Thread-independent services |
The image files PTHREAD$RTL.EXE, CMA$TIS_SHR.EXE, CMA$RTL.EXE, and CMA$LIB_SHR.EXE are included in the IMAGELIB library, making it unnecessary to specify those images (unless you are using the /NOSYSLIB switch with the linker) in a Linker options file.
When you link an image that utilizes the CMA$OPEN_LIB_SHR.EXE and CMA$OPEN_RTL.EXE images, they must be specified in a Linker options file.
While this version of DECthreads for OpenVMS supports upward compatibility of source and binaries for the DECthreads d4 interface, DECthreads does not support upward compability for object files. For instance, under OpenVMS V7.0 and higher, to link object files that were compiled under OpenVMS V6.2, follow these steps:
|
An asynchronous system trap, or AST, is an OpenVMS mechanism for reporting an asynchronous event to a process. The following are restrictions concerning the use of ASTs with DECthreads:
Certain run-time libraries use conditional synchronization mechanisms. These mechanisms typically are enabled during image initialization when the run-time library is loaded, and only if the process is multithreaded (that is, if the DECthreads core run-time library PTHREAD$RTL has been linked in). If the process is not multithreaded, the synchronization is disabled.
If your application were to dynamically activate PTHREAD$RTL, any run-time library that uses conditional synchronization may not behave reliably. Thus, dynamic activation of the DECthreads core run-time library PTHREAD$RTL is not supported.
If your application must dynamically activate an image that depends upon PTHREAD$RTL (that is, the image must run, or can be run, in a multithreaded environment), you must build the application by explicitly linking the image calling LIB$FIND_IMAGE_SYMBOL against PTHREAD$RTL.
Use the OpenVMS command ANALYZE/IMAGE to determine whether an image depends upon PTHREAD$RTL. For more information see your OpenVMS documentation.
Libraries that wish to use thread-safe synchronization only when
threads are present should use the tis functions
instead of dynamically activating PTHREAD$RTL.EXE.
B.6 Default and Minimum Thread Stack Size
As of OpenVMS Version 7.2, DECthreads has increased the default thread stack size for both OpenVMS Alpha and OpenVMS VAX. Applications that create threads using the default stack size (or a size calculated from the default) will be unaffected by this change.
As of OpenVMS Version 7.2, DECthreads has increased the minimum thread
stack size (based on the PTHREAD_STACK_MIN constant) for
OpenVMS VAX only. Existing applications that were built using a version
prior to OpenVMS Version 7.2 and that base their thread stack sizes on
this minimum must be recompiled.
B.7 Requesting a Specific, Absolute Thread Stack Size
Prior to OpenVMS Version 7.2, when an application requested to allocate a thread stack of a specific, absolute size, DECthreads would increase the size by a certain quantity, then round up that sum to an integral number of pages. This process resulted in the actual stack size being considerably larger than the caller's request, possibly by more than one page.
Starting with OpenVMS Version 7.2, when an application requests DECthreads to allocate a thread stack of a specific, absolute size, no additional space is added, but the allocation is still rounded up to an integral number of pages.
Any application that uses default-sized stacks is unlikely to experience problems due to this change. Similarly, any application that sets its thread stack allocations in terms of either the DECthreads default or the allowable minimum stack size is unlikely to experience problems due to this change; however, depending on the allocation calculation used, the application might receive more memory for thread stacks.
Starting with OpenVMS Version 7.2, any thread that is created with a stack allocation of a specific, absolute size might fail during execution because of insufficient stack space. This failure indicates an existing bug in the application that was made manifest by the change in DECthreads.
When the application requests to allocate a thread stack of a specific
size, it must allow for not only the space that the application itself
requires, but also sufficient stack space for context switches and
other DECthreads activity. DECthreads only occasionally uses this
additional stack space, such as during timeslice interruptions. A
thread with inadequate stack space might encounter no problems during
development and testing because of timing vagaries---for instance, a
thread might not experience problems until a timeslice occurs while the
thread is at its maximum stack utilization---and this situation might
never arise during in-house testing. In a different system environment,
such as in a production environment, the timing might be different,
possibly resulting in occasional failures when certain conditions are
met.
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.1 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 (d4 or
DECthreads) 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.
| 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. |
This section applies to OpenVMS Alpha systems only.
Under OpenVMS Alpha Version 7.0 and later, DECthreads implements a two-level scheduling model. 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.
| Previous | Next | Contents | Index |