Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ threads(5) — DG/UX R4.11

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

reentrant(3)

mxdb(1)



threads(5)                        SDK R4.11                       threads(5)


NAME
       threads, pthreads - DG/UX support for Posix Threads

DESCRIPTION
       Threads are an emerging model for expressing parallelism within a
       process in the UNIX® operating system.

       On a system that provides hardware and software support for parallel
       execution, the use of threads can increase the speed of execution by
       providing an application programmer with the ability to use all
       available processors simultaneously.  Even on a uniprocessor system,
       threads are useful for mapping asynchronous behavior into equivalent
       synchronous behavior such as providing I/O parallelism, controlling
       asynchronous computations, or structuring applications composed of
       many logically distinct tasks (e.g., simulations and windowing
       systems).

       The thread model is based on a well understood synchronous,
       procedural model consistent with the C function model.  Threads can
       be used to model the parallelism inherent in windowing environments,
       realtime event processing, Ada tasking, transaction processing, and
       networked/distributed systems.

       A thread is a single sequential flow of control within a process.
       Each thread has a minimal amount of private state; most of the state
       associated with a process is shared among all of the threads in the
       process.

       This man page has the following sections:

         ·    Posix Threads Under DG/UX

         ·    Compiling and Linking

         ·    Header Files

         ·    Per-Thread Errno

         ·    Portability and Sanity Considerations

         ·    Basic Thread Management

         ·    Thread Attributes Objects

         ·    Thread-Specific Data

         ·    Threads in Familiar Unix Contexts

         ·    Signals

         ·    Thread Cancellation

         ·    Synchronization Primitives

         ·    Reentrant Functions

         ·    Debugging Threads Under DG/UX

         ·    Thread Scheduling

         ·    DG/UX Thread Groups

         ·    DG/UX Hierarchical CPU Affinity

   Posix Threads Under DG/UX
       Posix Threads, or Pthreads, provide an industry-wide standard for
       threads.  This standard is formally known as the Threads Extension
       for Portable Operating Systems, or IEEE 1003.4a.  A related standard
       is IEEE 1003.4, the realtime extension to Posix.

       Because Pthreads are not yet an official standard, DG/UX provides
       support for Draft 6 of Pthreads (dated February 26, 1992).  In order
       to allow easy migration from draft 6 to future drafts and the final
       standard, DG/UX plans to support draft 6 for at least one major
       revision beyond DG/UX R3.00.  This flexibility will give application
       writers ample time to migrate their code to these future drafts.  In
       fact, DG/UX plans to support multiple drafts concurrently, allowing
       applications to incrementally migrate their code.  As discussed in
       the next section, the target draft is selected on the compile line.

       DG/UX also provides numerous extensions to Pthreads, which are
       described briefly in later sections of this man page.  Most notably,
       DG/UX allows applications to create groups of computationally related
       threads that can be scheduled together onto sets of physically close
       CPUs on the underlying machine.   Thread Groups and Hierarchical CPU
       Affinity are unique features of DG/UX.   However, these DG-specific
       features can be easily isolated in application code, maintaining
       portability to other vendors' thread implementations, while
       optimizing performance on Data General systems.

   Compiling and Linking
       Compiling Pthread programs is only supported under the DG/UX Elf
       environment (the default environment).  Because Pthreads is not yet a
       standard, the desired draft of Pthreads must be specified on the
       compile line.  For now, draft 6 is the only draft that can be
       selected.  The Pthread functions and other DG/UX extensions are
       implemented in libthread.so, which can only be linked shared.

       The following example illustrates how to compile, using the GNU C
       compiler, a module named foo.c, which uses Draft 6 of Pthreads:

       # gcc -DPOSIX4ADRAFT6SOURCE -o foo.o foo.c

       The following example illustrates how to link this program named foo:

       # gcc -o foo foo.o -lthread -ldgc

       At runtime, /usr/lib/libthread.so, /usr/lib/libdgc.so.1 and
       /usr/dglib/libc.so.1 are linked in dynamically.  This allows DG/UX to
       supply new revisions of these libraries without requiring that
       applications be relinked.  This is particularly important as the
       implementation of libthread.so is closely related to the
       implementation of the DG/UX kernel, and the reentrant libraries are
       closely related to the implementation of libthread.so.

   Header Files
       It is sufficient to #include <pthread.h> in order to gain access to
       all threads functionality, including DG/UX extensions for thread
       groups.  The following list includes other common and internal header
       files related to Pthreads and DG/UX extensions for thread groups and
       hierarchical CPU affinity:

       <pthread.h>                     Main header file for Pthreads
       <sys/pthreads.h>                Included by <pthread.h> and contains
                                       draft-specific macros that map from
                                       pthreadcreate to
                                       d6pthreadcreate, etc.
       <sys/intd6pthread.h>        Included by <sys/pthread.h> and
                                       contains the actual Draft 6
                                       declarations of d6pthreadcreate,
                                       etc.
       <timers.h>                      Definition of struct timespec
       <sched.h>                       1004.4 realtime scheduling policies
       <sys/dglwp.h>                  DG/UX LWPs, LWP groups, and
                                       dglwpinfo
       <sys/dgcpu.h>                  DG/UX dgcpuinfo and hierarchical
                                       CPU affinity

   Per-Thread Errno
       In a multi-threaded program, each thread must have its own copy of
       errno because multiple threads could be making system calls at the
       same time.  The global definition of errno does not suffice because
       multiple threads could stomp on it at the same time.  Instead, when a
       program is compiled for threads, the definition of errno becomes a
       macro that ensures that each thread has its own copy of errno and can
       use the name errno as an l-value or r-value.

       In order to insure that all DG/UX system calls used by your
       application will use the per-thread errno, be sure to include -ldgc
       on the linker command as shown above.

       In Draft 6 of Pthreads, errno is set upon return from Pthread
       functions that fail and return -1.  In subsequent drafts, the errno
       value is instead returned by Pthread functions that fail.  However,
       errno will still be set by existing Posix and Unix functions.

   Portability and Sanity Considerations
       This section suggests the use of icing macros in order to facilitate
       error checking and portability to future drafts of Pthreads.  It also
       discusses portable feature probing for Pthreads functionality.

       Failing to check the return value from Pthread functions will cause
       errors to go undetected.  However, error checking can be cumbersome
       and can make code more difficult to read.  The use of icing macros
       can help hide this error checking and avoid extra typing.

       Applications should also consider portability to future drafts of
       Pthreads.  In particular, they must deal with the difference in the
       way errno is set in Draft 6 vs. returned in future drafts, and must
       handle some gratuitous name changes for functions and literals.
       Icing macros can also help to hide these differences.

       The following example illustrates the use of an icing macro to
       perform error checking on a call to pthreadmutexlock() and to hide
       its interface under draft 6.  The macro aborts on error:

       #define zthreadmutexlock(mutexptr)             \
       {                                                 \
       if (pthreadmutexlock(mutexptr) != 0)           \
           {                                             \
           fprintf(stderr                                \
                   "pthreadmutexlock failed in file %s \
                    at line %d, errno = %d\n",           \
                   FILE, LINE, errno );          \
           abort();                                      \
           }                                             \
       }

       Posix provides a portable paradigm for inquiring about the features
       of Pthreads that are supported by the underlying system.  Queries can
       be made at compile time by testing to see if certain literals are
       defined.  This, combined with runtime checks using sysconf(),
       provides the best assurance as to whether or not the underlying
       system supports particular features.  The following example tests to
       see if the running system supports Pthreads (in general):

       #include <unistd.h>

       #ifdef POSIXTHREADS
       if (sysconf(SCTHREADS)) == 1)
           {
           /* do threads stuff */
           }
       #endif

       DG/UX supports the following features in draft 6 of Pthreads:

       _POSIX_THREADS                            Pthreads, in general
       _POSIX_REENTRANT_FUNCTIONS                Reentrant library functions
       _POSIX_THREAD_ATTR_STACKSIZE              Thread stacksize attribute
       _POSIX_THREAD_PRIORITY_SCHEDULING         Fixed priority realtime
                                                 scheduling
       _POSIX_THREADS_PROCESS_SHARED             Interprocess mutexes and
                                                 conditions

       DG/UX does not currently support the following realtime features for
       mutexes:

       _POSIX_THREADS_PRIO_INHERIT               Priority inheritance
                                                 protocol for mutexes
       _POSIX_THREADS_PRIO_PROTECT               Priority ceiling protocol
                                                 for mutexes

   Basic Thread Management
       The following Pthread functions create threads, exit threads, wait
       for threads to terminate, and manipulate thread IDs:

       pthreadcreate               Create a thread
       pthreadjoin                 Wait for a thread to terminate and clean
                                    it up
       pthreadexit                 Terminate a thread normally
       pthreaddetach               Cause a thread to clean up for itself
                                    when it exits
       pthreadself                 Get the caller's thread ID
       pthreadequal                Compare two thread IDs

       DG/UX provides the following extensions for miscellaneous thread
       management:

       dgpthreadsleep             Sleep with nanosecond granularity
       dgpthreadgetlwpid         Translate a thread ID to an underlying
                                    LWPID
       dglwpinfo                  Get information about a process's LWPs

   Thread Attributes Objects
       Thread attributes objects provide a portable and extensible way of
       overriding the default creation attributes, such as stack size, for
       newly created threads.  They also allow an application to change the
       scheduling attributes, such as policy and priority, for an existing
       thread.

       Basic thread attributes manipulation functions are:

       pthreadattrinit                  Initialize a thread attributes
                                          object
       pthreadattrdestroy               Delete a thread attributes object
       pthreadattrsetstacksize          Set stack size thread attribute
       pthreadattrgetstacksize          Retrieve stack size thread
                                          attribute
       pthreadattrsetdetachstate        Set detach state thread attribute
       pthreadattrgetdetachstate        Retrieve detach state thread
                                          attribute

       Functions for manipulating the scheduling attributes for new and
       existing threads are discussed below in the section titled Thread
       Scheduling.

   Thread-Specific Data
       Thread-specific data allows each thread in a process to have
       different values for the the same variable name.  These variable
       names are called keys.

       Thread-specific data functions are:

       pthreadkeycreate           Create a new key (variable name)
       pthreadsetspecific          Set the caller's per-thread value for a
                                    key
       pthreadgetspecific          Get the caller's per-thread value for a
                                    key

   Threads in Familiar Unix Contexts
       In general, all passive process state is shared by all threads in the
       same process, but threads wait on things separately.

       For the user address space, all user address space is accessible by
       all threads.  This implies that a thread can write over any other
       thread's stack.  All threads share the same malloc pool.  If one
       thread maps a file, it becomes visible to all threads.  However,
       threads can page fault separately;  the page becomes resident for all
       threads in the process.

       All file descriptors are shared by all threads.  If one thread opens
       a file, it will be open for all threads.  However, threads block
       separately in calls to read(), write(), and select() on the same
       file, just as different processes would.  If one thread obtains a
       file or record lock, it will be obtained for all threads in the
       process; this is one of the only exceptions to the "threads wait
       separately" rule.

       Similarly, all open streams and pipes are accessible by all threads.
       If there are multiple threads blocked in a stream, the behavior is
       similar to when multiple processes are blocked in the same stream.
       All threads share the same controlling TTY.  Signals implicitly sent
       by streams are sent to the process as a whole.

       The process's PID, PPID, PGID, SID, etc. are the same for all
       threads.  The process's credentials and security attributes are
       shared by all threads (with a shared address space there is no point
       in having per-thread security attributes).  All threads share the
       same profiling buffer.  By default, threads share the same global
       process priority, but each thread can have its own local priority
       within the process.

       IPC descriptors for Unix semaphores and message queues are shared by
       all threads.  However, each thread waits separately.  Similar
       arguments apply to Posix 1003.4 realtime semaphores and message
       queues.

       When a thread calls exit(), either explicitly or implicitly as a
       result of returning from main(), all threads are aborted.  No thread-
       specific data destructor functions or cancellation handlers are
       called.  The system pulls the threads out from wherever they are.  If
       multiple threads are exiting at the same time, one will get there
       first and the others will be aborted.  When the last thread in a
       process terminates with a call to pthreadexit(), the whole process
       terminates; however, file buffers are not automatically flushed.

       When a thread calls exec, the exec'ing thread will change the address
       space to that for the new image and all other threads will be
       aborted.  If multiple threads are exec'ing at the same time, only one
       will succeed and the others will be aborted.

       When a thread forks a new process, the parent process is not changed.
       The child process will contain a copy of the forking thread; no other
       threads will exist in the child process.  This implies that the child
       process cannot safely do much else besides call exec(), as a thread
       that didn't make it into the child process could hold a critical
       resource whose state in the new process reflects that the missing
       thread holds it.

   Signals
       In general, signals are slow and error-prone, and should be avoided
       in multithreaded programs.  Signal handlers, in particular, can lead
       to deadlocks in multithreaded applications if they are not used
       correctly.

       The following discussion concentrates on the generation and handling
       of signals in the context of multithreaded programs.  It then
       proposes a safer way, using sigwait(2), to handle signals in a
       multithreaded program.

       There are only two ways to generate a signal for a specific thread.
       Firstly, the signal could have been synchronously generated by the
       thread;  this results from a SIGSEGV, SIGBUS, SIGFPE, SIGILL,
       raise(3C) call, or abort(3C) call.  Secondly, the signal could have
       been sent with a call to pthreadkill() from a thread in the same
       process as the target thread.

       All other generated signals are set to the process as a whole.  This
       includes, but is not limited to, signals sent by kill(), signals
       generated asynchronously by any software timer such as setitimer(),
       and most signals generated by the operating system.

       Signals sent to the process are delivered to exactly one thread.  The
       signal is delivered to a thread that has expressed "interest" in the
       signal.  If no thread is interested in the signal, the signal remains
       pending for the process as a whole until a thread takes interest in
       it.

       A thread expresses interest in a signal by unblocking it or waiting
       for the signal synchronously by calling sigwait(2).  When a signal is
       delivered to the process, the signal will be made pending first for a
       thread in the middle of sigwait() for the signal, then to a thread
       that has the signal unblocked, if any.  In the case of ties, an
       arbitrary thread is chosen in each case.

       A thread will process a pending signal at any time.  If the signal is
       a terminate signal (e.g., SIGKILL), the entire process and all of its
       threads are aborted.  If the signal is a stop signal (e.g., SIGSTOP),
       the entire process is stopped until the process is SIGCONTed.

       If a thread invokes a handler, it can occur at any point in the
       thread's execution.  Hence there isn't much that a signal handler can
       safely do.  For example, it can't call printf() because the thread
       may have been signaled out of printf(), where it may hold a critical
       mutex.  A function is said to be async-safe if it can be called from
       a signal handler.  The only Pthread functions that are async-safe
       are: pthreadmutextrylock(), pthreadcondsignal(), and
       pthreadcondbroadcast().  If synchronization must be performed in
       signal handlers, it should be done using traditional Unix or Posix
       semaphores, as mutexes and condition functions are not async-safe.

       For these reasons, signal handlers should be avoided in multithreaded
       programs.  The recommended way to handle signals in a multithreaded
       program is to dedicate one or more threads to synchronously wait for
       signals using calls to sigwait().   Such calls return with the signal
       number caught instead of executing signal handlers; thus upon return,
       any Pthread function can be executed.  The proper setup for using
       sigwait() is as follows.   Firstly, have the main thread block all
       signals during program initialization.  Because the blocked mask is
       inherited across pthreadcreate(), all created threads will inherit
       the all-blocked mask.  Secondly, have the main thread create one or
       more threads dedicated to handling signals.  Each of these threads
       will call sigwait() to synchronously wait for the signals for which
       it is responsible.  Any signals directed to the process are
       guaranteed to be delivered to these special threads because all
       threads in the process have all signals blocked.

       Finally, just because signals can be used safely does not imply that
       they should be used at all.  Thread creation is orders of magnitude
       faster than signal handling.  Realtime applications should, whenever
       possible, use threads instead of signals for asynchronous event
       creation.

   Thread Cancellation
       The Pthread cancellation mechanism allows an application to cleanly
       abort another thread in an asynchronous fashion.  Each thread can
       control whether or not it will accept cancellation and where it will
       accept cancellation.  By default, threads only accept cancellation at
       certain cancellation (interruption) points.  In general, a
       cancellation point is any standard function call where a thread could
       block for an indefinite period of time; this includes, but is not
       limited to, all system calls that can return EINTR.  In addition,
       each thread can push one more cleanup handlers onto a stack of
       handlers;  when a thread is cancelled, it will implicitly pop these
       handlers in reverse order and execute them.  Cleanup handlers can
       thus be used to release critical resources held by a canceled thread.

       Thread cancellation functions are:

       pthreadcancel               Cancel a thread
       pthreadsetintr              Enable or disable cancellation
       pthreadsetintrtype          Allow controlled or asynchronous
                                    cancellation
       pthreadtestintr             Create an explicit cancellation point
       pthreadcleanuppush         Push a cleanup handler
       pthreadcleanuppop          Pop a cleanup handler

   Synchronization Primitives
       Pthreads provide synchronization primitives in the form of mutexes
       and condition variables.  Mutexes allow applications to "lock" data
       that are write-shared by multiple threads.  Conditions allow
       applications to arbitrarily suspend and wake up threads.  Mutexes and
       conditions are typically used together to implement more complex
       synchronization constructs.  Moreover, mutexes and conditions can be
       configured for use among multiple processes that are using shared
       memory.

       Mutex functions are:

       pthreadmutexinit                 Initialize a mutex
       pthreadmutexdestroy              Destroy a mutex
       pthreadmutexlock                 Acquire a mutex lock
       pthreadmutextrylock              Acquire a mutex lock without
                                          waiting
       pthreadmutexunlock               Release a mutex lock

       Condition functions are:


       pthreadcondinit                  Initialize a condition

       pthreadconddestroy               Destroy a condition

       pthreadcondwait                  Wait for a condition

       pthreadcondtimedwait             Wait for a condition or timeout

       pthreadcondsignal                Wakeup at least one waiting thread

       pthreadcondbroadcast             Wakeup all waiting threads

       Mutexes and conditions also have attributes objects that can be used
       to initialize them with non-default properties.  In particular, the
       DG/UX system supports the process-shared attribute, which allows
       mutexes and conditions to be used by multiple processes.

       Mutex attribute functions are:

       pthreadmutexattrinit             Initialize default attributes
                                          object for a mutex
       pthreadmutexattrdestroy          Destroy attributes object for a
                                          mutex
       pthreadmutexattrsetpshared       Set process-shared attribute for a
                                          mutex
       pthreadmutexattrgetpshared       Get process-shared attribute for a
                                          mutex

       Condition attribute functions are:

       pthreadcondattrinit              Initialize default attributes
                                          object for a condition
       pthreadcondattrdestroy           Destroy attributes object for a
                                          condition
       pthreadcondattrsetpshared        Set condition's process-shared
                                          attribute
       pthreadcondattrgetpshared        Get condition's process-shared
                                          attribute

       The following miscellaneous function can be used to synchronize the
       initialization of a dynamically initialized package:

       pthreadonce                       Initialize a package dynamically

   Reentrant Functions
       Applications which call C library functions from threads should only
       call those library functions which are known to be reentrant.  For a
       list of reentrant functions and guidelines for their use, see
       reentrant(3).

   Debugging Threads Under DG/UX
       Threaded programs can be easily debugged using features of Data
       General's MXDB debugger.  The following MXDB commands are related to
       thread debugging:

       thread-status                      View the status of all threads
       focus                              Focus to a particular thread
       mutex-status                       Interrogate a mutex
       cond-status                        Interrogate a condition variable

       Note that, breakpoints on Pthread functions must be prefixed by the
       draft number.  For example, for draft 6, a breakpoint should be set
       at d6pthreadcreate instead of pthreadcreate.  These prefixes
       allow DG/UX to provide peaceful coexistence of multiple drafts in
       future releases.

   Thread Scheduling
       Thread attributes objects can also be used to set the scheduling
       attributes of newly created threads, or to set or retrieve the
       scheduling attributes of existing threads.

       Scheduling attribute functions are:

       pthreadattrsetscope                   Set the contention scope
                                               attribute
       pthreadattrgetscope                   Get the contention scope
                                               attribute
       pthreadattrsetinheritsched            Set the inherit-scheduling
                                               attribute
       pthreadattrgetinheritsched            Get the inherit-scheduling
                                               attribute
       pthreadattrsetsched                   Set the scheduling policy
                                               attribute
       pthreadattrgetsched                   Get the scheduling policy
                                               attribute
       pthreadattrsetprio                    Set the scheduling priority
                                               attribute
       pthreadattrgetprio                    Get the scheduling priority
                                               attribute
       pthreadsetschedattr                    Change the scheduling
                                               attributes of an existing
                                               thread
       pthreadgetschedattr                    Retrieve the scheduling
                                               attributes of an existing
                                               thread

       In addition, the pthreadyield() function causes the calling thread
       to yield to other threads of equal or better priority.

   DG/UX Thread Groups
       DG/UX provides extensions for thread groups, which allow sets of
       computationally-related threads to be scheduled together for purposes
       of CPU affinity.  Affinity is particularly important for large
       multithreaded processes running on machines with multiple CPUs.
       Thread groups can be used alone to give hints to the DG/UX system
       about the desired groupings of threads.  They can also be used with
       the hierarchical CPU affinity calls described in the next section to
       manually affine thread groups to sets of CPUs that reside close
       together on the underlying machine.

       Basic thread group functions are:

       dgpthreadgroupcreate                 Create an empty thread group
       dgpthreadgroupdestroy                Destroy a thread group
       dgpthreadgroupself                   Get the caller's thread group
                                               ID
       dgpthreadgroupequal                  Compare two thread group IDs
       dgpthreadgroupgetlwpgroupid       Translate a thread group ID
                                               to an LWP group ID
       dgpthreadgroupgettimes              Get the accumulated CPU times
                                               for a thread group

       Thread group attributes objects can be used to establish the
       scheduling attributes of newly created thread groups, and to change
       or retrieve the scheduling attributes of an existing thread group:

       dgpthreadgroupattrinit               Initialize a thread group
                                               attributes object
       dgpthreadgroupattrdestroy            Delete a thread group
                                               attributes object
       dgpthreadgroupattrsetinheritsched    Set the inherit-scheduling
                                               attribute
       dgpthreadgroupattrgetinheritsched    Get the inherit-scheduling
                                               attribute
       dgpthreadgroupattrsetsched           Set the scheduling policy
                                               attribute
       dgpthreadgroupattrgetsched           Get the scheduling policy
                                               attribute
       dgpthreadgroupattrsetprio            Set the scheduling priority
                                               attribute
       dgpthreadgroupattrgetprio            Get the scheduling priority
                                               attribute
       dgpthreadgroupsetschedattr           Change the scheduling
                                               attributes of an existing
                                               thread group
       dgpthreadgroupgetschedattr           Retrieve the scheduling
                                               attributes of an existing
                                               thread group

       Once a thread group has been created, a new thread can be created in
       that thread group by specifying the thread group ID as an attribute
       to the thread's creation.  This can be done in a well-isolated way
       using the following thread attributes object functions:

       dgpthreadattrsetgroup                Set the thread group ID
                                               attribute for created threads
       dgpthreadattrsetgroup                Get the thread group ID
                                               attribute for created threads

   DG/UX Hierarchical CPU Affinity
       DG/UX provides a hierarchical CPU affinity feature that can be used
       to explicitly affine thread groups (actually their LWP groups) to
       sets of CPUs backed by the same secondary cache or local memory.
       Hierarchical CPU affinity, when combined with thread groups, can
       significantly improve the performance of large multithreaded programs
       running on multiprocessor machines.  Refer to <sys/dgcpu.h> and
       related functions for more details on hierarchical CPU affinity.

       The following functions manipulate opaque sets of CPU IDs, which are
       used in subsequent CPU-related calls:

       dgcpuidsetinit                      Initialize a CPU ID set to
                                               empty
       dgcpuidsetdestroy                   Destroy a CPU ID set
       dgcpuidsetaddid                    Add a CPU ID to a CPU ID set
       dgcpuidsetremoveid                 Remove a CPU ID from a CPU ID
                                               set
       dgcpuidsetismember                 Test a CPU ID for inclusion
                                               in a CPU ID set
       dgcpuidsetassignset                Assign one CPU ID set to
                                               another
       dgcpuidsetaddset                   Compute the union of two CPU
                                               ID sets
       dgcpuidsetremoveset                Compute the difference
                                               between two CPU ID sets
       dgcpuidsethasmembers               Test a CPU ID set for
                                               inclusion in another

       The following functions can be used to query the CPU/cache/memory
       hierarchy of the underlying machine:

       dgcpuinfoinit                        Initialize a struct
                                               dgcpuinfo
       dgcpuinfodestroy                     Destroy a struct dgcpuinfo
       dgcpuinfo                             Retrieve the CPU/cache/memory
                                               hierarchy information for one
                                               CPU

       The following functions can be used to package up affinity attributes
       for affected LWP groups:

       dgcpuaffinityattrinit               Initialize an affinity
                                               attributes object
       dgcpuaffinityattrdestroy            Destroy an affinity
                                               attribtutes object
       dgcpuaffinityattrsetcpuidset     Set the allowed-CPU-ID-set
                                               attribute
       dgcpuaffinityattrgetcpuidset     Get the allowed-CPU-ID-set
                                               attribute
       dgcpuaffinityattrsetminimumlevel  Set the allowed-minimum-
                                               migration-level attribute
       dgcpuaffinityattrgetminimumlevel  Get the allowed-minimum-
                                               migration-level attribute

       The following functions can be used to set or retrieve affinity
       attributes for LWP groups:

       dgcpusetaffiniy                      Set affinity attributes for
                                               one or more LWP groups

       dgcpugetaffiniy                      Get affinity attributes for
                                               an LWP group

SEE ALSO
       reentrant(3), mxdb(1).


Licensed material--property of copyright holder(s)

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026