Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

reentrant(3)

mxdb(1)



threads(5)                     DG/UX 5.4R3.00                     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




Licensed material--property of copyright holder(s)                         1




threads(5)                     DG/UX 5.4R3.00                     threads(5)


         ⊕    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 -D_POSIX4A_DRAFT6_SOURCE -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



Licensed material--property of copyright holder(s)                         2




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       /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
                                       pthread_create to
                                       __d6_pthread_create, etc.
       <sys/_int__d6_pthread.h>        Included by <sys/pthread.h> and
                                       contains the actual Draft 6
                                       declarations of __d6_pthread_create,
                                       etc.
       <timers.h>                      Definition of struct timespec
       <sched.h>                       1004.4 realtime scheduling policies
       <sys/dg_lwp.h>                  DG/UX LWPs, LWP groups, and
                                       dg_lwp_info
       <sys/dg_cpu.h>                  DG/UX dg_cpu_info 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



Licensed material--property of copyright holder(s)                         3




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       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 pthread_mutex_lock() and to hide
       its interface under draft 6.  The macro aborts on error:

       #define zthread_mutex_lock(mutex_ptr)             \
       {                                                 \
       if (pthread_mutex_lock(mutex_ptr) != 0)           \
           {                                             \
           fprintf(stderr                                \
                   "pthread_mutex_lock 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 _POSIX_THREADS
       if (sysconf(_SC_THREADS)) == 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



Licensed material--property of copyright holder(s)                         4




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       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:

       pthread_create               Create a thread
       pthread_join                 Wait for a thread to terminate and clean
                                    it up
       pthread_exit                 Terminate a thread normally
       pthread_detach               Cause a thread to clean up for itself
                                    when it exits
       pthread_self                 Get the caller's thread ID
       pthread_equal                Compare two thread IDs

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

       dg_pthread_sleep             Sleep with nanosecond granularity
       dg_pthread_get_lwpid         Translate a thread ID to an underlying
                                    LWPID
       dg_lwp_info                  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:

       pthread_attr_init                  Initialize a thread attributes
                                          object
       pthread_attr_destroy               Delete a thread attributes object
       pthread_attr_setstacksize          Set stack size thread attribute
       pthread_attr_getstacksize          Retrieve stack size thread
                                          attribute
       pthread_attr_setdetachstate        Set detach state thread attribute
       pthread_attr_getdetachstate        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



Licensed material--property of copyright holder(s)                         5




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       names are called keys.

       Thread-specific data functions are:

       pthread_key_create           Create a new key (variable name)
       pthread_setspecific          Set the caller's per-thread value for a
                                    key
       pthread_getspecific          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



Licensed material--property of copyright holder(s)                         6




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       process terminates with a call to pthread_exit(), 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 pthread_kill() 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



Licensed material--property of copyright holder(s)                         7




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       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: pthread_mutex_trylock(), pthread_cond_signal(), and
       pthread_cond_broadcast().  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 pthread_create(), 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:

       pthread_cancel               Cancel a thread
       pthread_setintr              Enable or disable cancellation



Licensed material--property of copyright holder(s)                         8




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       pthread_setintrtype          Allow controlled or asynchronous
                                    cancellation
       pthread_testintr             Create an explicit cancellation point
       pthread_cleanup_push         Push a cleanup handler
       pthread_cleanup_pop          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:

       pthread_mutex_init                 Initialize a mutex
       pthread_mutex_destroy              Destroy a mutex
       pthread_mutex_lock                 Acquire a mutex lock
       pthread_mutex_trylock              Acquire a mutex lock without
                                          waiting
       pthread_mutex_unlock               Release a mutex lock

       Condition functions are:


       pthread_cond_init                  Initialize a condition

       pthread_cond_destroy               Destroy a condition

       pthread_cond_wait                  Wait for a condition

       pthread_cond_timedwait             Wait for a condition or timeout

       pthread_cond_signal                Wakeup at least one waiting thread

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

       pthread_mutexattr_init             Initialize default attributes
                                          object for a mutex
       pthread_mutexattr_destroy          Destroy attributes object for a
                                          mutex
       pthread_mutexattr_setpshared       Set process-shared attribute for a
                                          mutex
       pthread_mutexattr_getpshared       Get process-shared attribute for a



Licensed material--property of copyright holder(s)                         9




threads(5)                     DG/UX 5.4R3.00                     threads(5)


                                          mutex

       Condition attribute functions are:

       pthread_condattr_init              Initialize default attributes
                                          object for a condition
       pthread_condattr_destroy           Destroy attributes object for a
                                          condition
       pthread_condattr_setpshared        Set condition's process-shared
                                          attribute
       pthread_condattr_getpshared        Get condition's process-shared
                                          attribute

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

       pthread_once                       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 __d6_pthread_create instead of pthread_create.  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:

       pthread_attr_setscope                   Set the contention scope
                                               attribute
       pthread_attr_getscope                   Get the contention scope
                                               attribute
       pthread_attr_setinheritsched            Set the inherit-scheduling
                                               attribute
       pthread_attr_getinheritsched            Get the inherit-scheduling



Licensed material--property of copyright holder(s)                        10




threads(5)                     DG/UX 5.4R3.00                     threads(5)


                                               attribute
       pthread_attr_setsched                   Set the scheduling policy
                                               attribute
       pthread_attr_getsched                   Get the scheduling policy
                                               attribute
       pthread_attr_setprio                    Set the scheduling priority
                                               attribute
       pthread_attr_getprio                    Get the scheduling priority
                                               attribute
       pthread_setschedattr                    Change the scheduling
                                               attributes of an existing
                                               thread
       pthread_getschedattr                    Retrieve the scheduling
                                               attributes of an existing
                                               thread

       In addition, the pthread_yield() 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:

       dg_pthread_group_create                 Create an empty thread group
       dg_pthread_group_destroy                Destroy a thread group
       dg_pthread_group_self                   Get the caller's thread group
                                               ID
       dg_pthread_group_equal                  Compare two thread group IDs
       dg_pthread_group_get_lwp_group_id       Translate a thread group ID
                                               to an LWP group ID
       dg_pthread_group_get_times              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:

       dg_pthread_groupattr_init               Initialize a thread group
                                               attributes object
       dg_pthread_groupattr_destroy            Delete a thread group
                                               attributes object
       dg_pthread_groupattr_setinheritsched    Set the inherit-scheduling
                                               attribute
       dg_pthread_groupattr_getinheritsched    Get the inherit-scheduling
                                               attribute



Licensed material--property of copyright holder(s)                        11




threads(5)                     DG/UX 5.4R3.00                     threads(5)


       dg_pthread_groupattr_setsched           Set the scheduling policy
                                               attribute
       dg_pthread_groupattr_getsched           Get the scheduling policy
                                               attribute
       dg_pthread_groupattr_setprio            Set the scheduling priority
                                               attribute
       dg_pthread_groupattr_getprio            Get the scheduling priority
                                               attribute
       dg_pthread_group_setschedattr           Change the scheduling
                                               attributes of an existing
                                               thread group
       dg_pthread_group_getschedattr           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:

       dg_pthread_attr_setgroup                Set the thread group ID
                                               attribute for created threads
       dg_pthread_attr_setgroup                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/dg_cpu.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:

       dg_cpu_id_set_init                      Initialize a CPU ID set to
                                               empty
       dg_cpu_id_set_destroy                   Destroy a CPU ID set
       dg_cpu_id_set_add_id                    Add a CPU ID to a CPU ID set
       dg_cpu_id_set_remove_id                 Remove a CPU ID from a CPU ID
                                               set
       dg_cpu_id_set_is_member                 Test a CPU ID for inclusion
                                               in a CPU ID set
       dg_cpu_id_set_assign_set                Assign one CPU ID set to
                                               another
       dg_cpu_id_set_add_set                   Compute the union of two CPU
                                               ID sets
       dg_cpu_id_set_remove_set                Compute the difference
                                               between two CPU ID sets
       dg_cpu_id_set_has_members               Test a CPU ID set for
                                               inclusion in another




Licensed material--property of copyright holder(s)                        12




threads(5)                     DG/UX 5.4R3.00                     threads(5)


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

       dg_cpu_info_init                        Initialize a struct
                                               dg_cpu_info
       dg_cpu_info_destroy                     Destroy a struct dg_cpu_info
       dg_cpu_info                             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:

       dg_cpu_affinity_attr_init               Initialize an affinity
                                               attributes object
       dg_cpu_affinity_attr_destroy            Destroy an affinity
                                               attribtutes object
       dg_cpu_affinity_attr_set_cpu_id_set     Set the allowed-CPU-ID-set
                                               attribute
       dg_cpu_affinity_attr_get_cpu_id_set     Get the allowed-CPU-ID-set
                                               attribute
       dg_cpu_affinity_attr_set_minimum_level  Set the allowed-minimum-
                                               migration-level attribute
       dg_cpu_affinity_attr_get_minimum_level  Get the allowed-minimum-
                                               migration-level attribute

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

       dg_cpu_set_affiniy                      Set affinity attributes for
                                               one or more LWP groups

       dg_cpu_get_affiniy                      Get affinity attributes for
                                               an LWP group

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




















Licensed material--property of copyright holder(s)                        13


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