/sys$common/syshlp/HELPLIB.HLB  —  POSIX Threads
    The POSIX Threads Library is VSI's multithreading run-time
    library package. It offers access to library routines via several
    interfaces. The Threads Library offers two primary interfaces:

    o  The PTHREAD multithreading interface is VSI's implementation
       of the IEEE POSIX 1003.1-1996 standard. Use this interface to
       build portable, multithreaded applications.

    o  The proprietary TIS interface offers routines that provide
       "thread-independent services." These routines allow a program
       to perform (or a library to offer) thread-safe processing that
       requires synchronization, but without requiring the use of
       threads.

    A thread is a single, sequential flow of control within a
    program. Use threads to improve a program's performance-that
    is, its throughput, computational speed, responsiveness, or some
    combination. Multiple threads are useful in a multiprocessor
    system, where a program's threads can run concurrently on
    separate processors. On single-processor systems, multiple
    threads can also improve a program's performance by permitting
    the overlap of input, output, or other slow operations with
    computational operations. For more information see the Guide
    to the POSIX Threads Library documentation.

1  –  PTHREAD routines

    Routines that comprise the multithreading pthread interface are
    based on the IEEE POSIX 1003.1-1996 standard. The global errno
    variable is not used by these routines. To indicate errors,
    the PTHREAD routines return integer values indicating the type
    of error. Routine names ending with the _np suffix denote that
    the routine is not portable; that is, the routine might not be
    available in implementations of POSIX 1003.1-1996 other than
    the Threads Library. See the Guide to the POSIX Threads Library
    documentation for more information.

1.1  –  pthread_attr_destroy

    Destroys a thread attributes object.

1.1.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_destroy (
                pthread_attr_t   *attr);

1.1.2  –  Arguments

 attr

    Thread attributes object to be destroyed.

1.1.3  –  Description

    This routine destroys a thread attributes object. Call this
    routine when a thread attributes object will no longer be
    referenced.

    Threads that were created using this thread attributes object are
    not affected by the destruction of the thread attributes object.

    The results of calling this routine are unpredictable if
    the value specified by the attr argument refers to a thread
    attributes object that does not exist.

1.1.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.1.5  –  Associated Routines

       pthread_attr_init()
       pthread_create()

1.2  –  pthread_attr_getdetachstate

    Obtains the detachstate attribute of the specified thread
    attributes object.

1.2.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getdetachstate (
                const pthread_attr_t   *attr,
                int   *detachstate);

1.2.2  –  Arguments

 attr

    Thread attributes object whose detachstate attribute is obtained.

 detachstate

    Receives the value of the detachstate attribute.

1.2.3  –  Description

    This routine obtains the detachstate attribute of a thread
    attributes object. This attribute specifies whether threads
    created using the specified thread attributes object are created
    in a detached state.

    On successful completion, this routine returns a zero and the
    detachstate attribute is set in detachstate. A value of PTHREAD_
    CREATE_JOINABLE indicates the thread is not detached, and a value
    of PTHREAD_CREATE_DETACHED indicates the thread is detached.

    See the pthread_attr_setdetachstate() description for information
    about the detachstate attribute.

1.2.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr does not refer to an
                existing thread attributes object.

1.2.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_setdetachstate()

1.3  –  pthread_attr_getguardsize

    Obtains the guardsize attribute of the specified thread
    attributes object.

1.3.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getguardsize (
                const pthread_attr_t   *attr,
                size_t   *guardsize);

1.3.2  –  Arguments

 attr

    Address of the thread attributes object whose guardsize attribute
    is obtained.

 guardsize

    Receives the value of the guardsize attribute of the thread
    attributes object specified by attr.

1.3.3  –  Description

    This routine obtains the value of the guardsize attribute of
    the thread attributes object specified in the attr argument and
    stores it in the location specified by the guardsize argument.
    The specified attributes object must already be initialized at
    the time this routine is called.

    When creating a thread, use a thread attributes object to specify
    nondefault values for thread attributes. The guardsize attribute
    of a thread attributes object specifies the minimum size (in
    bytes) of the guard area for the stack of a new thread.

    A guard area can help a multithreaded program detect the overflow
    of a thread's stack. A guard area is a region of no-access memory
    that the Threads Library allocates at the overflow end of the
    thread's stack. When any thread attempts to access a memory
    location within this region, a memory addressing violation
    occurs.

    Note that the value of the guardsize attribute of a particular
    thread attributes object does not necessarily correspond to the
    actual size of the guard area of any existing thread in your
    multithreaded program.

1.3.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr does not refer to an
                existing thread attributes object.

1.3.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_setguardsize()
       pthread_attr_setstacksize()
       pthread_create()

1.4  –  pthread_attr_getinheritsched

    Obtains the inherit scheduling attribute of the specified thread
    attributes object.

1.4.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getinheritsched (
                const pthread_attr_t   *attr,
                int   *inheritsched);

1.4.2  –  Arguments

 attr

    Thread attributes object whose inherit scheduling attribute is
    obtained.

 inheritsched

    Receives the value of the inherit scheduling attribute. Refer to
    the description of the pthread_attr_setinheritsched() function
    for valid values.

1.4.3  –  Description

    This routine obtains the value of the inherit scheduling
    attribute from the specified thread attributes object. The
    inherit scheduling attribute specifies whether threads created
    using the attributes object inherit the scheduling attributes of
    the creating thread, or use the scheduling attributes stored in
    the attributes object that is passed to pthread_create().

1.4.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.4.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_setinheritsched()
       pthread_create()

1.5  –  pthread_attr_getname_np

    Obtains the object name attribute from a thread attributes
    object.

1.5.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getname_np (
             const pthread_attr_t   *attr,
             char   *name,
             size_t   len,
             void   **mbz);

1.5.2  –  Arguments

 attr

    Address of the thread attributes object whose object name
    attribute is to be obtained.

 name

    Location to store the obtained object name.

 len

    Length in bytes of buffer at the location specified by name.

 mbz

    Reserved for future use. The value must be zero (0).

1.5.3  –  Description

    This routine copies the object name attribute from the thread
    attributes object specified by the attr argument to the buffer
    at the location specified by the name argument. Before calling
    this routine, your program must allocate the buffer indicated by
    name. A new thread created using the thread attributes object is
    initialized with the object name that was set in that attributes
    object.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    If the specified thread attributes object has not been previously
    set with an object name, this routine copies a C language null
    string into the buffer at location name.

    This routine contrasts with pthread_getname_np(), which obtains
    the object name from the thread object for an existing thread.

1.5.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.5.5  –  Associated Routines

       pthread_getname_np()
       pthread_attr_setname_np()
       pthread_setname_np()

1.6  –  pthread_attr_getschedparam

    Obtains the scheduling parameters for an attribute of the
    specified thread attributes object.

1.6.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getschedparam (
                const pthread_attr_t   *attr,
                struct sched_param   *param);

1.6.2  –  Arguments

 attr

    Thread attributes object of the scheduling policy attribute whose
    parameters are obtained.

 param

    Receives the values of scheduling parameters for the scheduling
    policy attribute of the attributes object specified by the
    attr argument. Refer to the description of the pthread_attr_
    setschedparam() routine for valid parameters and their values.

1.6.3  –  Description

    This routine obtains the scheduling parameters associated
    with the scheduling policy attribute of the specified thread
    attributes object.

1.6.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.6.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_setschedparam()
       pthread_create()

1.7  –  pthread_attr_getschedpolicy

    Obtains the scheduling policy attribute of the specified thread
    attributes object.

1.7.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getschedpolicy (
                const pthread_attr_t   *attr,
                int   *policy);

1.7.2  –  Arguments

 attr

    Thread attributes object whose scheduling policy attribute is
    obtained.

 policy

    Receives the value of the scheduling policy attribute. Refer to
    the description of the pthread_attr_setschedpolicy() routine for
    valid values.

1.7.3  –  Description

    This routine obtains the value of the scheduling policy attribute
    of the specified thread attributes object. The scheduling policy
    attribute defines the scheduling policy for threads created using
    the attributes object.

1.7.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.7.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_setschedpolicy()
       pthread_create()

1.8  –  pthread_attr_getscope

    Obtains the contention scope attribute of the specified thread
    attributes object.

1.8.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getscope (
                const pthread_attr_t   *attr,
                int   *scope);

1.8.2  –  Arguments

 attr

    Address of the thread attributes object whose contention scope
    attribute is obtained.

 scope

    Receives the value of the contention scope attribute of the
    thread attributes object specified by attr.

1.8.3  –  Description

    This routine obtains the value of the contention scope attribute
    of the thread attributes object specified in the attr argument
    and stores it in the location specified by the scope argument.
    The specified attributes object must already be initialized at
    the time this routine is called.

    The contention scope attribute specifies the set of threads
    with which a thread must compete for processing resources. The
    contention scope attribute specifies whether the new thread
    competes for processing resources only with other threads in its
    own process, called process contention scope, or with all threads
    on the system, called system contention scope.

    The Threads Library selects at most one thread to execute on
    each processor at any point in time. The Threads Library resolves
    the contention based on each thread's scheduling attributes (for
    example, priority) and scheduling policy (for example, round-
    robin).

    A thread created using a thread attributes object whose
    contention scope attribute is set to PTHREAD_SCOPE_PROCESS
    contends for processing resources with other threads within its
    own process that also were created with PTHREAD_SCOPE_PROCESS.
    It is unspecified how such threads are scheduled relative to
    threads in other processes or threads in the same process that
    were created with PTHREAD_SCOPE_SYSTEM contention scope.

    A thread created using a thread attributes object whose
    contention scope attribute is set to PTHREAD_SCOPE_SYSTEM
    contends for processing resources with other threads in any
    process that also were created with PTHREAD_SCOPE_SYSTEM.

    Note that the value of the contention scope attribute of a
    particular thread attributes object does not necessarily
    correspond to the actual scheduling contention scope of any
    existing thread in your multithreaded program.

1.8.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.
    [ENOSYS]    This routine is not supported by the implementation.

1.8.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_setscope()

1.9  –  pthread_attr_getstackaddr

    Obtains the stack address attribute of the specified thread
    attributes object.

1.9.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getstackaddr (
                const pthread_attr_t   *attr,
                void   **stackaddr);

1.9.2  –  Arguments

 attr

    Address of the thread attributes object whose stack address
    attribute is obtained.

 stackaddr

    Receives the value of the stack address attribute of the thread
    attributes object specified by attr.

1.9.3  –  Description

    This routine obtains the value of the stack address attribute of
    the thread attributes object specified in the attr argument and
    stores it in the location specified by the stackaddr argument.
    The specified attributes object must already be initialized when
    this routine is called.

    The stack address attribute of a thread attributes object points
    to the origin of the stack for a new thread.

    Note that the value of the stack address attribute of a
    particular thread attributes object does not necessarily
    correspond to the actual stack origin of any existing thread
    in your multithreaded program.

1.9.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.9.5  –  Associated Routines

       pthread_attr_getguardsize()
       pthread_attr_getstacksize()
       pthread_attr_init()
       pthread_attr_setguardsize()
       pthread_attr_setstackaddr()
       pthread_attr_setstacksize()
       pthread_create()

1.10  –  pthread_attr_getstackaddr_np

    Obtains the stack address attribute of the specified thread
    attributes object.

1.10.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getstackaddr (
                const pthread_attr_t   *attr,
                void   **stackaddr,
                size_t   *size);

1.10.2  –  Arguments

 attr

    Address of the thread attributes object whose stack address
    attribute is obtained.

 stackaddr

    Receives the address of the stack region of the thread attributes
    object specified by attr.

 size

    The size of the stack region in bytes.

1.10.3  –  Description

    This routine obtains the value of the stack address attribute of
    the thread attributes object specified in the attr argument and
    stores it in the location specified by the stackaddr argument.
    The specified attributes object must already be initialized when
    this routine is called.

    The stack address attribute of a thread attributes object points
    to the origin of the stack for a new thread.

    Unlike pthread_attr_getstackaddr(), this routine is a much more
    reliable portable interface. With the POSIX standard pthread_
    attr_getstackaddr(), a stack is specified using a single,
    undefined, address. An implementation of the standard can only
    assume that the specified value represents the value to which the
    thread's stack pointer should be set when beginning execution.
    However, this requires the application to know how the machine
    uses the stack. For example, a stack may "grow" either up (to
    higher addresses) or down (to lower addresses), and may be
    decreased (or increased) either before or after storing a new
    value.

    The Threads Library provides an alternative interface with
    pthread_attr_getstackaddr_np(). Instead of returning a stack
    address, it returns the base (lowest) address and the size.

1.10.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.10.5  –  Associated Routines

       pthread_attr_setstackaddr_np()

1.11  –  pthread_attr_getstacksize

    Obtains the stacksize attribute of the specified thread
    attributes object.

1.11.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_getstacksize (
             const pthread_attr_t   *attr,
             size_t   *stacksize);

1.11.2  –  Arguments

 attr

    Thread attributes object whose stacksize attribute is obtained.

 stacksize

    Receives the value for the stacksize attribute of the thread
    attributes object specified by the attr argument.

1.11.3  –  Description

    This routine obtains the stacksize attribute of the thread
    attributes object specified in the attr argument.

1.11.4  –  Return Values

    On successful completion, this routine returns a zero (0) and
    the stacksize value in bytes in the location specified in the
    stacksize argument.

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid stack
                attributes object.

1.11.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_setstacksize()
       pthread_create()

1.12  –  pthread_attr_init

    Initializes a thread attributes object.

1.12.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_init (
             pthread_attr_t   *attr);

1.12.2  –  Arguments

 attr

    Address of a thread attributes object to be initialized.

1.12.3  –  Description

    This routine initializes the thread attributes object specified
    by the attr argument with a set of default attribute values. A
    thread attributes object is used to specify the attributes of
    one or more threads when they are created. The attributes object
    created by this routine is used only in calls to the pthread_
    create() routine.

    The following routines change individual attributes of an
    initialized thread attributes object:

       pthread_attr_setdetachstate()
       pthread_attr_setguardsize()
       pthread_attr_setinheritsched()
       pthread_attr_setschedparam()
       pthread_attr_setschedpolicy()
       pthread_attr_setscope()
       pthread_attr_setstackaddr()
       pthread_attr_setstacksize()

    The attributes of the thread attributes object are initialized to
    default values. The default value of each attribute is discussed
    in the reference description for each routine previously listed.

    When a thread attributes object is used to create a thread,
    the object's attribute values determine the characteristics
    of the new thread. Thus, attributes objects act as additional
    arguments to thread creation. Changing the attributes of a
    thread attributes object does not affect any threads that were
    previously created using that attributes object.

    You can use the same thread attributes object in successive calls
    to pthread_create(), from any thread. (However, you cannot use
    the same value of the stack address attribute to create multiple
    threads that might run concurrently; threads cannot share a
    stack.) If more than one thread might change the attributes in
    a shared attributes object, your program must use a mutex to
    protect the integrity of the attributes object's contents.

    When you set the scheduling policy or scheduling parameters,
    or both, in a thread attributes object, you must disable
    scheduling inheritance if you want the scheduling attributes
    you set to be used at thread creation. To disable scheduling
    inheritance, before creating the new thread use the pthread_attr_
    setinheritsched() routine to specify the value PTHREAD_EXPLICIT_
    SCHED for the inherit argument.

1.12.4  –  Return Values

    If an error condition occurs, the thread attributes object cannot
    be used, and this routine returns an integer value indicating the
    type of error. Possible return values are as follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.
    [ENOMEM]    Insufficient memory to initialize the thread
                attributes object.

1.12.5  –  Associated Routines

       pthread_attr_destroy()
       pthread_attr_setdetachstate()
       pthread_attr_setguardsize()
       pthread_attr_setinheritsched()
       pthread_attr_setschedparam()
       pthread_attr_setschedpolicy()
       pthread_attr_setscope()
       pthread_attr_setstackaddr()
       pthread_attr_setstacksize()
       pthread_create()

1.13  –  pthread_attr_setdetachstate

    Changes the detachstate attribute in the specified thread
    attributes object.

1.13.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setdetachstate (
                pthread_attr_t   *attr,
                int   detachstate);

1.13.2  –  Arguments

 attr

    Thread attributes object to be modified.

 detachstate

    New value for the detachstate attribute. Valid values are as
    follows:

    PTHREAD_CREATE_       This is the default value. Threads are
    JOINABLE              created in "undetached" state.
    PTHREAD_CREATE_       The created thread is detached immediately,
    DETACHED              before it begins running.

1.13.3  –  Description

    This routine changes the detachstate attribute in the thread
    attributes object specified by the attr argument. The detachstate
    attribute specifies whether the thread created using the
    specified thread attributes object is created in a detached state
    or not. A value of PTHREAD_CREATE_JOINABLE indicates the thread
    is not detached, and a value of PTHREAD_CREATE_DETACHED indicates
    the thread is detached. PTHREAD_CREATE_JOINABLE is the default
    value.

    Your program cannot use the thread handle (the value of type
    pthread_t returned by the pthread_create() routine) of a detached
    thread because the thread might terminate asynchronously, and a
    detached thread ID is not valid after termination. In particular,
    it is an error to attempt to detach or join with a detached
    thread.

    When a thread that has not been detached completes execution,
    the Threads Library retains the state of that thread to allow
    another thread to join with it. If the thread is detached
    before it completes execution, the Threads Library is free to
    immediately reclaim the thread's storage and resources. Failing
    to detach threads that have completed execution can result in
    wasting resources, so threads should be detached as soon as
    the program is done with them. If there is no need to use the
    thread's handle after creation, such as to join with it, create
    the thread initially detached.

1.13.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by the attr argument is not a
                valid threads attribute object or the detachstate
                argument is invalid.

1.13.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_getdetachstate()
       pthread_create()
       pthread_join()

1.14  –  pthread_attr_setguardsize

    Changes the guardsize attribute of the specified thread
    attributes object.

1.14.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setguardsize (
             pthread_attr_t   *attr,
             size_t   guardsize);

1.14.2  –  Arguments

 attr

    Address of the thread attributes object whose guardsize attribute
    is to be modified.

 guardsize

    New value for the guardsize attribute of the thread attributes
    object specified by attr.

1.14.3  –  Description

    This routine uses the value specified in the guardsize argument
    to set the guardsize attribute of the thread attributes object
    specified in the attr argument.

    When creating a thread, use a thread attributes object to specify
    nondefault values for thread attributes. The guardsize attribute
    of a thread attributes object specifies the minimum size (in
    bytes) of the guard area for the stack of a new thread.

    A guard area, with its associated overflow warning area, can
    help a multithreaded program detect overflow of a thread's
    stack. A guard area is a region of no-access memory that the
    Threads Library allocates at the overflow end of the thread's
    stack, following the thread's overflow warning area. If the
    thread attempts to write in the overflow warning area, a stack
    overflow exception occurs. Your program can catch this exception
    and continue processing as long as the thread does not attempt
    to write in the guard area. When any thread attempts to access
    a memory location within the guard area, a memory addressing
    violation occurs without the possibility of recovery.

    A new thread can be created with a default guardsize attribute
    value. This value is platform dependent, but will always be
    at least one "hardware protection unit" (that is, at least one
    page). For more information, see this guide's platform-specific
    appendixes.

    After this routine is called, due to platform-specific factors
    the Threads Library might reserve a larger guard area for the
    new thread than was specified in the guardsize argument. See this
    guide's platform-specific appendixes for more information.

    The Threads Library allows your program to specify the size of a
    thread stack's guard area for two reasons:

    o  When a thread allocates large data structures on its stack, a
       guard area with a size greater than the default size might be
       required to detect stack overflow.

    o  Overflow protection of a thread's stack can potentially waste
       system resources, such as for an application that creates a
       large number of threads that will never overflow their stacks.
       Your multithreaded program can conserve system resources
       by "turning off" a thread's stack guard area-that is, by
       specifying a guardsize attribute of zero.

    If a thread is created using a thread attributes object whose
    stackaddr attribute is set (using the pthread_attr_setstackaddr()
    routine), this routine ignores the object's guardsize attribute
    and provides no thread stack overflow warning or guard area for
    the new thread.

1.14.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The argument attr is not a valid thread attributes
                object, or the argument guardsize contains an invalid
                value.

1.14.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_getguardsize()
       pthread_attr_setstacksize()
       pthread_create()

1.15  –  pthread_attr_setinheritsched

    Changes the inherit scheduling attribute of the specified thread
    attributes object.

1.15.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setinheritsched (
             pthread_attr_t   *attr,
             int   inheritsched);

1.15.2  –  Arguments

 attr

    Thread attributes object whose inherit scheduling attribute is to
    be modified.

 inheritsched

    New value for the inherit scheduling attribute. Valid values are
    as follows:

       PTHREAD_INHERIT_      The created thread inherits the
       SCHED                 scheduling policy and associated
                             scheduling attributes of the thread
                             calling pthread_create(). Any scheduling
                             attributes in the attributes object
                             specified by the pthread_create() attr
                             argument are ignored during thread
                             creation. This is the default value.
       PTHREAD_EXPLICIT_     The scheduling policy and associated
       SCHED                 scheduling attributes of the created
                             thread are set to the corresponding
                             values from the attribute object
                             specified by the pthread_create()  attr
                             argument.

1.15.3  –  Description

    This routine changes the inherit scheduling attribute of the
    thread attributes object specified by the attr argument. The
    inherit scheduling attribute specifies whether a thread created
    using the specified attributes object inherits the scheduling
    attributes of the creating thread, or uses the scheduling
    attributes stored in the attributes object specified by the
    pthread_create() attr argument.

    The first thread in an application has a scheduling policy of
    SCHED_OTHER. See the pthread_attr_setschedparam() and pthread_
    attr_setschedpolicy() routines for more information on valid
    priority values and valid scheduling policy values.

    Inheriting scheduling attributes (instead of using the scheduling
    attributes stored in the attributes object) is useful when a
    thread is creating several helper threads-that is, threads
    that are intended to work closely with the creating thread to
    cooperatively solve the same problem. For example, inherited
    scheduling attributes ensure that helper threads created in
    a sort routine execute with the same priority as the calling
    thread.

1.15.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by the attr argument is not a
                valid thread attributes object, or the inheritsched
                argument contains an invalid value.
    [ENOTSUP]   An attempt was made to set the attribute to an
                unsupported value.

1.15.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_getinheritsched()
       pthread_attr_setschedpolicy()
       pthread_attr_setschedparam()
       pthread_attr_setscope()
       pthread_create()

1.16  –  pthread_attr_setname_np

    Changes the object name attribute in a thread attributes object.

1.16.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setname_np (
             pthread_attr_t   *attr,
             const char   *name,
             void   *mbz);

1.16.2  –  Arguments

 attr

    Address of the thread attributes object whose object name
    attribute is to be changed.

 name

    Object name value to copy into the thread attributes object's
    object name attribute.

 mbz

    Reserved for future use. The value must be zero (0).

1.16.3  –  Description

    This routine changes the object name attribute in the thread
    attributes object specified by the attr argument to the value
    specified by the name argument. A new thread created using the
    thread attributes object is initialized with the object name that
    was set in that attributes object.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    This routine contrasts with pthread_setname_np(), which changes
    the object name in the thread object for an existing thread.

1.16.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object, or the length in characters of
                name exceeds 31.
    [ENOMEM]    Insufficient memory exists to create a copy of the
                object name string.

1.16.5  –  Associated Routines

       pthread_attr_getname_np()
       pthread_getname_np()
       pthread_setname_np()

1.17  –  pthread_attr_setschedparam

    Changes the values of the parameters associated with a scheduling
    policy of the specified thread attributes object.

1.17.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setschedparam (
             pthread_attr_t   *attr,
             const struct sched_param   *param);

1.17.2  –  Arguments

 attr

    Thread attributes object for the scheduling policy attribute
    whose parameters are to be set.

 param

    A structure containing new values for scheduling parameters
    associated with the scheduling policy attribute of the specified
    thread attributes object.

                                   NOTE

       The Threads Library provides only the sched_priority
       scheduling parameter. See below for information about this
       scheduling parameter.

1.17.3  –  Description

    This routine sets the scheduling parameters associated with
    the scheduling policy attribute of the thread attributes object
    specified by the attr argument.
    Scheduling Priority
    Use the sched_priority field of a sched_param structure to set
    a thread's execution priority. The effect of the scheduling
    priority you assign depends on the scheduling policy specified
    for the attributes object specified by the attr argument.

    By default, a created thread inherits the priority of the thread
    calling pthread_create(). To specify a priority using this
    routine, scheduling inheritance must be disabled at the time the
    thread is created. Before calling pthread_create(), call pthread_
    attr_setinheritsched() and specify the value PTHREAD_EXPLICIT_
    SCHED for the inherit argument.

    An application specifies priority only to express the urgency
    of executing the thread relative to other threads. Do not use
    priority to control mutual exclusion when you are accessing
    shared data. With a sufficient number of processors present, all
    ready threads, regardless of priority, execute simultaneously.
    Even on a uniprocessor, a lower priority thread could either
    execute before or be interleaved with a higher priority thread,
    for example due to page fault behavior. See <REFERENCE>(intro_
    threads_chap) and <REFERENCE>(threads_concepts_chap) for more
    information.

    Valid values of the sched_priority scheduling parameter depend on
    the chosen scheduling policy. Use the POSIX routines sched_get_
    priority_min() or sched_get_priority_max()  to determine the low
    and high limits of each policy.

    Additionally, the Threads Library provides nonportable priority
    range constants, as follows:

    Policy          Low            High

    SCHED_FIFO      PRI_FIFO_MIN   PRI_FIFO_MAX
    SCHED_RR        PRI_RR_MIN     PRI_RR_MAX
    SCHED_OTHER     PRI_OTHER_MIN  PRI_OTHER_MAX
    SCHED_FG_NP     PRI_FG_MIN_NP  PRI_FG_MAX_NP
    SCHED_BG_NP     PRI_BG_MIN_NP  PRI_BG_MAX_NP

    The default priority varies by platform. On Tru64 UNIX, the
    default is 19 (that is, the POSIX priority of a normal timeshare
    process). On other platforms, the default priority is the
    midpoint between PRI_FG_MIN_NP and PRI_FG_MAX_NP.

1.17.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object, or the value specified by param is
                invalid.
    [ENOTSUP]   An attempt was made to set the attribute to an
                unsupported value.

1.17.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_getschedparam()
       pthread_attr_setinheritsched()
       pthread_attr_setschedpolicy()
       pthread_create()
       sched_yield()

1.18  –  pthread_attr_setschedpolicy

    Changes the scheduling policy attribute of the specified thread
    attributes object.

1.18.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setschedpolicy (
             pthread_attr_t   *attr,
             int   policy);

1.18.2  –  Arguments

 attr

    Thread attributes object to be modified.

 policy

    New value for the scheduling policy attribute. Valid values are
    as follows:

       SCHED_BG_NP
       SCHED_FG_NP (also known as SCHED_OTHER)
       SCHED_FIFO
       SCHED_RR

    SCHED_OTHER is the default value.

1.18.3  –  Description

    This routine sets the scheduling policy of a thread that is
    created using the attributes object specified by the attr
    argument. The default value of the scheduling attribute is SCHED_
    OTHER.

    By default, a created thread inherits the policy of the thread
    calling pthread_create(). To specify a policy using this routine,
    scheduling inheritance must be disabled at the time the thread
    is created. Before calling pthread_create(), call pthread_attr_
    setinheritsched() and specify the value PTHREAD_EXPLICIT_SCHED
    for the inherit argument.

    Preemption is caused by both scheduling and policy. Never attempt
    to use scheduling as a mechanism for synchronization.

1.18.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object, or the value specified by policy
                is invalid.

1.18.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_getschedpolicy()
       pthread_attr_setinheritsched()
       pthread_attr_setschedparam()
       pthread_create()

1.19  –  pthread_attr_setscope

    Sets the contention scope attribute of the specified thread
    attributes object.

1.19.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setscope (
                pthread_attr_t   *attr,
                int   scope);

1.19.2  –  Arguments

 attr

    Address of the thread attributes object whose contention scope
    attribute is to be modified.

 scope

    New value for the contention scope attribute of the thread
    attributes object specified by attr.

1.19.3  –  Description

    This routine uses the value specified in the scope argument
    to set the contention scope attribute of the thread attributes
    object specified in the attr argument.

    When creating a thread, use a thread attributes object to specify
    nondefault values for thread attributes. The contention scope
    attribute specifies the set of threads with which a thread must
    compete for processing resources. The contention scope attribute
    specifies whether the new thread competes for processing
    resources only with other threads in its own process, called
    process contention scope, or with all threads on the system,
    called system contention scope.

    The Threads Library selects at most one thread to execute on
    each processor at any point in time. The Threads Library resolves
    the contention based on each thread's scheduling attributes (for
    example, priority) and scheduling policy (for example, round-
    robin).

    A thread created using a thread attributes object whose
    contention scope attribute is set to PTHREAD_SCOPE_PROCESS
    contends for processing resources with other threads within its
    own process that also were created with PTHREAD_SCOPE_PROCESS. It
    is unspecified how such threads are scheduled relative to either
    threads in other processes or threads in the same process that
    were created with PTHREAD_SCOPE_SYSTEM contention scope.

    A thread created using a thread attributes object whose
    contention scope attribute is set to PTHREAD_SCOPE_SYSTEM
    contends for processing resources with other threads in any
    process that also were created with PTHREAD_SCOPE_SYSTEM.

    Note that the value of the contention scope attribute of a
    particular thread attributes object does not necessarily
    correspond to the actual scheduling contention scope of any
    existing thread in your multithreaded program.

1.19.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes value, or the value specified by scope is
                not valid.
    [ENOTSUP]   An attempt was made to set the attribute to an
                unsupported value.

1.19.5  –  Associated Routines

       pthread_attr_destroy()
       pthread_attr_init()
       pthread_attr_getscope()
       pthread_attr_setinheritsched()
       pthread_create()

1.20  –  pthread_attr_setstackaddr

    Changes the stack address attribute of the specified thread
    attributes object.

1.20.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setstackaddr (
             pthread_attr_t   *attr,
             void   *stackaddr);

1.20.2  –  Arguments

 attr

    Address of the thread attributes object whose stack address
    attribute is to be modified.

 stackaddr

    New value for the stack address attribute of the thread
    attributes object specified by attr.

1.20.3  –  Description

    This routine uses the value specified in the stackaddr argument
    to set the stack address attribute of the thread attributes
    object specified in the attr argument.

    When creating a thread, use a thread attributes object to specify
    nondefault values for thread attributes. The stack address
    attribute of a thread attributes object points to the origin
    of the stack for a new thread.

    The default value for the stack address attribute of an
    initialized thread attributes object is NULL.

                                   NOTE

       Correct use of this routine depends upon details of the
       target platform's stack architecture. Thus, this routine
       cannot be used in a portable manner.

       The size of the stack must be at least PTHREAD_STACK_MIN
       bytes (see the pthread.h header file). However, because the
       Threads Library must use a portion of this stack memory to
       begin thread execution and to maintain thread state, your
       program's "user thread code" cannot rely on using all of the
       stack memory allocated.

    For your program to calculate a value for the stackaddr
    attribute, note that:

    o  Your program must allocate the memory that will be used for
       the new thread's stack.

    o  On Tru64 UNIX, to create a new thread using a thread
       attributes object, the stackaddr attribute must be an address
       that points to the high-memory end of the memory region
       allocated for the stack. This address must point to the
       highest even-boundary quadword in the allocated memory region.

    Also note that:

    o  If you use the pthread_attr_setstackaddr() routine to set a
       thread attributes object's stack address attribute and use
       that attributes object to create a new thread, the Threads
       Library ignores the attributes object's guardsize attribute
       and provides no thread stack guard area or overflow warning
       area for the new thread.

    o  If you use the same thread attributes object to create more
       than one thread and each created thread uses a nondefault
       stack address, you must use the pthread_attr_setstackaddr()
       routine to set a unique stack address attribute value for each
       new thread created using that attributes object.

1.20.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.20.5  –  Associated Routines

       pthread_attr_getguardsize()
       pthread_attr_getstackaddr()
       pthread_attr_getstacksize()
       pthread_attr_init()
       pthread_attr_setguardsize()
       pthread_attr_setstacksize()
       pthread_create()

1.21  –  pthread_attr_setstackaddr_np

    Changes the stack address and size of the specified thread
    attributes object.

1.21.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setstackaddr_np (
             pthread_attr_t   *attr,
             void   *stackaddr,
             size_t   size);

1.21.2  –  Arguments

 attr

    Address of the thread attributes object whose stack address
    attribute is to be modified.

 stackaddr

    New value for the address of the stack region of the thread
    attributes object specified by attr.

 size

    The size of the stack region in bytes.

1.21.3  –  Description

    This routine uses the values specified in the stackaddr and size
    arguments to set the base stack address and size of the thread
    attributes object specified in the attr argument.

    When creating a thread, use a thread attributes object to specify
    nondefault values for thread attributes. The default value for
    the stack address attribute of an initialized thread attributes
    object is NULL.

    Unlike pthread_attr_setstackaddr(), this routine is a much more
    reliable portable interface. With the POSIX standard pthread_
    attr_setstackaddr(), a stack is specified using a single,
    undefined, address. An implementation of the standard can only
    assume that the specified value represents the value to which the
    thread's stack pointer should be set when beginning execution.
    However, this requires the application to know how the machine
    uses the stack. For example, a stack may "grow" either up (to
    higher addresses) or down (to lower addresses), and may be
    decreased (or increased) either before or after storing a new
    value.

    The Threads Library provides an alternative interface with
    pthread_attr_setstackaddr_np(). Instead of specifying a stack
    address, you specify the base (lowest) address and the size.

1.21.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object.

1.21.5  –  Associated Routines

       pthread_attr_getstackaddr_np()

1.22  –  pthread_attr_setstacksize

    Changes the stacksize attribute in the specified thread
    attributes object.

1.22.1  –  C Binding

    #include <pthread.h>

    int
    pthread_attr_setstacksize (
             pthread_attr_t   *attr,
             size_t   stacksize);

1.22.2  –  Arguments

 attr

    Threads attributes object to be modified.

 stacksize

    New value for the stacksize attribute of the thread attributes
    object specified by the attr argument. The stacksize argument
    must be greater than or equal to PTHREAD_STACK_MIN. PTHREAD_
    STACK_MIN specifies the minimum size (in bytes) of the stack
    needed for a thread.

1.22.3  –  Description

    This routine sets the stacksize attribute in the thread
    attributes object specified by the attr argument. Use this
    routine to adjust the size of the writable area of the stack
    for a new thread.

    The size of a thread's stack is fixed at the time of thread
    creation. On OpenVMS systems, only the initial thread can
    dynamically extend its stack. On Tru64 UNIX systems, very large
    stacks can be created, but only a few pages are committed.

    Many compilers do not check for stack overflow. Ensure that the
    new thread's stack is sufficient for the resources required by
    routines that are called from the thread.

1.22.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid thread
                attributes object, or the value specified by
                stacksize either is less than PTHREAD_STACK_MIN or
                exceeds a Threads Library-imposed limit.

1.22.5  –  Associated Routines

       pthread_attr_init()
       pthread_attr_getstacksize()
       pthread_create()

1.23  –  pthread_cancel

    Allows a thread to request a thread to terminate execution.

1.23.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cancel (
             pthread_t   thread);

1.23.2  –  Arguments

 thread

    Thread that will receive a cancelation request.

1.23.3  –  Description

    This routine sends a cancelation request to the specified target
    thread. A cancelation request is a mechanism by which a calling
    thread requests the target thread to terminate as quickly as
    possible. Issuing a cancelation request does not guarantee that
    the target thread will receive or handle the request.

    When the cancelation request is acted on, all active cleanup
    handler routines for the target thread are called. When the last
    cleanup handler returns, the thread-specific data destructor
    routines are called for each thread-specific data key with a
    destructor and for which the target thread has a non-NULL value.
    Finally, the target thread is terminated.

    Note that cancelation of the target thread runs asynchronously
    with respect to the calling thread's returning from pthread_
    cancel(). The target thread's cancelability state and type
    determine when or if the cancelation takes place, as follows:

    1. The target thread can delay cancelation during critical
       operations by setting its cancelability state to PTHREAD_
       CANCEL_DISABLE.

    2. Because of communication delays, the calling thread can only
       rely on the fact that a cancelation request will eventually
       become pending in the target thread (provided that the target
       thread does not terminate beforehand).

    3. The calling thread has no guarantee that a pending cancelation
       request will be delivered because delivery is controlled by
       the target thread.

    When a cancelation request is delivered to a thread, termination
    processing is similar to that for pthread_exit(). For more
    information about thread termination, see the Thread Termination
    section of pthread_create().

    This routine is preferred in implementing an Ada abort statement
    and any other language- or software-defined construct for
    requesting thread cancelation.

    The results of this routine are unpredictable if the value
    specified in thread refers to a thread that does not currently
    exist.

1.23.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The specified thread is invalid.
    [ESRCH]     The thread argument does not specify an existing
                thread.

1.23.5  –  Associated Routines

       pthread_cleanup_pop()
       pthread_cleanup_push()
       pthread_create()
       pthread_exit()
       pthread_join()
       pthread_setcancelstate()
       pthread_setcanceltype()
       pthread_testcancel()

1.24  –  pthread_cleanup_pop

    (Macro) Removes the cleanup handler routine from the calling
    thread's cleanup handler stack and optionally executes it.

1.24.1  –  C Binding

    #include <pthread.h>

    void
    pthread_cleanup_pop(
             int   execute);

1.24.2  –  Arguments

 execute

    Integer that specifies whether the cleanup handler routine
    specified in the matching call to pthread_cleanup_push() is
    executed. A nonzero value causes the cleanup handler routine
    to be executed.

1.24.3  –  Description

    This routine removes the cleanup handler routine established by
    the matching call to pthread_cleanup_push() from the calling
    thread's cleanup handler stack, then executes it if the value
    specified in this routine's execute argument is nonzero.

    A cleanup handler routine can be used to clean up from a block
    of code whether exited by normal completion, cancelation, or the
    raising (or reraising) of an exception. The routine is popped
    from the calling thread's cleanup handler stack and is called
    with the arg argument (see the description for pthread_cleanup_
    push()) when any of the following actions occur:

    o  The thread calls pthread_cleanup_pop() and specifies a nonzero
       value for the execute argument.

    o  The thread calls pthread_exit().

    o  The thread is canceled.

    o  An exception is raised and is caught when the Threads Library
       unwinds the calling thread's stack to the lexical scope of the
       pthread_cleanup_push() and pthread_cleanup_pop()  pair.

    This routine and pthread_cleanup_push() are implemented as
    macros and must appear as statements and in pairs within the
    same lexical scope. You can think of the pthread_cleanup_push()
    macro as expanding to a string whose first character is a left
    brace ({) and pthread_cleanup_pop() as expanding to a string
    containing the corresponding right brace (}). This routine and
    pthread_cleanup_push() are implemented as exceptions, and may not
    work in a C++ environment. (See <REFERENCE>(exceptions_chap) for
    more information.)

1.24.4  –  Return Values

    None

1.24.5  –  Associated Routines

       pthread_cancel()
       pthread_cleanup_push()
       pthread_create()
       pthread_exit()

1.25  –  pthread_cleanup_push

    (Macro) Establishes a cleanup handler routine to be executed when
    the thread exits or is canceled.

1.25.1  –  C Binding

    #include <phtread.h>

    void
    pthread_cleanup_push(
             void   (*routine)(void *),
             void   *arg);

1.25.2  –  Arguments

 routine

    Routine executed as the cleanup handler.

 arg

    Argument passed to the cleanup handler routine.

1.25.3  –  Description

    This routine pushes the specified routine onto the calling
    thread's cleanup handler stack. The cleanup handler routine is
    popped from the stack and called with the arg argument when any
    of the following actions occur:

    o  The thread calls pthread_cleanup_pop() and specifies a nonzero
       value for the execute argument.

    o  The thread calls pthread_exit().

    o  The thread is canceled.

    o  An exception is raised and is caught when the Threads Library
       unwinds the calling thread's stack to the lexical scope of the
       pthread_cleanup_push() and pthread_cleanup_pop()  pair.

    This routine and pthread_cleanup_pop() are implemented as macros
    and must appear as statements and in pairs within the same
    lexical scope. You can think of the pthread_cleanup_push() macro
    as expanding to a string whose first character is a left brace
    ({) and pthread_cleanup_pop() as expanding to a string containing
    the corresponding right brace (}). This routine and pthread_
    cleanup_pop() are implemented as exceptions, and may not work
    in a C++ environment. (See <REFERENCE>(exceptions_chap) for more
    information.)

1.25.4  –  Return Values

    None

1.25.5  –  Associated Routines

       pthread_cancel()
       pthread_cleanup_pop()
       pthread_create()
       pthread_exit()
       pthread_testcancel()

1.26  –  pthread_cond_broadcast

    Wakes all threads that are waiting on the specified condition
    variable.

1.26.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_broadcast (
             pthread_cond_t   *cond);

1.26.2  –  Arguments

 cond

    Condition variable upon which the threads (to be awakened) are
    waiting.

1.26.3  –  Description

    This routine unblocks all threads waiting on the specified
    condition variable cond. Calling this routine implies that data
    guarded by the associated mutex has changed, so that it might be
    possible for one or more waiting threads to proceed. The threads
    that are unblocked shall contend for the mutex according to their
    respective scheduling policies (if applicable).

    If only one of the threads waiting on a condition variable may be
    able to proceed, but one of those threads can proceed, then use
    pthread_cond_signal() instead.

    Whether the associated mutex is locked or unlocked, you can still
    call this routine. However, if predictable scheduling behavior is
    required, that mutex should then be locked by the thread calling
    the pthread_cond_broadcast() routine.

    If no threads are waiting on the specified condition variable,
    this routine takes no action. The broadcast does not propagate to
    the next condition variable wait.

1.26.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

1.26.5  –  Associated Routines

       pthread_cond_destroy()
       pthread_cond_init()
       pthread_cond_signal()
       pthread_cond_timedwait()
       pthread_cond_wait()

1.27  –  pthread_cond_destroy

    Destroys a condition variable.

1.27.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_destroy (
             pthread_cond_t   *cond);

1.27.2  –  Arguments

 cond

    Condition variable to be destroyed.

1.27.3  –  Description

    This routine destroys the condition variable specified by cond.
    This effectively uninitializes the condition variable. Call this
    routine when a condition variable will no longer be referenced.
    Destroying a condition variable allows the Threads Library to
    reclaim internal memory associated with the condition variable.

    It is safe to destroy an initialized condition variable upon
    which no threads are currently blocked. Attempting to destroy a
    condition variable upon which other threads are blocked results
    in unpredictable behavior.

    The results of this routine are unpredictable if the condition
    variable specified in cond either does not exist or is not
    initialized.

1.27.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.
    [EBUSY]     The object being referenced by cond is being
                referenced by another thread that is currently
                executing
                pthread_cond_wait()  or pthread_cond_timedwait() on
                the condition variable specified in cond.

1.27.5  –  Associated Routines

       pthread_cond_broadcast()
       pthread_cond_init()
       pthread_cond_signal()
       pthread_cond_timedwait()
       pthread_cond_wait()

1.28  –  pthread_cond_getname_np

    Obtains the object name from a condition variable object.

1.28.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_getname_np (
             pthread_cond_t   *cond,
             char   *name,
             size_t   len);

1.28.2  –  Arguments

 cond

    Address of the condition variable object whose object name is to
    be obtained.

 name

    Location to store the obtained object name.

 len

    Length in bytes of buffer at the location specified by name.

1.28.3  –  Description

    This routine copies the object name from the condition variable
    object specified by the cond argument to the buffer at the
    location specified by the name argument. Before calling this
    routine, your program must allocate the buffer indicated by name.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    If the specified condition variable object has not been
    previously set with an object name, this routine copies a C
    language null string into the buffer at location name.

1.28.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

1.28.5  –  Associated Routines

       pthread_cond_setname_np()

1.29  –  pthread_cond_init

    Initializes a condition variable.

1.29.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_init (
             pthread_cond_t   *cond,
             const pthread_condattr_t   *attr);

1.29.2  –  Arguments

 cond

    Condition variable to be initialized.

 attr

    Condition variable attributes object that defines the
    characteristics of the condition variable to be initialized.

1.29.3  –  Description

    This routine initializes the condition variable cond with
    attributes specified in the attr argument. If attr is NULL, the
    default condition variable attributes are used.

    A condition variable is a synchronization object used in
    conjunction with a mutex. A mutex controls access to data that
    is shared among threads; a condition variable allows threads to
    wait for that data to enter a defined state.

    Condition variables are not owned by a particular thread. Any
    associated storage is not automatically deallocated when the
    creating thread terminates.

    Use the macro PTHREAD_COND_INITIALIZER to initialize statically
    allocated condition variables to the default condition variable
    attributes. To invoke this macro, enter:

       pthread_cond_t condition = PTHREAD_COND_INITIALIZER

    When statically initialized, a condition variable should not also
    be initialized using pthread_cond_init(). Also, a statically
    initialized condition variable need not be destroyed using
    pthread_cond_destroy().

    Under certain circumstances it might be impossible to wait upon
    a statically initialized condition variable when the process
    virtual address space (or some other memory limit) is nearly
    exhausted. In such a case pthread_cond_wait() or pthread_cond_
    timedwait() can return [ENOMEM]. To avoid this possibility,
    initialize critical condition variables using pthread_cond_
    init().

1.29.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacks the necessary resources to
                initialize another condition variable, or

                The system-imposed limit on the total number of
                condition variables under execution by a single user
                is exceeded.
    [EBUSY]     The implementation has detected an attempt to
                reinitialize the object referenced by cond, a
                previously initialized, but not yet destroyed
                condition variable.
    [EINVAL]    The value specified by attr is not a valid attributes
                object.
    [ENOMEM]    Insufficient memory exists to initialize the
                condition variable.

1.29.5  –  Associated Routines

       pthread_cond_broadcast()
       pthread_cond_destroy()
       pthread_cond_signal()
       pthread_cond_timedwait()
       pthread_cond_wait()

1.30  –  pthread_cond_setname_np

    Changes the object name for a condition variable object.

1.30.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_setname_np (
             pthread_cond_t   *cond,
             const char   *name,
             void   *mbz);

1.30.2  –  Arguments

 cond

    Address of the condition variable object whose object name is to
    be changed.

 name

    Object name value to copy into the condition variable object.

 mbz

    Reserved for future use. The value must be zero (0).

1.30.3  –  Description

    This routine changes the object name in the condition variable
    object specified by the cond argument to the value specified
    by the name argument. To set a new condition variable object's
    object name, call this routine immediately after initializing the
    condition variable object.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

1.30.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable object, or the length in characters of name
                exceeds 31.
    [ENOMEM]    Insufficient memory exists to create a copy of the
                object name string.

1.30.5  –  Associated Routines

       pthread_cond_getname_np()

1.31  –  pthread_cond_signal

    Wakes at least one thread that is waiting on the specified
    condition variable.

1.31.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_signal (
             pthread_cond_t   *cond);

1.31.2  –  Arguments

 cond

    Condition variable to be signaled.

1.31.3  –  Description

    This routine unblocks at least one thread waiting on the
    specified condition variable cond. Calling this routine implies
    that data guarded by the associated mutex has changed, thus it
    might be possible for one of the waiting threads to proceed. In
    general, only one thread will be released.

    If no threads are waiting on the specified condition variable,
    this routine takes no action. The signal does not propagate to
    the next condition variable wait.

    This routine should be called when any thread waiting on the
    specified condition variable might find its predicate true,
    but only one thread should proceed. If more than one thread can
    proceed, or if any of the threads would not be able to proceed,
    then you must use pthread_cond_broadcast().

    The scheduling policy determines which thread is awakened. For
    policies SCHED_FIFO and SCHED_RR, a blocked thread is chosen
    in priority order, using first-in/first-out (FIFO) within
    priorities.

    If the calling thread holds the lock to the target condition
    variable's associated mutex while setting the variable's wait
    predicate, that thread can call pthread_cond_signal() to signal
    the variable even after releasing the lock on that mutex.
    However, for more predictable scheduling behavior, call pthread_
    cond_signal() before releasing the target condition variable's
    associated mutex.

1.31.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

1.31.5  –  Associated Routines

       pthread_cond_broadcast()
       pthread_cond_destroy()
       pthread_cond_init()
       pthread_cond_timedwait()
       pthread_cond_wait()

1.32  –  pthread_cond_signal_int_np

    Wakes one thread that is waiting on the specified condition
    variable (called from interrupt level only).

1.32.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_signal_int_np(
             pthread_cond_t   *cond);

1.32.2  –  Arguments

 cond

    Condition variable to be signaled.

1.32.3  –  Description

    This routine wakes one thread waiting on the specified condition
    variable. It can only be called from a software interrupt handler
    routine (such as from a Tru64 UNIX signal handler or OpenVMS
    AST). Calling this routine implies that it might be possible for
    a single waiting thread to proceed.

    The scheduling policies of the waiting threads determine which
    thread is awakened. For policies SCHED_FIFO and SCHED_RR, a
    blocked thread is chosen in priority order, using first-in/first-
    out (FIFO) within priorities.

    This routine does not cause a thread blocked on a condition
    variable to resume execution immediately. A thread resumes
    execution at some time after the interrupt handler routine
    returns. If no threads are waiting on the condition variable
    at the time of the call to pthread_cond_signal_int_np(), the next
    future waiting thread will be automatically released (that is,
    it will not actually wait). This routine establishes a "pending"
    wake if necessary.

    You can call this routine regardless of whether the associated
    mutex is either locked or unlocked. (Never lock a mutex from an
    interrupt handler routine.)

                                   NOTE

       This routine allows you to signal a condition variable from
       a software interrupt handler. Do not call this routine from
       noninterrupt code. To signal a condition variable from the
       normal noninterrupt level, use pthread_cond_signal().

1.32.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

1.32.5  –  Associated Routines

       pthread_cond_broadcast()
       pthread_cond_signal()
       pthread_cond_sig_preempt_int_np()
       pthread_cond_timedwait()
       pthread_cond_wait()

1.33  –  pthread_cond_sig_preempt_int_np

    Wakes one thread that is waiting on the specified condition
    variable (called from interrupt level only).

1.33.1  –  C Binding

     void
    pthread_cond_sig_preempt_int_np (
             pthread_cond_t   *cond);

1.33.2  –  Arguments

 cond

    Condition variable signaled.

1.33.3  –  Description

    This routine wakes one thread waiting on a condition variable.
    It can only be called from a software interrupt handler routine.
    Calling this routine implies that it might be possible for a
    single waiting thread to proceed. Call this routine when any
    thread waiting on the specified condition variable might find its
    predicate true.

    The scheduling policies of the waiting threads determine which
    thread is awakened. For policies SCHED_FIFO and SCHED_RR, a
    blocked thread is chosen in priority order, using first-in/first-
    out (FIFO) within priorities.

    You can call this routine when the associated mutex is either
    locked or unlocked. (Never try to lock a mutex from an interrupt
    handler.)

    This routine allows you to signal a thread from a software
    interrupt handler. Do not call this routine from noninterrupt
    code. If you want to signal a thread from the normal noninterrupt
    level, use pthread_cond_signal.

                                   NOTE

       If a waiting thread has a preemptive scheduling policy and
       a higher priority than the thread which was running when
       the interrupt occurred, then the waiting thread will preempt
       the interrupt routine and begin to run immediately. This
       is unlike pthread_cond_signal_int_np() which causes the
       condition variable to be signaled at a safe point after
       the interrupt has completed. pthread_cond_sig_preempt_int_
       np() avoids the possible latency which pthread_cond_signal_
       int_np() may introduce; however, a side effect of this is
       that during the call to pthread_cond_sig_preempt_int_np()
       other threads may run if a preemption occurs. Thus, once an
       interrupt routine calls pthread_cond_sig_preempt_int_np()
       it can no longer rely on any assumptions of exclusivity
       or atomicity which are typically provided by interrupt
       routines. Furthermore, once the call to pthread_cond_sig_
       preempt_int_np() is made, in addition to other threads
       running, subsequent interrupts may be delivered at any time
       as well (that is, they will not be blocked until the current
       interrupt completes). For this reason, it is recommended
       that pthread_cond_sig_preempt_int_np() be called as the last
       statement in the interrupt routine.

1.33.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

1.33.5  –  Associated Routines

       pthread_cond_broadcast()
       pthread_cond_signal()
       pthread_cond_signal_int_np()
       pthread_cond_timedwait()
       pthread_cond_wait()

1.34  –  pthread_cond_timedwait

    Causes a thread to wait for the specified condition variable
    to be signaled or broadcast, such that it will awake after a
    specified period of time.

1.34.1  –  C Binding

    #include <pthread.h>
    int
    pthread_cond_timedwait (
             pthread_cond_t   *cond,
             pthread_mutex_t   *mutex,
             const struct timespec   *abstime);

1.34.2  –  Arguments

 cond

    Condition variable that the calling thread waits on.

 mutex

    Mutex associated with the condition variable specified in cond.

 abstime

    Absolute time at which the wait expires, if the condition has not
    been signaled or broadcast. See the pthread_get_expiration_np()
    routine, which is used to obtain a value for this argument.

    The abstime argument is specified in Universal Coordinated Time
    (UTC). In the UTC-based model, time is represented as seconds
    since the Epoch. The Epoch is defined as the time 0 hours, 0
    minutes, 0 seconds, January 1st, 1970 UTC.

1.34.3  –  Description

    This routine causes a thread to wait until one of the following
    occurs:

    o  The specified condition variable is signaled or broadcast.

    o  The current system clock time is greater than or equal to the
       time specified by the abstime argument.

    This routine is identical to pthread_cond_wait(), except that
    this routine can return before a condition variable is signaled
    or broadcast, specifically, when the specified time expires. For
    more information, see the pthread_cond_wait() description.

    This routine atomically releases the mutex and causes the calling
    thread to wait on the condition. When the thread regains control
    after calling pthread_cond_timedwait(), the mutex is locked and
    the thread is the owner. This is true regardless of why the wait
    ended. If general cancelability is enabled, the thread reacquires
    the mutex (blocking for it if necessary) before the cleanup
    handlers are run (or before the exception is raised).

    If the current time equals or exceeds the expiration time, this
    routine returns immediately, releasing and reacquiring the mutex.
    It might cause the calling thread to yield (see the sched_yield()
    description). Your code should check the return status whenever
    this routine returns and take the appropriate action. Otherwise,
    waiting on the condition variable can become a nonblocking loop.

    Call this routine after you have locked the mutex specified
    in mutex. The results of this routine are unpredictable if
    this routine is called without first locking the mutex. The
    only routines that are supported for use with asynchronous
    cancelability enabled are those that disable asynchronous
    cancelability.

1.34.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond, mutex, or abstime is
                invalid, or

                Different mutexes are supplied for concurrent
                pthread_cond_timedwait()  operations or
                pthread_cond_wait()  operations on the same condition
                variable, or

                The mutex was not owned by the calling thread at the
                time of the call.
    [ETIMEDOUT] The time specified by abstime expired.
    [ENOMEM]    The Threads Library cannot acquire memory needed
                to block using a statically initialized condition
                variable.

1.34.5  –  Associated Routines

       pthread_cond_broadcast()
       pthread_cond_destroy()
       pthread_cond_init()
       pthread_cond_signal()
       pthread_cond_wait()
       pthread_get_expiration_np()

1.35  –  pthread_cond_wait

    Causes a thread to wait for the specified condition variable to
    be signaled or broadcast.

1.35.1  –  C Binding

    #include <pthread.h>

    int
    pthread_cond_wait (
             pthread_cond_t   *cond,
             pthread_mutex_t   *mutex);

1.35.2  –  Arguments

 cond

    Condition variable that the calling thread waits on.

 mutex

    Mutex associated with the condition variable specified in cond.

1.35.3  –  Description

    This routine causes a thread to wait for the specified condition
    variable to be signaled or broadcast. Each condition corresponds
    to one or more Boolean relations, called a predicate, based on
    shared data. The calling thread waits for the data to reach a
    particular state for the predicate to become true. However, the
    return from this routine does not imply anything about the value
    of the predicate and it should be reevaluated upon return.

    Call this routine after you have locked the mutex specified in
    mutex. The results of this routine are unpredictable if this
    routine is called without first locking the mutex.

    This routine atomically releases the mutex and causes the calling
    thread to wait on the condition. When the thread regains control
    after calling pthread_cond_wait(), the mutex is locked and the
    thread is the owner. This is true regardless of why the wait
    ended. If general cancelability is enabled, the thread reacquires
    the mutex (blocking for it if necessary) before the cleanup
    handlers are run (or before the exception is raised).

    A thread that changes the state of storage protected by the
    mutex in such a way that a predicate associated with a condition
    variable might now be true, must call either pthread_cond_
    signal() or pthread_cond_broadcast()  for that condition
    variable. If neither call is made, any thread waiting on the
    condition variable continues to wait.

    This routine might (with low probability) return when the
    condition variable has not been signaled or broadcast. When
    this occurs, the mutex is reacquired before the routine returns.
    To handle this type of situation, enclose each call to this
    routine in a loop that checks the predicate. The loop provides
    documentation of your intent and protects against these spurious
    wakeups, while also allowing correct behavior even if another
    thread consumes the desired state before the awakened thread
    runs.

    It is illegal for threads to wait on the same condition variable
    by specifying different mutexes.

    The only routines that are supported for use with asynchronous
    cancelability enabled are those that disable asynchronous
    cancelability.

1.35.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond or mutex is invalid, or

                Different mutexes are supplied for concurrent
                pthread_cond_wait()  or pthread_cond_timedwait()
                operations on the same condition variable, or

                The mutex was not owned by the calling thread at the
                time of the call.
    [ENOMEM]    The Threads Library cannot acquire memory needed
                to block using a statically initialized condition
                variable.

1.35.5  –  Associated Routines

       pthread_cond_broadcast()
       pthread_cond_destroy()
       pthread_cond_init()
       pthread_cond_signal()
       pthread_cond_timedwait()

1.36  –  pthread_condattr_destroy

    Destroys a condition variable attributes object.

1.36.1  –  C Binding

    #include <pthread.h>

    int
    pthread_condattr_destroy (
             pthread_condattr_t   *attr);

1.36.2  –  Arguments

 attr

    Condition variable attributes object to be destroyed.

1.36.3  –  Description

    This routine destroys the specified condition variable attributes
    object. Call this routine when a condition variable attributes
    object will no longer be referenced.

    Condition variables that were created using this attributes
    object are not affected by the destruction of the condition
    variable attributes object.

    The results of calling this routine are unpredictable if the
    value specified by the attr argument refers to a condition
    variable attributes object that does not exist.

1.36.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The attributes object specified by attr is invalid.

1.36.5  –  Associated Routines

       pthread_condattr_init()

1.37  –  pthread_condattr_init

    Initializes a condition variable attributes object.

1.37.1  –  C Binding

    #include <pthread.h>

    int
    pthread_condattr_init (
             pthread_condattr_t   *attr);

1.37.2  –  Arguments

 attr

    Address of the condition variable attributes object to be
    initialized.

1.37.3  –  Description

    This routine initializes the condition variable attributes object
    specified by the attr argument with a set of default attribute
    values.

    When an attributes object is used to create a condition
    variable, the values of the individual attributes determine the
    characteristics of the new condition variable. Attributes objects
    act as additional arguments to condition variable creation.
    Changing individual attributes in an attributes object does not
    affect any condition variables that were previously created using
    that attributes object.

    You can use the same condition variable attributes object in
    successive calls to pthread_condattr_init(), from any thread.
    If multiple threads can change attributes in a shared attributes
    object, your program must use a mutex to protect the integrity of
    that attributes object.

    Results are undefined if this routine is called and the attr
    argument specifies a condition variable attributes object that is
    already initialized.

    Currently, on OpenVMS systems, no attributes affecting condition
    variables are defined; you cannot change any attributes in the
    condition variable attributes object. On Tru64 UNIX systems, the
    PSHARED attribute is defined.

    The pthread_condattr_init() and pthread_condattr_destroy()
    routines are provided for future expandability of the pthread
    interface and to conform with the POSIX.1 standard. These
    routines serve no useful function, because there are no pthread_
    condattr_set*() type routines available at this time.

1.37.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid condition
                variable attributes object.
    [ENOMEM]    Insufficient memory exists to initialize the
                condition variable attributes object.

1.37.5  –  Associated Routines

       pthread_condattr_destroy()
       pthread_cond_init()

1.38  –  pthread_create

    Creates a thread.

1.38.1  –  C Binding

    #include <pthread.h>

    int
    pthread_create (
             pthread_t   *thread,
             const pthread_attr_t   *attr,
             void *   (*start_routine) (void *),
             void   *arg);

1.38.2  –  Arguments

 thread

    Location for thread object to be created.

 attr

    Thread attributes object that defines the characteristics of the
    thread being created. If you specify NULL, default attributes are
    used.

 start_routine

    Function executed as the new thread's start routine.

 arg

    Address value copied and passed to the thread's start routine.

1.38.3  –  Description

    This routine creates a thread. A thread is a single, sequential
    flow of control within a program. It is the active execution of a
    designated routine, including any nested routine invocations.

    Successful execution of this routine includes the following
    actions:

    o  The Threads Library creates a thread object to describe
       and control the thread. The thread object includes a thread
       environment block (TEB) that programs can use, with care. (See
       the <sys/types.h> header file on Tru64 UNIX, or the pthread.h
       header file on other platforms.)

    o  The thread argument receives an identifier for the new thread.

    o  An executable thread is created with attributes specified
       by the attr argument (or with default attributes if NULL is
       specified).

    Thread Creation
    The Threads Library creates a thread in the ready state and
    prepares the thread to begin executing its start routine,
    the function passed to pthread_create() as the start_routine
    argument. Depending on the presence of other threads and their
    scheduling and priority attributes, the new thread might start
    executing immediately. The new thread can also preempt its
    creator, depending on the two threads' respective scheduling
    and priority attributes. The caller of pthread_create() can
    synchronize with the new thread using the pthread_join() routine
    or using any mutually agreed upon mutexes, condition variables or
    read-write locks.

    For the duration of the new thread's existence, the Threads
    Library maintains and manages the thread object and other thread
    state overhead. A thread exists until it is both terminated and
    detached. A thread is detached when created if the detachstate
    attribute of its thread object is set to PTHREAD_CREATE_DETACHED.
    It is also detached after any thread returns successfully from
    calling pthread_detach() or pthread_join()  for the thread.
    Termination is explained in the next section (see Thread
    Termination).

    The Threads Library assigns each new thread a thread identifier,
    which is written into the address specified as the pthread_
    create() routine's thread argument. The new thread's thread
    identifier is written before the new thread executes.

    By default, the new thread's scheduling policy and priority
    are inherited from the creating thread-that is, by default,
    the pthread_create() routine ignores the scheduling policy and
    priority set in the specified thread attributes object. Thus,
    to create a thread that is subject to the scheduling policy and
    priority set in the specified thread attributes object, before
    calling pthread_create(), your program must use the pthread_attr_
    setinheritsched() routine to set the inherit thread attributes
    object's scheduling attribute to PTHREAD_EXPLICIT_SCHED.

    On Tru64 UNIX, the signal state of the new thread is initialized
    as follows:

    1. The signal mask is inherited from the creating thread.

    2. The set of signals pending for the new thread is empty.

    If pthread_create() fails, no new thread is created, and the
    contents of the location referenced by thread are undefined.
    Thread Termination
    A thread terminates when one of the following events occurs:

    o  The thread returns from its start routine.

    o  The thread calls the pthread_exit() routine.

    o  The thread is canceled.

    When a thread terminates, the following actions are performed:

    1. A return value (if one is available) is written into the
       terminated thread's thread object, as follows:

       o  If the thread has been canceled, the value PTHREAD_CANCELED
          is written into the thread's thread object.

       o  If the thread terminated by returning from its start
          routine, the return value is copied from the start routine
          (if one is available) into the thread's thread object.
          Alternatively, if the thread explicitly called pthread_
          exit(), the value received in the value_ptr argument (from
          pthread_exit()) is stored in the thread's thread object.

       Another thread can obtain this return value by joining with
       the terminated thread (using pthread_join()).

                                      NOTE

          If the thread terminated by returning from its start
          routine normally and the start routine does not provide a
          return value, the results obtained by joining with that
          thread are unpredictable.

    2. If the termination results from a cancelation request or a
       call to pthread_exit(), the Threads Library calls, in turn,
       each cleanup handler that this thread declared (using pthread_
       cleanup_push()) and that is not yet removed (using pthread_
       cleanup_pop()). (The Threads Library also transfers control to
       any appropriate CATCH, CATCH_ALL, or FINALLY blocks .)

       The Threads Library calls the terminated thread's most
       recently pushed cleanup handler first.

       For C++ programmers: At normal exit from a thread, your
       program will call the appropriate destructor functions, just
       as if an exception had been raised.

    3. To exit the terminated thread due to a call to pthread_exit(),
       the Threads Library raises the pthread_exit_e exception. To
       exit the terminated thread due to cancelation, the Threads
       Library raises the pthread_cancel_e exception.

       Your program can use the exception package to operate on the
       generated exception. (In particular, note that the practice of
       using CATCH handlers in place of pthread_cleanup_push() is not
       portable.)

    4. For each of the terminated thread's thread-specific data keys
       that has a non-NULL value:

       o  The thread's value for the corresponding key is set to
          NULL.

       o  Call each thread-specific data destructor function in this
          multithreaded process' list of destructors.

       Repeat this step until all thread-specific data values in the
       thread are NULL, or for up to a number of iterations equal to
       PTHREAD_DESTRUCTOR_ITERATIONS. This destroys all thread-
       specific data associated with the terminated thread.

    5. Awaken the thread (if there is one) that is currently waiting
       to join with the terminated thread. That is, awaken the thread
       that is waiting in a call to pthread_join().

    6. If the thread is already detached, destroy its thread object.
       Otherwise, the thread continues to exist until detached or
       joined with.

1.38.4  –  Return Values

    If an error condition occurs, no thread is created, the contents
    of thread are undefined, and this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacks the necessary resources to create
                another thread, or the system-imposed limit on the
                total number of threads under execution by a single
                user is exceeded.
    [EINVAL]    The value specified by attr is not a valid attributes
                block.
    [ENOMEM]    Insufficient memory exists to create a thread.
    [EPERM]     The caller does not have the appropriate permission
                to create a thread with the specified attributes.

1.38.5  –  Associated Routines

       pthread_atfork()
       pthread_attr_destroy()
       pthread_attr_init()
       pthread_attr_setdetachstate()
       pthread_attr_setinheritsched()
       pthread_attr_setschedparam()
       pthread_attr_setschedpolicy()
       pthread_attr_setstacksize()
       pthread_cancel()
       pthread_detach()
       pthread_exit()
       pthread_join()

1.39  –  pthread_delay_np

    Delays a thread's execution.

1.39.1  –  C Binding

    #include <pthread.h>

    int
    pthread_delay_np (
             const struct timespec   *interval);

1.39.2  –  Arguments

 interval

    Number of seconds and nanoseconds to delay execution. The value
    specified for each must be greater than or equal to zero.

1.39.3  –  Description

    This routine causes a thread to delay execution for a specific
    interval of time. This interval ends at the current time plus the
    specified interval. The routine will not return before the end
    of the interval is reached, but may return an arbitrary amount of
    time after the end of the interval is reached. This can be due to
    system load, thread priorities, and system timer granularity.

    Specifying an interval of zero (0) seconds and zero (0)
    nanoseconds is allowed and can be used to force the thread either
    to give up the processor or to deliver a pending cancelation
    request.

    The timespec structure contains the following two fields:

    o  tv_sec is an integral number of seconds.

    o  tv_nsec is an integral number of nanoseconds.

1.39.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by interval is invalid.

1.40  –  pthread_detach

    Marks a thread object for deletion.

1.40.1  –  C Binding

    #include <pthread.h>

    int
    pthread_detach (
             pthread_t   thread);

1.40.2  –  Arguments

 thread

    Thread object being marked for deletion.

1.40.3  –  Description

    This routine marks the specified thread object to indicate that
    storage for the corresponding thread can be reclaimed when
    the thread terminates. This includes storage for the thread
    argument's return value, as well as the thread object. If thread
    has not terminated when this routine is called, this routine does
    not cause it to terminate.

    When a thread object is no longer referenced, call this routine.

    The results of this routine are unpredictable if the value of
    thread refers to a thread object that does not exist.

    You can create a thread already detached by setting its thread
    object's detachstate attribute.

    The pthread_join() routine also detaches the target thread after
    pthread_join() returns successfully.

1.40.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by thread does not refer to a
                joinable thread.
    [ESRCH]     The value specified by thread cannot be found.

1.40.5  –  Associated Routines

       pthread_cancel()
       pthread_create()
       pthread_exit()
       pthread_join()

1.41  –  pthread_equal

    Compares one thread identifier to another thread identifier.

1.41.1  –  C Binding

    #include <pthread.h>

    int
    pthread_equal (
             pthread_t   t1,
             pthread_t   t2);

1.41.2  –  Arguments

 t1

    The first thread identifier to be compared.

 t2

    The second thread identifier to be compared.

1.41.3  –  Description

    This routine compares one thread identifier to another thread
    identifier.

    If either t1 or t2 are not valid thread identifiers, this
    routine's behavior is undefined.

1.41.4  –  Return Values

    Possible return values are as follows:

    Return      Description

    0           Values of t1 and t2 do not designate the same object.
    Non-zero    Values of t1 and t2 designate the same object.

1.42  –  pthread_exc_get_status_np

    (Macro) Obtains a system-defined error status from a status
    exception object.

1.42.1  –  C Binding

    #include <pthread_exception.h>

    int
    pthread_exc_get_status_np (
             EXCEPTION    *exception,
             unsigned long    *code);

1.42.2  –  Arguments

 exception

    Threads Library status exception object whose status code is
    obtained.

 code

    Receives the system-specific status code associated with the
    specified status exception object.

1.42.3  –  Description

    This routine obtains and returns the system-specific status
    value from the status exception object specified in the exception
    argument. This value must have already been associated with the
    exception object using the pthread_exc_set_status_np() routine.

    In a program that uses Threads Library status exceptions, use
    this routine within a CATCH or CATCH_ALL code block to obtain the
    status code value associated with a caught exception. Note that
    any exception objects set to the same status value are considered
    equivalent by the Threads Library.

1.42.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. If the routine's exception
    object argument is a status exception, it sets the code argument
    and returns zero (0). Possible return values are as follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The exception argument is not a valid status
                exception object.

1.42.5  –  Associated Routines

       pthread_exc_set_status_np()

1.43  –  pthread_exc_matches_np

    (Macro) Determines whether two Threads Library exception objects
    are identical.

1.43.1  –  C Binding

    #include <pthread_exception.h>

    int
    pthread_exc_matches_np (
             EXCEPTION    *exception1,
             EXCEPTION    *exception2);

1.43.2  –  Arguments

 exception1

    Threads Library exception object.

 exception2

    Threads Library exception object.

1.43.3  –  Description

    This routine compares two exception objects, taking into
    consideration whether each is an address exception or status
    exception.

    This routine returns either the C language value TRUE or the
    C language value FALSE, indicating whether the two exception
    objects specified in the arguments exception1 and exception2 are
    identical.

1.43.4  –  Return Values

    The C language value TRUE if the exception objects are identical,
    or the C language value FALSE if not.

1.43.5  –  Associated Routines

       pthread_exc_get_status_np()
       pthread_exc_report_np()
       pthread_exc_set_status_np()

1.44  –  pthread_exc_report_np

    Produces a message that reports what a specified Threads Library
    status exception object represents.

1.44.1  –  C Binding

    #include <pthread_exception.h>

    void
    pthread_exc_report_np (
             EXCEPTION    *exception);

1.44.2  –  Arguments

 exception

    Threads Library exception object that has been set with a status
    value.

1.44.3  –  Description

    This routine produces a text message on the stderr device
    (Tru64 UNIX systems) or SYS$ERROR device (OpenVMS systems) that
    describes the exception whose exception object is specified in
    the exception argument.

    In a program that uses status exceptions, use this routine within
    a CATCH or CATCH_ALL code block to produce the message associated
    with a caught exception. Note that any exception objects set to
    the same status value are considered equivalent by the Threads
    Library.

1.44.4  –  Return Values

    None

1.44.5  –  Associated Routines

       pthread_exc_get_status_np()
       pthread_exc_set_status_np()

1.45  –  pthread_exc_set_status_np

    (Macro) Imports a system-defined error status into a Threads
    Library address exception object.

1.45.1  –  C Binding

    #include <pthread_exception.h>

    void
    pthread_exc_set_status_np (
             EXCEPTION    *exception,
             unsigned long   code);

1.45.2  –  Arguments

 exception

    Threads Library address exception object into which the specified
    status code is imported.

 code

    System-specific status code to be imported.

1.45.3  –  Description

    This routine associates a system-specific status value with the
    specified address exception object. This transforms the address
    exception object into a status exception object.

    The exception argument must already have been initialized with
    the exception package's EXCEPTION_INIT macro.

    Use this routine to associate any system-specific status value
    with the specified address exception object. Note that any
    exception objects set to the same status value are considered
    equivalent by the Threads Library.

1.45.4  –  Return Values

    None

1.45.5  –  Associated Routines

       pthread_exc_get_status_np()

1.46  –  pthread_exit

    Terminates the calling thread.

1.46.1  –  C Binding

    #include <pthread.h>

    void
    pthread_exit (
             void   *value_ptr);

1.46.2  –  Arguments

 value_ptr

    Value copied and returned to the caller of pthread_join(). Note
    that void * is used as a universal datatype, not as a pointer.
    The Threads Library treats the value_ptr as a value and stores it
    to be returned by pthread_join().

1.46.3  –  Description

    This routine terminates the calling thread and makes a status
    value (value_ptr) available to any thread that calls pthread_
    join() and specifies the terminating thread.

    Any cleanup handlers that have been pushed and not yet popped
    from the stack are popped in the reverse order that they were
    pushed and then executed. After all cleanup handlers have been
    executed, appropriate destructor functions are called in an
    unspecified order if the thread has any thread-specific data.
    Thread termination does not release any application-visible
    process resources, including, but not limited to mutexes and
    file descriptors, nor does it perform any process-level cleanup
    actions, including, but not limited to calling any atexit()
    routine that may exist.

    The Threads Library issues an implicit call to pthread_exit()
    when a thread returns from the start routine that was used to
    create it. The Threads Library writes the function's return value
    as the return value in the thread's thread object. The process
    exits when the last running thread calls pthread_exit().

    After a thread has terminated, the result of access to local
    (that is, explicitly or implicitly declared auto) variables
    of the thread is undefined. So, do not use references to local
    variables of the existing thread for the value_ptr argument of
    the pthread_exit() routine.

1.46.4  –  Return Values

    None

1.46.5  –  Associated Routines

       pthread_cancel()
       pthread_create()
       pthread_detach()
       pthread_join()

1.47  –  pthread_get_expiration_np

    Obtains a value representing a desired expiration time.

1.47.1  –  C Binding

    #include <pthread.h>

    int
    pthread_get_expiration_np (
                const struct timespec   *delta,
                struct timespec   *abstime);

1.47.2  –  Arguments

 delta

    Number of seconds and nanoseconds to add to the current system
    time. (The result is the time in the future.) This result will be
    placed in abstime.

 abstime

    Value representing the absolute expiration time. The absolute
    expiration time is obtained by adding delta to the current system
    time. The resulting abstime is in Universal Coordinated Time
    (UTC).

1.47.3  –  Description

    This routine adds a specified interval to the current absolute
    system time and returns a new absolute time. This new absolute
    time may then be used as the expiration time in a call to
    pthread_cond_timedwait().

    The timespec structure contains the following two fields:

    o  tv_sec is an integral number of seconds.

    o  tv_nsec is an integral number of nanoseconds.

1.47.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by delta is invalid.

1.47.5  –  Associated Routines

       pthread_cond_timedwait()

1.48  –  pthread_getconcurrency

    Obtains the value of the concurrency level global variable for
    this process.

1.48.1  –  C Binding

    #include <pthread.h>

    int
    pthread_getconcurrency (
                void);

1.48.2  –  Description

    This routine obtains and returns the value of the "concurrency
    level" global setting for the calling thread's process. Because
    the Threads Library automatically manages the concurrency of all
    threads in a multithreaded process, it ignores this concurrency
    level value.

    The concurrency level value has no effect on the behavior of a
    multithreaded program that uses the Threads Library. This routine
    is provided for Single UNIX Specification, Version 2, source code
    compatibility and has no other effect when called.

    The initial concurrency level is zero (0), indicating that the
    Threads Library controls the concurrency level.

    The concurrency level can be set using the pthread_
    setconcurrency() routine.

1.48.3  –  Return Values

    This routine always returns the value of this process'
    concurrency level global variable. If this process has never
    called the pthread_setconcurrency() routine, this routine returns
    zero (0).

1.48.4  –  Associated Routines

       pthread_setconcurrency()

1.49  –  pthread_getname_np

    Obtains the object name from the thread object for an existing
    thread.

1.49.1  –  C Binding

    #include <pthread.h>

    int
    pthread_getname_np (
             pthread_thread_t   thread,
             char   *name,
             size_t   len);

1.49.2  –  Arguments

 thread

    Thread object whose object name is to be obtained.

 name

    Location to store the obtained object name.

 len

    Length in bytes of buffer at the location specified by name.

1.49.3  –  Description

    This routine copies the object name from the thread object
    specified by the thread argument to the buffer at the location
    specified by the name argument. Before calling this routine, your
    program must allocate the buffer indicated by name.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    If the specified thread object has not been previously set with
    an object name, this routine copies a C language null string into
    the buffer at location name.

1.49.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [ESRCH]     The thread specified by thread does not exist.

1.49.5  –  Associated Routines

       pthread_setname_np()

1.50  –  pthread_getschedparam

    Obtains the current scheduling policy and scheduling parameters
    of a thread.

1.50.1  –  C Binding

    #include <pthread.h>

    int
    pthread_getschedparam (
             pthread_t   thread,
             int   *policy,
             struct sched_param   *param);

1.50.2  –  Arguments

 thread

    Thread whose scheduling policy and parameters are obtained.

 policy

    Receives the value of the scheduling policy for the thread
    specified in thread. Refer to the description of the pthread_
    setschedparam() routine for valid policies and their meanings.

 param

    Receives the value of the scheduling parameters for the thread
    specified in thread. Refer to the description of the pthread_
    setschedparam() routine for valid values.

1.50.3  –  Description

    This routine obtains both the current scheduling policy and
    associated scheduling parameters of the thread specified by the
    thread argument.

    The priority value returned in the param structure is the value
    specified either in the attr argument passed to pthread_create()
    or by the most recent call to pthread_setschedparam() that
    affects the target thread.

    This routine differs from pthread_attr_getschedpolicy() and
    pthread_attr_getschedparam(), in that those routines get the
    scheduling policy and parameter attributes that are used to
    establish the priority and scheduling policy of a new thread
    when it is created. This routine, however, obtains the scheduling
    policy and parameters of an existing thread.

1.50.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [ESRCH]     The value specified by thread does not refer to an
                existing thread.

1.50.5  –  Associated Routines

       pthread_attr_getschedparam()
       pthread_attr_getschedpolicy()
       pthread_create()
       pthread_self()
       pthread_setschedparam()

1.51  –  pthread_getsequence_np

    Obtains the unique identifier for the specified thread.

1.51.1  –  C Binding

    #include <pthread.h>

    unsigned long
    pthread_getsequence_np (
             pthread_t   thread);

1.51.2  –  Arguments

 thread

    Thread whose sequence number is to be obtained.

1.51.3  –  Description

    This routine obtains and returns the thread sequence number
    for the thread identified by the thread object specified in the
    thread argument.

    The thread sequence number provides a unique identifier for each
    existing thread. A thread's thread sequence number is never
    reused while the thread exists, but can be reused after the
    thread terminates. The debugger interfaces use this sequence
    number to identify each thread in commands and in display output.

    The result of calling this routine is undefined if the thread
    argument does not specify a valid thread object.

1.51.4  –  Return Values

    No errors are returned. This routine returns the thread sequence
    number for the thread identified by the thread object specified
    in the thread argument. The result of calling this routine is
    undefined if the thread argument does not specify a valid thread.

1.51.5  –  Associated Routines

       pthread_create()
       pthread_self()

1.52  –  pthread_getspecific

    Obtains the thread-specific data associated with the specified
    key.

1.52.1  –  C Binding

    #include <pthread.h>

    void
    *pthread_getspecific (
                pthread_key_t   key);

1.52.2  –  Arguments

 key

    The context key identifies the thread-specific data to be
    obtained.

1.52.3  –  Description

    This routine obtains the thread-specific data associated with the
    specified key for the current thread. Obtain this key by calling
    the pthread_key_create() routine. This routine returns the value
    currently bound to the specified key on behalf of the calling
    thread.

    This routine may be called from a thread-specific data destructor
    function.

1.52.4  –  Return Values

    No errors are returned. This routine returns the thread-specific
    data value associated with the specified key argument. If no
    thread-specific data value is associated with key, or if key is
    not defined, then this routine returns a NULL value.

1.52.5  –  Associated Routines

       pthread_key_create()
       pthread_setspecific()

1.53  –  pthread_join

                   PTHREAD_JOIN32(),  PTHREAD_JOIN64()

       The pthread_join32() and pthread_join64() forms are only
       valid in 64-bit pointer environments for OpenVMS Alpha.
       Ensure that your compiler provides 64-bit support before you
       use pthread_join64().

    Causes the calling thread to wait for the termination of a
    specified thread.

1.53.1  –  C Binding

    #include <pthread.h>

    int
    pthread_join (
             pthread_t   thread,
             void   **value_ptr);

1.53.2  –  Arguments

 thread

    Thread whose termination is awaited by the calling routine.

 value_ptr

    Return value of the terminating thread (when that thread either
    calls pthread_exit() or returns from its start routine).

1.53.3  –  Description

    This routine suspends execution of the calling thread until the
    specified target thread thread terminates.

    On return from a successful pthread_join() call with a non-
    NULL value_ptr argument, the value passed to pthread_exit()
    is returned in the location referenced by value_ptr, and the
    terminating thread is detached.

    If more than one thread attempts to join with the same thread,
    the results are unpredictable.

    A call to pthread_join() returns after the target thread
    terminates. The pthread_join() routine is a deferred cancelation
    point; the target thread will not be detached if the thread
    blocked in pthread_join() is canceled.

    If a thread calls this routine and specifies its own pthread_t, a
    deadlock can result.

    The pthread_join() (or pthread_detach())  routine should
    eventually be called for every thread that is created with the
    detachstate attribute of its thread object set to PTHREAD_CREATE_
    JOINABLE, so that storage associated with the thread can be
    reclaimed.

                                   NOTE

       For OpenVMS Alpha systems:
       The pthread_join() routine is defined to pthread_join64()
       if you compile using /pointer_size=long. If you do not
       specify /pointer_size, or if you specify /pointer_
       size=short, then pthread_join() is defined to be pthread_
       join32(). You can call pthread_join32() or pthread_join64()
       instead of pthread_join(). The pthread_join32() form
       returns a 32-bit void * value in the address to which
       value_ptr points. The pthread_join64() form returns a 64-
       bit void * value. You can call either, or you can call
       pthread_join(). Note that if you call pthread_join32() and
       the thread with which you join returns a 64-bit value, the
       high 32 bits of which are not 0 (zero), the Threads Library
       discards those high bits with no warning.

1.53.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by thread does not refer to a
                joinable thread.
    [ESRCH]     The value specified by thread does not refer to an
                existing thread ID.
    [EDEADLK]   A deadlock was detected, or thread specifies the
                calling thread.

1.53.5  –  Associated Routines

       pthread_cancel()
       pthread_create()
       pthread_detach()
       pthread_exit()

1.54  –  pthread_key_create

    Generates a unique thread-specific data key.

1.54.1  –  C Binding

    #include <pthread.h>

    int
    pthread_key_create (
             pthread_key_t   *key,
             void   (*destructor)(void *));

1.54.2  –  Arguments

 key

    Location where the new thread-specific data key will be stored.

 destructor

    Procedure called to destroy a thread-specific data value
    associated with the created key when the thread terminates.
    Note that the argument to the destructor for the user-specified
    routine is the non-NULL value associated with a key.

1.54.3  –  Description

    This routine generates a unique, thread-specific data key that
    is visible to all threads in the process. The variable key
    provided by this routine is an opaque object used to locate
    thread-specific data. Although the same key value can be used
    by different threads, the values bound to the key by pthread_
    setspecific() are maintained on a per-thread basis and persist
    for the life of the calling thread. The initial value of the key
    in all threads is NULL.

    The Threads Library imposes a maximum number of thread-specific
    data keys, equal to the symbolic constant PTHREAD_KEYS_MAX.

    Thread-specific data allows client software to associate "static"
    information with the current thread. For example, where a routine
    declares a variable static in a single-threaded program, a
    multithreaded version of the program might create a thread-
    specific data key to store the same variable.

    This routine generates and returns a new key value. The key
    reserves a cell within each thread. Each call to this routine
    creates a new cell that is unique within an application
    invocation. Keys must be generated from initialization code that
    is guaranteed to be called only once within each process. (See
    the pthread_once() description for more information.)

    When a thread terminates, its thread-specific data is
    automatically destroyed; however, the key remains unless
    destroyed by a call to pthread_key_delete(). An optional
    destructor function can be associated with each key. At thread
    exit, if a key has a non-NULL destructor pointer, and the thread
    has a non-NULL value associated with that key, the destructor
    function is called with the current associated value as its sole
    argument. The order in which thread-specific data destructors are
    called at thread termination is undefined.

    Before each destructor is called, the thread's value for the
    corresponding key is set to NULL. After the destructors have been
    called for all non-NULL values with associated destructors, if
    there are still some non-NULL values with associated destructors,
    then this sequence of actions is repeated. If there are still
    non-NULL values for any key with a destructor after four
    repetitions of this sequence, the thread is terminated. At this
    point, any key values that represent allocated heap will be lost.
    Note that this occurs only when a destructor performs some action
    that creates a new value for some key. Your program's destructor
    code should attempt to avoid this sort of circularity.

1.54.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacked the necessary resources to create
                another thread-specific data key, or the limit on the
                total number of keys per process (PTHREAD_KEYS_MAX)
                has been exceeded.
    [ENOMEM]    Insufficient memory exists to create the key.

1.54.5  –  Associated Routines

       pthread_getspecific()
       pthread_key_delete()
       pthread_once()
       pthread_setspecific()

1.55  –  pthread_key_delete

    Deletes a thread-specific data key.

1.55.1  –  C Binding

    #include <pthread.h>

    int
    pthread_key_delete (
             pthread_key_t   key);

1.55.2  –  Arguments

 key

    Context key to be deleted.

1.55.3  –  Description

    This routine deletes the thread-specific data key specified by
    the key argument, which must have been previously returned by
    pthread_key_create().

    The thread-specific data values associated with key need not be
    NULL at the time this routine is called. The application must
    free any application storage or perform any cleanup actions for
    data structures related to the deleted key or associated thread-
    specific data in any threads. This cleanup can be done either
    before or after this routine is called.

    Attempting to use the key after calling this routine results in
    unpredictable behavior.

    No destructor functions are invoked by this routine. Any
    destructor functions that may have been associated with key shall
    no longer be called upon thread exit. pthread_key_delete() can be
    called from within destructor functions.

1.55.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The key value is not a valid key.

1.55.5  –  Associated Routines

       pthread_exit()
       pthread_getspecific()
       pthread_key_create()

1.56  –  pthread_key_getname_np

    Obtains the object name from a thread-specific data key object.

1.56.1  –  C Binding

    #include <pthread.h>

    int
    pthread_key_getname_np (
             pthread_key_t   *key,
             char   *name,
             size_t   len);

1.56.2  –  Arguments

 key

    Address of the thread-specific data key object whose object name
    is to be obtained.

 name

    Location to store the obtained object name.

 len

    Length in bytes of buffer at the location specified by name.

1.56.3  –  Description

    This routine copies the object name from the thread-specific
    data key object specified by the key argument to the buffer at
    the location specified by the name argument. Before calling this
    routine, your program must allocate the buffer indicated by name.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    If the specified thread-specific data key object has not been
    previously set with an object name, this routine copies a C
    language null string into the buffer at location name.

1.56.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by key is not a valid key.

1.56.5  –  Associated Routines

       pthread_key_setname_np()

1.57  –  pthread_key_setname_np

    Changes the object name in a thread-specific data key object.

1.57.1  –  C Binding

    #include <pthread.h>

    int
    pthread_key_setname_np (
             pthread_key_t   *cond,
             const char   *name,
             void   *mbz);

1.57.2  –  Arguments

 key

    Address of the thread-specific data key object whose object name
    is to be changed.

 name

    Object name value to copy into the key object.

 mbz

    Reserved for future use. The value must be zero (0).

1.57.3  –  Description

    This routine changes the object name in the thread-specific
    data key object specified by the key argument to the value
    specified by the name argument. To set a new thread-specific data
    key object's object name, call this routine immediately after
    initializing the key object.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

1.57.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by key is not a valid key, or the
                length in characters of name exceeds 31.
    [ENOMEM]    Insufficient memory exists to create a copy of the
                object name string.

1.57.5  –  Associated Routines

       pthread_key_getname_np()

1.58  –  pthread_lock_global_np

    Locks the Threads Library global mutex.

1.58.1  –  C Binding

    #include <pthread.h>

    int
    pthread_lock_global_np (void);

1.58.2  –  Arguments

    None

1.58.3  –  Description

    This routine locks the Threads Library global mutex. If the
    global mutex is currently held by another thread when a thread
    calls this routine, the calling thread waits for the global mutex
    to become available and then locks it.

    The thread that has locked the global mutex becomes its current
    owner and remains the owner until the same thread has unlocked
    it. This routine returns with the global mutex in the locked
    state and with the current thread as the global mutex's current
    owner.

    Use the global mutex when calling a library package that is
    not designed to run in a multithreaded environment. Unless the
    documentation for a library function specifically states that it
    is thread-safe, assume that it is not compatible; in other words,
    assume it is nonreentrant.

    The global mutex is one lock. Any code that calls any function
    that is not known to be reentrant should use the same lock.
    This prevents problems resulting from dependencies among threads
    that call library functions and those functions' calling other
    functions, and so on.

    The global mutex is a recursive mutex. A thread that has locked
    the global mutex can relock it without deadlocking. The locking
    thread must call pthread_unlock_global_np() as many times as it
    called this routine, to allow another thread to lock the global
    mutex.

1.58.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.

1.58.5  –  Associated Routines

       pthread_unlock_global_np()

1.59  –  pthread_mutex_destroy

    Destroys a mutex.

1.59.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutex_destroy (
             pthread_mutex_t   *mutex);

1.59.2  –  Arguments

 mutex

    The mutex to be destroyed.

1.59.3  –  Description

    This routine destroys the specified mutex by uninitializing it,
    and should be called when a mutex object is no longer referenced.
    After this routine is called, the Threads Library may reclaim
    internal storage used by the specified mutex.

    It is safe to destroy an initialized mutex that is unlocked.
    However, it is illegal to destroy a locked mutex.

    The results of this routine are unpredictable if the mutex object
    specified in the mutex argument does not currently exist, or is
    not initialized.

1.59.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EBUSY]     An attempt was made to destroy the object referenced
                by mutex while it is locked.
    [EINVAL]    The value specified by mutex is not a valid mutex.

1.59.5  –  Associated Routines

       pthread_mutex_init()
       pthread_mutex_lock()
       pthread_mutex_trylock()
       pthread_mutex_unlock()

1.60  –  pthread_mutex_getname_np

    Obtains the object name from a mutex object.

1.60.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutex_getname_np (
             pthread_mutex_t   *mutex,
             char   *name,
             size_t   len);

1.60.2  –  Arguments

 mutex

    Address of the mutex object whose object name is to be obtained.

 name

    Location to store the obtained object name.

 len

    Length in bytes of buffer at the location specified by name.

1.60.3  –  Description

    This routine copies the object name from the mutex object
    specified by the mutex argument to the buffer at the location
    specified by the name argument. Before calling this routine, your
    program must allocate the buffer indicated by name.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    If the specified condition variable object has not been
    previously set with an object name, this routine copies a C
    language null string into the buffer at location name.

1.60.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by mutex is not a valid mutex.

1.60.5  –  Associated Routines

       pthread_mutex_setname_np()

1.61  –  pthread_mutex_init

    Initializes a mutex.

1.61.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutex_init (
             pthread_mutex_t   *mutex,
             const pthread_mutexattr_t   *attr);

1.61.2  –  Arguments

 mutex

    Mutex to be initialized.

 attr

    Mutex attributes object that defines the characteristics of the
    mutex to be initialized.

1.61.3  –  Description

    This routine initializes a mutex with the attributes specified
    by the mutex attributes object specified in the attr argument. A
    mutex is a synchronization object that allows multiple threads to
    serialize their access to shared data.

    The mutex is initialized and set to the unlocked state. If attr
    is set to NULL, the default mutex attributes are used. The
    pthread_mutexattr_settype() routine can be used to specify the
    type of mutex that is created (normal, recursive, or errorcheck).

    Use the PTHREAD_MUTEX_INITIALIZER macro to statically initialize
    a mutex without calling this routine. Statically initialized
    mutexes need not be destroyed using pthread_mutex_destroy(). Use
    this macro as follows:

       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER

    Only normal mutexes can be statically initialized.

    A mutex is a resource of the process, not part of any particular
    thread. A mutex is neither destroyed nor unlocked automatically
    when any thread exits. If a mutex is allocated on a stack, static
    initializers cannot be used on the mutex.

1.61.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error, the mutex is not initialized,
    and the contents of mutex are undefined. Possible return values
    are as follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacks the necessary resources to
                initialize the mutex.
    [EBUSY]     The implementation has detected an attempt to
                reinitialize the mutex (a previously initialized,
                but not yet destroyed mutex).
    [EINVAL]    The value specified by mutex is not a valid mutex.
    [ENOMEM]    Insufficient memory exists to initialize the mutex.
    [EPERM]     The caller does not have privileges to perform this
                operation.

1.61.5  –  Associated Routines

       pthread_mutexattr_init()
       pthread_mutexattr_gettype()
       pthread_mutexattr_settype()
       pthread_mutex_lock()
       pthread_mutex_trylock()
       pthread_mutex_unlock()

1.62  –  pthread_mutex_lock

    Locks an unlocked mutex.

1.62.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutex_lock (
             pthread_mutex_t   *mutex);

1.62.2  –  Arguments

 mutex

    Mutex to be locked.

1.62.3  –  Description

    This routine locks a mutex with behavior that depends upon the
    type of mutex, as follows:

    o  If a normal or default mutex is specified, a deadlock can
       result if the current owner of the mutex calls this routine in
       an attempt to lock the mutex a second time. (The deadlock is
       not detected or reported.)

    o  If a recursive mutex is specified, the current owner of the
       mutex can relock the same mutex without blocking. The lock
       count is incremented for each recursive lock within the
       thread.

    o  If an errorcheck mutex is specified and the current owner
       tries to lock the mutex a second time, this routine reports
       the [EDEADLK] error. If the mutex is locked by another thread,
       the calling thread waits for the mutex to become available.

    Use the pthread_mutexattr_settype() routine to set the type of
    the mutex to normal, default, recursive, or errorcheck.

    The thread that has locked a mutex becomes its current owner and
    remains its owner until the same thread has unlocked it. This
    routine returns with the mutex in the locked state and with the
    calling thread as the mutex's current owner.

    A recursive or errorcheck mutex records the identity of the
    thread that locks it, allowing debuggers to display this
    information. In most cases, normal and default mutexes do not
    record the owning thread's identity.

1.62.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EDEADLK]   A deadlock condition is detected.
    [EINVAL]    The value specified by mutex is not a valid mutex.

1.62.5  –  Associated Routines

       pthread_mutexattr_settype()
       pthread_mutex_destroy()
       pthread_mutex_init()
       pthread_mutex_trylock()
       pthread_mutex_unlock()

1.63  –  pthread_mutex_setname_np

    Changes the object name in a mutex object.

1.63.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutex_setname_np (
             pthread_mutex_t   *mutex,
             const char   *name,
             void   *mbz);

1.63.2  –  Arguments

 mutex

    Address of the mutex object whose object name is to be changed.

 name

    Object name value to copy into the mutex object.

 mbz

    Reserved for future use. The value must be zero (0).

1.63.3  –  Description

    This routine changes the object name in the mutex object
    specified by the mutex argument to the value specified by the
    name argument. To set a new mutex object's object name, call this
    routine immediately after initializing the mutex object.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

1.63.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by mutex is not a valid mutex, or
                the length in characters of name exceeds 31.
    [ENOMEM]    Insufficient memory to create a copy of the object
                name string.

1.63.5  –  Associated Routines

       pthread_mutex_getname_np()

1.64  –  pthread_mutex_trylock

    Attempts to lock the specified mutex. If the mutex is already
    locked, the calling thread does not wait for the mutex to become
    available.

1.64.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutex_trylock (
             pthread_mutex_t   *mutex);

1.64.2  –  Arguments

 mutex

    Mutex to be locked.

1.64.3  –  Description

    This routine attempts to lock the mutex specified in the mutex
    argument. When a thread calls this routine, an attempt is made to
    immediately lock the mutex. If the mutex is successfully locked,
    this routine returns zero (0) and the calling thread becomes the
    mutex's current owner. If the specified mutex is locked when a
    thread calls this routine, the calling thread does not wait for
    the mutex to become available.

    The behavior of this routine is as follows:

    o  For a normal, default, or errorcheck mutex: if the mutex
       is locked by any thread (including the calling thread) when
       this routine is called, this routine returns [EBUSY] and the
       calling thread does not wait to acquire the lock.

    o  For a normal or errorcheck mutex: if the mutex is not owned,
       this routine returns zero (0) and the mutex becomes locked by
       the calling thread.

    o  For a recursive mutex: if the mutex is owned by the current
       thread, this routine returns zero (0) and the mutex lock count
       is incremented. (To unlock a recursive mutex, each call to
       pthread_mutex_trylock() must be matched by a call to pthread_
       mutex_unlock().)

    Use the pthread_mutexattr_settype() routine to set the mutex type
    attribute (normal, default, recursive, or errorcheck).

1.64.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EBUSY]     The mutex is already locked; therefore, it was not
                acquired.
    [EINVAL]    The value specified by mutex is not a valid mutex.

1.64.5  –  Associated Routines

       pthread_mutexattr_settype()
       pthread_mutex_destroy()
       pthread_mutex_init()
       pthread_mutex_lock()
       pthread_mutex_unlock()

1.65  –  pthread_mutex_unlock

    Unlocks the specified mutex.

1.65.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutex_unlock (
             pthread_mutex_t   *mutex);

1.65.2  –  Arguments

 mutex

    Mutex to be unlocked.

1.65.3  –  Description

    This routine unlocks the mutex specified by the mutex argument.

    This routine behaves as follows, based on the type of the
    specified mutex:

    o  For a normal, default, or errorcheck mutex: if the mutex is
       owned by the calling thread, it is unlocked with no current
       owner. Further, for a normal or default mutex: if the mutex
       is not locked or is locked by another thread, this routine
       can also return [EPERM], but this is not guaranteed. For an
       errorcheck mutex: if the mutex is not locked or is locked by
       another thread, this routine returns [EPERM].

    o  For a recursive mutex: if the mutex is owned by the calling
       thread, the lock count is decremented. The mutex remains
       locked and owned until the lock count reaches zero (0). When
       the lock count reaches zero, the mutex becomes unlocked with
       no current owner.

    If one or more threads are waiting to lock the specified mutex,
    and the mutex becomes unlocked, this routine causes one thread
    to unblock and to try to acquire the mutex. The scheduling policy
    is used to determine which thread to unblock. For the SCHED_FIFO
    and SCHED_RR policies, a blocked thread is chosen in priority
    order, using first-in/first-out within priorities. Note that the
    mutex might not be acquired by the awakened thread, if any other
    running thread attempts to lock the mutex first.

    On Tru64 UNIX, if a signal is delivered to a thread waiting for
    a mutex, upon return from the signal handler, the thread resumes
    waiting for the mutex as if it was not interrupted.

1.65.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified for mutex is not a valid mutex.
    [EPERM]     The calling thread does not own the mutex.

1.65.5  –  Associated Routines

       pthread_mutexattr_settype()
       pthread_mutex_destroy()
       pthread_mutex_init()
       pthread_mutex_lock()
       pthread_mutex_trylock()

1.66  –  pthread_mutexattr_destroy

    Destroys the specified mutex attributes object.

1.66.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutexattr_destroy (
             pthread_mutexattr_t   *attr);

1.66.2  –  Arguments

 attr

    Mutex attributes object to be destroyed.

1.66.3  –  Description

    This routine destroys a mutex attributes object-that is, the
    object becomes uninitialized. Call this routine when your program
    no longer needs the specified mutex attributes object.

    After this routine is called, the Threads Library may reclaim
    the storage used by the mutex attributes object. Mutexes that
    were created using this attributes object are not affected by the
    destruction of the mutex attributes object.

    The results of calling this routine are unpredictable, if the
    attributes object specified in the attr argument does not exist.

1.66.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid attributes
                object.

1.66.5  –  Associated Routines

       pthread_mutexattr_init()

1.67  –  pthread_mutexattr_gettype

    Obtains the mutex type attribute in the specified mutex attribute
    object.

1.67.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutexattr_gettype (
                const pthread_mutexattr_t   *attr,
                int   *type);

1.67.2  –  Arguments

 attr

    Mutex attributes object whose mutex type attribute is obtained.

 type

    Receives the value of the mutex type attribute. The type argument
    specifies the type of mutex that can be created. Valid values
    are:

       PTHREAD_MUTEX_NORMAL
       PTHREAD_MUTEX_DEFAULT (default)
       PTHREAD_MUTEX_RECURSIVE
       PTHREAD_MUTEX_ERRORCHECK

1.67.3  –  Description

    This routine obtains the value of the mutex type attribute in
    the mutex attributes object specified by the attr argument and
    stores it in the location specified by the type argument. See the
    pthread_mutexattr_settype() description for information about
    mutex types.

1.67.4  –  Return Values

    On successful completion, this routine returns the mutex type in
    the location specified by the type argument.

    If an error condition occurs, this routine returns an integer
    value indicating the type of the error. Possible return values
    are as follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid mutex
                attributes object.

1.67.5  –  Associated Routines

       pthread_mutexattr_init()
       pthread_mutexattr_settype()
       pthread_mutex_init()

1.68  –  pthread_mutexattr_init

    Initializes a mutex attributes object.

1.68.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutexattr_init (
             pthread_mutexattr_t   *attr);

1.68.2  –  Arguments

 attr

    Address of the mutex attributes object to be initialized.

1.68.3  –  Description

    This routine initializes the mutex attributes object specified
    by the attr argument with a set of default values. A mutex
    attributes object is used to specify the attributes of one or
    more mutexes when they are created. The attributes object created
    by this routine is used only in calls to the pthread_mutex_init()
    routine.

    When a mutex attributes object is used to create a mutex, the
    values of the individual attributes determine the characteristics
    of the new mutex. Thus, attributes objects act as additional
    arguments to mutex creation. Changing individual attributes
    in an attributes object does not affect any mutexes that were
    previously created using that attributes object.

    You can use the same mutex attributes object in successive calls
    to pthread_mutex_init(), from any thread. If multiple threads
    can change attributes in a shared mutex attributes object,
    your program must use a mutex to protect the integrity of the
    attributes object's contents.

    Results are undefined if this routine is called and the attr
    argument specifies a mutex attributes object that is already
    initialized.

1.68.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [ENOMEM]    Insufficient memory to create the mutex attributes
                object.

1.68.5  –  Associated Routines

       pthread_mutexattr_destroy()
       pthread_mutexattr_gettype()
       pthread_mutexattr_settype()
       pthread_mutex_init()

1.69  –  pthread_mutexattr_settype

    Specifies the mutex type attribute that is used when a mutex is
    created.

1.69.1  –  C Binding

    #include <pthread.h>

    int
    pthread_mutexattr_settype (
             pthread_mutexattr_t   *attr,
             int   type);

1.69.2  –  Arguments

 attr

    Mutex attributes object whose mutex type attribute is to be
    modified.

 type

    New value for the mutex type attribute. The type argument
    specifies the type of mutex that will be created. Valid values
    are:

       PTHREAD_MUTEX_NORMAL
       PTHREAD_MUTEX_DEFAULT (default)
       PTHREAD_MUTEX_RECURSIVE
       PTHREAD_MUTEX_ERRORCHECK

1.69.3  –  Description

    This routine sets the mutex type attribute that is used to
    determine which type of mutex is created based on a subsequent
    call to pthread_mutex_init().

1.69.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr or type is not a valid
                mutex attributes type.
    [ESRCH]     The value specified by attr does not refer to an
                existing mutex attributes object.

1.69.5  –  Associated Routines

       pthread_mutexattr_init()
       pthread_mutexattr_gettype()
       pthread_mutex_init()

1.70  –  pthread_once

    Calls a routine that is executed by a single thread, once.

1.70.1  –  C Binding

    #include <pthread.h>

    int
    pthread_once (
             pthread_once_t   *once_control,
             void   (*routine) (void));

1.70.2  –  Arguments

 once_control

    Address of a record that controls the one-time execution code.
    Each one-time execution routine must have its own unique pthread_
    once_t record.

 routine

    Address of a procedure to be executed once. This routine is
    called only once, regardless of the number of times it and its
    associated once_control block are passed to pthread_once().

1.70.3  –  Description

    The first call to this routine by any thread in a process with
    a given once_control will call the specified routine with no
    arguments. Subsequent calls to pthread_once() with the same once_
    control will not call the routine. On return from pthread_once(),
    it is guaranteed that the routine has completed.

    For example, a mutex or a per-thread context key must be
    created exactly once. Calling pthread_once() ensures that the
    initialization is serialized across multiple threads. Other
    threads that reach the same point in the code would be delayed
    until the first thread is finished.

                                   NOTE

       If you specify a routine that directly or indirectly results
       in a recursive call to pthread_once() and that specifies the
       same routine argument, the recursive call can result in a
       deadlock.

    To initialize the once_control record, your program can zero out
    the entire structure, or you can use the PTHREAD_ONCE_INIT macro,
    which is defined in the pthread.h header file, to statically
    initialize that structure. If using PTHREAD_ONCE_INIT, declare
    the once_control record as follows:

    pthread_once_t  once_control = PTHREAD_ONCE_INIT;

    Note that it is often easier to simply lock a statically
    initialized mutex, check a control flag, and perform necessary
    initialization (in-line) rather than using pthread_once(). For
    example, you can code an initialization routine that begins with
    the following basic logic:

      init()
      {
       static pthread_mutex_t    mutex = PTHREAD_MUTEX_INITIALIZER;
       static int                flag = FALSE;

       pthread_mutex_lock(&mutex);
       if(!flag)
         {
          /* initialization code goes here */
          flag = TRUE;
         }
       pthread_mutex_unlock(&mutex);
      }

1.70.4  –  Return Values

    If an error occurs, this routine returns an integer indicating
    the type of error. Possible return values are as follows:

    Return      Description

    0           Successful completion
    [EINVAL]    Invalid argument

1.71  –  pthread_rwlock_destroy

    Destroys a read-write lock object.

1.71.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_destroy (
             pthread_rwlock_t   *rwlock);

1.71.2  –  Arguments

 rwlock

    Address of the read-write lock object to be destroyed.

1.71.3  –  Description

    This routine destroys the specified read-write lock object by
    uninitializing it, and should be called when the object is no
    longer referenced in your program. After this routine is called,
    the Threads Library may reclaim internal storage used by the
    specified read-write lock object. The effect of subsequent use of
    the lock is undefined until the lock is reinitialized by another
    call to pthread_rwlock_init().

    It is illegal to destroy a locked read-write lock.

    The results of this routine are unpredictable if the specified
    read-write lock object does not currently exist or is not
    initialized. This routine destroys the read-write lock object
    specified by the rwlock argument and releases any resources that
    the object used.

    A destroyed read-write lock object can be reinitialized using the
    pthread_rwlock_init() routine. The results of otherwise
    referencing a destroyed read-write lock object are undefined.

1.71.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EBUSY]     An attempt was made to destroy the object referenced
                by rwlock while it is locked or referenced.

1.71.5  –  Associated Routines

       pthread_rwlock_init()

1.72  –  pthread_rwlock_getname_np

    Obtains the object name from a read-write lock object.

1.72.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_getname_np (
             pthread_rwlock_t   *rwlock,
             char   *name,
             size_t   len);

1.72.2  –  Arguments

 rwlock

    Address of the read-write lock object whose object name is to be
    obtained.

 name

    Location to store the obtained object name.

 len

    Length in bytes of buffer at the location specified by name.

1.72.3  –  Description

    This routine copies the object name from the read-write lock
    object specified by rwlock to the buffer at the location name.
    Before calling this routine, your program must allocate the
    buffer indicated by name.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    If the specified read-write lock object has not been previously
    set with an object name, this routine copies a C language null
    string into the buffer at location name.

1.72.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by rwlock is not a valid read-
                write lock.

1.72.5  –  Associated Routines

       pthread_rwlock_setname_np()

1.73  –  pthread_rwlock_init

    Initializes a read-write lock object.

1.73.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_init (
             pthread_rwlock_t   *rwlock,
             const pthread_rwlockattr_t   *attr);

1.73.2  –  Arguments

 rwlock

    Read-write lock object to be initialized.

 attr

    Read-write lock attributes object that defines the
    characteristics of the read-write lock to be initialized.

1.73.3  –  Description

    This routine initializes a read-write lock object with the
    attributes specified by the read-write lock attributes object
    specified in attr. A read-write lock is a synchronization object
    that serializes access to shared information that needs to be
    read frequently and written only occasionally. A thread can
    acquire a read-write lock for shared read access or for exclusive
    write access.

    Upon successful completion of this routine, the read-write lock
    is initialized and set to the unlocked state. If attr is set to
    NULL, the default read-write lock attributes are used; the effect
    is the same as passing the address of a default read-write lock
    attributes object. Once initialized, the lock can be used any
    number of times without being reinitialized.

    Results of calling this routine are undefined if attr specifies
    an already initialized read-write lock or if rwlock is used
    without first being initialized.

    If this routine returns unsuccessfully, rwlock is not initialized
    and the contents of rwlock are undefined.

    A read-write lock is a resource of the process, not part of any
    particular thread. A read-write lock is neither destroyed not
    unlocked automatically when any thread exits. Because read-write
    locks are shared, they may be allocated in heap or static memory,
    but not on a stack.

    In cases where default read-write lock attributes are
    appropriate, you may use the PTHREAD_RWLOCK_INITIALIZER macro
    to statically initialize the lock object without calling this
    routine. The effect is equivalent to dynamic initialization by
    a call to pthread_rwlock_init() with attr specified as NULL,
    except that no error checks are performed. Statically initialized
    read-write locks need not be destroyed using pthread_rwlock_
    destroy().

    Use the PTHREAD_RWLOCK_INITIALIZER macro as follows:

    pthread_rwlock_t rwlock= PTHREAD_RWLOCK_INITIALIZER;

1.73.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacks the necessary resources to
                initialize the read-write lock.
    [EBUSY]     The Threads Library has detected an attempt to
                reinitialize the read-write lock (a previously
                initialized, but not yet destroyed, read-write lock
                object).
    [EINVAL]    The value specified by attr is not a valid attributes
                block.
    [ENOMEM]    Insufficient memory exists to initialize the read-
                write lock.
    [EPERM]     The caller does not have privileges to perform this
                operation.

1.73.5  –  Associated Routines

       pthread_rwlock_destroy()

1.74  –  pthread_rwlock_rdlock

    Acquires a read-write lock object for read access.

1.74.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_rdlock (
             pthread_rwlock_t   *rwlock);

1.74.2  –  Arguments

 rwlock

    Address of the read-write lock object to acquire for read access.

1.74.3  –  Description

    This routine acquires a read-write lock for read access. If no
    thread already holds the lock for write access and there are no
    writers waiting to acquire the lock, the lock for read access
    is granted to the calling thread and this routine returns. If
    a thread already holds the lock for read access, the lock is
    granted and this routine returns.

    A thread can hold multiple, concurrent locks for read access on
    the same read-write lock. In a given thread, for each call to
    this routine that successfully acquires the same read-write lock
    for read access, a corresponding call to pthread_rwlock_unlock
    must be issued.

    If some thread already holds the lock for write access, the
    calling thread will not acquire the read lock. If the read lock
    is not acquired, the calling thread blocks until it can acquire
    the lock for read access. Results are undefined if the calling
    thread has already acquired a lock for write access on rwlock
    when this routine is called.

    If the read-write lock object referenced by rwlock is not
    initialized, the results of calling this routine are undefined.

    If a thread is interrupted (via a Tru64 UNIX signal or an OpenVMS
    AST) while waiting for a read-write lock for read access, upon
    return from the interrupt routine the thread resumes waiting for
    the lock as if it had not been interrupted.

1.74.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion; the read-write lock object was
                acquired for read access.
    [EINVAL]    The value specified by rwlock does not refer to an
                initialized read-write lock object.
    [EDEADLCK]  The calling thread already owns the specified read-
                write lock object for write access.
    [EAGAIN]    The lock for read access could not be acquired
                because the maximum number of read lock acquisitions
                for rwlock has been exceeded.

1.74.5  –  Associated Routines

       pthread_rwlock_init()
       pthread_rwlockattr_init()
       pthread_rwlock_tryrdlock()
       pthread_rwlock_wrlock()
       pthread_rwlock_unlock()

1.75  –  pthread_rwlock_setname_np

    Changes the object name in a read-write lock object.

1.75.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_setname_np (
             pthread_rwlock_t   *rwlock,
             const char   *name,
             void   *mbz);

1.75.2  –  Arguments

 rwlock

    Address of the read-write lock object whose object name is to be
    changed.

 name

    Object name value to copy into the read-write lock object.

 mbz

    Reserved for future use. The value must be zero (0).

1.75.3  –  Description

    This routine changes the object name in the read-write lock
    object specified by rwlock to the value specified by name. To
    set a new read-write lock object's object name, call this routine
    immediately after initializing the read-write lock object.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

1.75.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion, the read-write lock object was
                acquired for read access.
    [EINVAL]    The value specified by rwlock is invalid, or the
                length in characters of name exceeds 31.
    [ENOMEM]    Insufficient memory to create a copy of the object
                name string.

1.75.5  –  Associated Routines

       pthread_rwlock_getname_np()
       pthread_rwlock_init()

1.76  –  pthread_rwlock_tryrdlock

    Attempts to acquire a read-write lock object for read access
    without waiting.

1.76.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_tryrdlock (
             pthread_rwlock_t    *rwlock);

1.76.2  –  Arguments

 rwlock

    Address of the read-write lock object to acquire for read access.

1.76.3  –  Description

    This routine attempts to acquire a read-write lock for read
    access, but does not wait for the lock if it not immediately
    available.

    If no thread already holds the lock for write access and there
    are no writers waiting to acquire the lock, the lock for read
    access is granted to the calling thread and this routine returns.
    If a thread already holds the lock for read access, the lock is
    granted and this routine returns.

    If some thread already holds the lock for write access, the
    calling thread will not acquire the read lock. Results are
    undefined if the calling thread has already acquired a lock for
    write access on rwlock when this routine is called.

    A thread can hold multiple, concurrent locks for read access on
    the same read-write lock. In a given thread, for each call to
    this routine that successfully acquires the same read-write lock
    for read access, a corresponding call to pthread_rwlock_unlock()
    must be issued.

    If the read-write lock object referenced by rwlock is not
    initialized, the results of calling this routine are undefined.

1.76.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion; the read-write lock object was
                acquired for read access.
    [EAGAIN]    The lock for read access could not be acquired
                because the maximum number of read lock acquisitions
                for rwlock has been exceeded.
    [EBUSY]     The read-write lock could not be acquired for read
                access because another thread already acquired it
                for write access or is blocked and waiting for it for
                write access.
    [EDEADLCK]  The current thread already owns the read-write lock
                for writing.
    [EINVAL]    The value specified by rwlock does not refer to an
                initialized read-write lock object.

1.76.5  –  Associated Routines

       pthread_rwlockattr_init()
       pthread_rwlock_init()
       pthread_rwlock_rdlock()
       pthread_rwlock_unlock()
       pthread_rwlock_wrlock()

1.77  –  pthread_rwlock_trywrlock

    Attempts to acquire a read-write lock object for write access
    without waiting.

1.77.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_trywrlock (
             pthread_rwlock_t   *rwlock);

1.77.2  –  Arguments

 rwlock

    Address of the read-write lock object to acquire for write
    access.

1.77.3  –  Description

    This routine attempts to acquire the read-write lock referenced
    by rwlock for write access. If any thread already holds that lock
    for write access or read access, this routine fails and returns
    [EBUSY] and the calling thread does not wait for the lock to
    become available.

    Results are undefined if the calling thread holds the read-write
    lock (whether for read or write access) at the time this routine
    is called.

    If the read-write lock object referenced by rwlock is not
    initialized, the results of calling this routine are undefined.

    Realtime applications can encounter priority inversion when using
    read-write locks. The problem occurs when a high-priority thread
    acquires a read-write lock that is about to be unlocked (that
    is, posted) by a low-priority thread, but the low-priority thread
    is preempted by a medium-priority thread. This scenario leads to
    priority inversion in that a high-priority thread is blocked by
    lower-priority threads for an unlimited period of time. During
    system design, realtime programmers must take into account the
    possibility of priority inversion and can deal with it in a
    number of ways, such as by having critical sections that are
    guarded by read-write locks execute at a high priority, so that
    a thread cannot be preempted while executing in its critical
    section.

1.77.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion, the read-write lock object was
                acquired for write access.
    [EBUSY]     The read-write lock could not be acquired for write
                access because it was already locked for write access
                or for read access.
    [EDEADLCK]  The current thread already owns the read-write lock
                for write or read access.
    [EINVAL]    The value specified by rwlock does not refer to an
                initialized read-write lock object.

1.77.5  –  Associated Routines

       pthread_rwlockattr_init()
       pthread_rwlock_init()
       pthread_rwlock_rdlock()
       pthread_rwlock_unlock()
       pthread_rwlock_wrlock()

1.78  –  pthread_rwlock_unlock

    Unlocks a read-write lock object.

1.78.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_unlock (
             pthread_rwlock_t   *rwlock);

1.78.2  –  Arguments

 rwlock

    Address of the read-write lock object to be unlocked.

1.78.3  –  Description

    This routine releases a lock acquisition held on the read-write
    lock object referenced by rwlock. Results are undefined if rwlock
    is not held by the calling thread.

    If this routine is called to release a lock for read access on
    rwlock and the calling thread also currently holds other locks
    for read access on rwlock, the read-write lock object remains
    in the read locked state. If this routine releases the calling
    thread's last lock for read access on rwlock, the calling thread
    is no longer one of the owners of the lock object.

    If this routine is called to release a lock for write access
    on rwlock, the lock object is put in the unlocked state with no
    owners.

    If a call to this routine results in the read-write lock object
    becoming unlocked and there are multiple threads waiting to
    acquire that lock for write access, the Threads Library uses
    the scheduling policy of those waiting threads to determine
    which thread next acquires the lock object for write access. If
    there are multiple threads waiting to acquire the read-write lock
    object for read access, the Threads Library uses the scheduling
    policy of those waiting threads to determine the order in which
    those threads acquire the lock for read access. If there are
    multiple threads waiting to acquire the read-write lock object
    for both read and write access, it is unspecified whether a
    thread waiting for read access or for write access next acquires
    the lock object.

    If the read-write lock object referenced by rwlock is not
    initialized, the results of calling this routine are undefined.

1.78.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The values specified by rwlock does not refer to an
                initialized read-write lock object.
    [EPERM]     The calling thread does not hold the read-write lock
                object.

1.78.5  –  Associated Routines

       pthread_rwlockattr_init()
       pthread_rwlock_init()
       pthread_rwlock_rdlock()
       pthread_rwlock_wrlock()

1.79  –  pthread_rwlock_wrlock

    Acquires a read-write lock for write access.

1.79.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlock_wrlock (
             pthread_rwlock_t   *rwlock);

1.79.2  –  Arguments

 rwlock

    Address of the read-write lock object to acquire for write
    access.

1.79.3  –  Description

    This routine attempts to acquire a read-write lock for write
    access. If any thread already has acquired the lock for write
    access or read access, the lock is not granted and the calling
    thread blocks until it can acquire the lock. A thread can hold
    only one lock for write access on a read-write lock.

    Results are undefined if the calling thread holds the read-write
    lock (whether for read or write access) at the time this routine
    is called.

    If the read-write lock object referenced by rwlock is not
    initialized, the results of calling this routine are undefined.

    If a thread is interrupted (via a Tru64 UNIX signal or an OpenVMS
    AST) while waiting for a read-write lock for write access, upon
    return from the interrupt routine the thread resumes waiting for
    the lock as if it had not been interrupted.

    Realtime applications can encounter priority inversion when using
    read-write locks. The problem occurs when a high-priority thread
    acquires a read-write lock that is about to be unlocked (that
    is, posted) by a low-priority thread, but the low-priority thread
    is preempted by a medium-priority thread. This scenario leads to
    priority inversion in that a high-priority thread is blocked by
    lower-priority threads for an unlimited period of time. During
    system design, realtime programmers must take into account the
    possibility of priority inversion and can deal with it in a
    number of ways, such as by having critical sections that are
    guarded by read-write locks execute at a high priority, so that
    a thread cannot be preempted while executing in its critical
    section.

1.79.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion, the read-write lock object was
                acquired for write access.
    [EDEADLCK]  The calling thread already owns the read-write lock
                for write or read access.
    [EINVAL]    The value specified by rwlock does not refer to an
                initialized read-write lock object.

1.79.5  –  Associated Routines

       pthread_rwlockattr_init()
       pthread_rwlock_init()
       pthread_rwlock_rdlock()
       pthread_rwlock_trywrlock()
       pthread_rwlock_unlock()

1.80  –  pthread_rwlockattr_destroy

    Destroys a previously initialized read-write lock attributes
    object.

1.80.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlockattr_destroy (
             pthread_rwlockattr_t   *attr);

1.80.2  –  Arguments

 attr

    Address of the read-write lock attributes object to be destroyed.

1.80.3  –  Description

    This routine destroys the read-write lock attributes object
    referenced by attr; that is, the object becomes uninitialized.

    After successful completion of this routine, the results of using
    attr in a call to any routine (other than pthread_rwlockattr_
    init()) are unpredictable.

1.80.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by attr is not a valid attributes
                block.

1.80.5  –  Associated Routines

       pthread_rwlockattr_init()
       pthread_rwlock_init()

1.81  –  pthread_rwlockattr_init

    Initializes a read-write lock attributes object.

1.81.1  –  C Binding

    #include <pthread.h>

    int
    pthread_rwlockattr_init (
             pthread_rwlockattr_t   *attr);

1.81.2  –  Arguments

 attr

    Address of the read-write lock attributes object to be
    initialized.

1.81.3  –  Description

    This routine initializes the read-write lock attributes object
    referenced by attr and sets its attributes with default values.

    The results of calling this routine are undefined if attr
    references an already initialized read-write lock attributes
    object.

    After an initialized read-write lock attributes object has been
    used to initialize one or more read-write lock objects, any
    operation on that attributes object (including destruction) has
    no effect on those read-write lock objects.

1.81.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion
    [ENOMEM]    Insufficient memory to initialize the read-write lock
                attributes object

1.81.5  –  Associated Routines

       pthread_rwlockattr_destroy()
       pthread_rwlock_init()

1.82  –  pthread_self

    Obtains the identifier of the calling thread.

1.82.1  –  C Binding

    #include <pthread.h>

    pthread_t
    pthread_self (void);

1.82.2  –  Arguments

    None

1.82.3  –  Description

    This routine returns the address of the calling thread's own
    thread identifier. For example, you can use this thread object
    to obtain the calling thread's own sequence number. To do so,
    pass the return value from this routine in a call to the pthread_
    getsequence_np() routine, as follows:

       .
       .
       .
       unsigned long     this_thread_nbr;
       .
       .
       .
       this_thread_nbr = pthread_getsequence_np( pthread_self( ) );
       .
       .
       .

    The return value from the pthread_self() routine becomes
    meaningless after the calling thread is destroyed.

1.82.4  –  Return Values

    Returns the address of the calling thread's own thread object.

1.82.5  –  Associated Routines

       pthread_cancel()
       pthread_create()
       pthread_detach()
       pthread_exit()
       pthread_getsequence_np()
       pthread_join()
       pthread_kill()
       pthread_sigmask()

1.83  –  pthread_setcancelstate

    Sets the calling thread's cancelability state.

1.83.1  –  C Binding

    #include <pthread.h>

    int
    pthread_setcancelstate (
             int   state,
             int   *oldstate );

1.83.2  –  Arguments

 state

    State of general cancelability to set for the calling thread. The
    following are valid cancel state values:

       PTHREAD_CANCEL_ENABLE
       PTHREAD_CANCEL_DISABLE

 oldstate

    Previous cancelability state for the calling thread.

1.83.3  –  Description

    This routine sets the calling thread's cancelability state and
    returns the calling thread's previous cancelability state in
    oldstate.

    When cancelability state is set to PTHREAD_CANCEL_DISABLE, a
    cancelation request cannot be delivered to the thread, even if a
    cancelable routine is called or asynchronous cancelability type
    is enabled.

    When a thread is created, its default cancelability state is
    PTHREAD_CANCEL_ENABLE.
    Possible Problems When Disabling Cancelability
    The most important use of thread cancelation is to ensure
    that indefinite wait operations are terminated. For example, a
    thread that waits on some network connection, which can possibly
    take days to respond (or might never respond), should be made
    cancelable.

    When a thread's cancelability is disabled, no routine in that
    thread is cancelable. As a result, the user is unable to
    cancel the operation performed by that thread. When disabling
    cancelability, be sure that no long waits can occur or that it is
    necessary for other reasons to defer cancelation requests around
    that particular region of code.

1.83.4  –  Return Values

    On successful completion, this routine returns the calling
    thread's previous cancelability state in the location specified
    by the oldstate argument.

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The specified state is not PTHREAD_CANCEL_ENABLE or
                PTHREAD_CANCEL_DISABLE.

1.83.5  –  Associated Routines

       pthread_cancel()
       pthread_setcanceltype()
       pthread_testcancel()

1.84  –  pthread_setcanceltype

    Sets the calling thread's cancelability type.

1.84.1  –  C Binding

    #include <pthread.h>

    int
    pthread_setcanceltype (
                int   type,
                int   *oldtype);

1.84.2  –  Arguments

 type

    The cancelability type to set for the calling thread. The
    following are valid values:

       PTHREAD_CANCEL_DEFERRED
       PTHREAD_CANCEL_ASYNCHRONOUS

 oldtype

    Returns the previous cancelability type.

1.84.3  –  Description

    This routine sets the cancelability type and returns the previous
    type in location oldtype.

    When a thread's cancelability state is set to PTHREAD_CANCEL_
    DISABLE, (see pthread_setcancelstate()), a cancelation request
    cannot be delivered to that thread, even if a cancelable routine
    is called or asynchronous cancelability type is enabled.

    When the cancelability state is set to PTHREAD_CANCEL_ENABLE,
    cancelability depends on the thread's cancelability type, as
    follows:

    o  If the thread's cancelability type is PTHREAD_CANCEL_DEFERRED,
       the thread can only receive a cancelation request at a
       cancelation point (including condition waits, thread joins,
       and calls to pthread_testcancel()).

    o  If the thread's cancelability type is PTHREAD_CANCEL_
       ASYNCHRONOUS, the thread can be canceled at any point in its
       execution.

    When a thread is created, the default cancelability type is
    PTHREAD_CANCEL_DEFERRED.

                                 CAUTION

       If the asynchronous cancelability type is set, do not call
       any routine unless it is explicitly documented as "safe for
       asynchronous cancelation." Note that none of the general
       run-time libraries and none of the POSIX Threads libraries
       are safe for asynchronous cancelation except for pthread_
       setcanceltype() and pthread_setcancelstate().

       Use asynchronous cancelability only when you have a compute-
       bound section of code that carries no state and makes no
       routine calls.

1.84.4  –  Return Values

    On successful completion, this routine returns the previous
    cancelability type in oldtype.

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The specified type is not PTHREAD_CANCEL_DEFERRED or
                PTHREAD_CANCEL_AYNCHRONOUS.

1.84.5  –  Associated Routines

       pthread_cancel()
       pthread_setcancelstate()
       pthread_testcancel()

1.85  –  pthread_setconcurrency

    Changes the value of the concurrency level global variable for
    this process.

1.85.1  –  C Binding

    #include <pthread.h>

    int
    pthread_setconcurrency (
                int   level);

1.85.2  –  Arguments

 level

    New value for the concurrency level for this process.

1.85.3  –  Description

    This routine stores the value specified in the level argument in
    the "concurrency level" global setting for the calling thread's
    process. Because the Threads Library automatically manages the
    concurrency of all threads in a multithreaded process, it ignores
    this concurrency level value.

    "Concurrency level" is a parameter used to coerce "simple" 2-
    level schedulers into allowing application concurrency. The
    Threads Library supplies the maximum concurrency at all times,
    automatically. It has no need for coercion, and calls pthread_
    setconcurrency() merely to determine the value returned by the
    next call to pthread_getconcurrency().

    The concurrency level value has no effect on the behavior of a
    multithreaded program that uses the Threads Library. This routine
    is provided for Single UNIX Specification, Version 2 source code
    compatibility and has no other effect when called.

    After calling this routine, subsequent calls to the pthread_
    getconcurrency() routine return the same value, until another
    call to pthread_setconcurrency() changes that value.

    The initial concurrency level is zero (0), indicating that the
    Threads Library manages the concurrency level. To indicate in a
    portable manner that the implementation is to resume control of
    concurrency level, call this routine with a level argument of
    zero (0).

    The concurrency level value can be obtained using the pthread_
    getconcurrency() routine.

1.85.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The value specified by new_level would cause a system
                resource to be exceeded.
    [EINVAL]    The value specified by new_level is negative.

1.85.5  –  Associated Routines

       pthread_getconcurrency()

1.86  –  pthread_setname_np

    Changes the object name in the thread object for an existing
    thread.

1.86.1  –  C Binding

    #include <pthread.h>

    int
    pthread_setname_np (
             pthread_thread_t   thread,
             const char   *name,
             void   *mbz);

1.86.2  –  Arguments

 thread

    Thread object whose object name is to be changed.

 name

    Object name value to copy into the thread object.

 mbz

    Reserved for future use. The value must be zero (0).

1.86.3  –  Description

    This routine changes the object name in the thread object for the
    thread specified by the thread argument to the value specified
    by the name argument. To set an existing thread's object name,
    call this routine after creating the thread. However, with this
    approach your program must account for the possibility that the
    target thread either has already exited or has been canceled
    before this routine is called.

    The object name is a C language string and provides an identifier
    that is meaningful to a person debugging a multithreaded
    application. The maximum number of characters in the object name
    is 31.

    This routine contrasts with pthread_attr_setname_np(), which
    changes the object name attribute in a thread attributes object
    that is used to create a new thread.

1.86.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The length in characters of name exceeds 31.
    [ENOMEM]    Insufficient memory to create a copy of the object
                name string.
    [ESRCH]     The thread specified by thread does not exist.

1.86.5  –  Associated Routines

       pthread_attr_getname_np()
       pthread_attr_setname_np()
       pthread_getname_np()

1.87  –  pthread_setschedparam

    Changes a thread's scheduling policy and scheduling parameters.

1.87.1  –  C Binding

    #include <pthread.h>

    int
    pthread_setschedparam (
             pthread_t   thread,
             int   policy,
             const struct sched_param   *param);

1.87.2  –  Arguments

 thread

    Thread whose scheduling policy and parameters are to be changed.

 policy

    New scheduling policy value for the thread specified in thread.
    The following are valid values:

       SCHED_BG_NP
       SCHED_FG_NP
       SCHED_FIFO
       SCHED_OTHER
       SCHED_RR

 param

    New values of the scheduling parameters associated with the
    scheduling policy for the thread specified in thread. Valid
    values for the sched_priority field of a sched_param structure
    depend on the chosen scheduling policy. Use the POSIX routines
    sched_get_priority_min() or sched_get_priority_max()  to
    determine the low and high limits of each policy.

    Additionally, the Threads Librray provides nonportable priority
    range constants, as follows:

    Low              High

    PRI_FIFO_MIN     PRI_FIFO_MAX
    PRI_RR_MIN       PRI_RR_MAX
    PRI_OTHER_MIN    PRI_OTHER_MAX
    PRI_FG_MIN_NP    PRI_FG_MAX_NP
    PRI_BG_MIN_NP    PRI_BG_MAX_NP

    The default priority varies by platform. On Tru64 UNIX, the
    default is 19 (that is, the POSIX priority of a normal timeshare
    process). On other platforms the default priority is the midpoint
    between PRI_FG_MIN_NP and PRI_FG_MAX_NP.

1.87.3  –  Description

    This routine changes both the current scheduling policy and
    associated scheduling parameters of the thread specified by
    thread to the policy and associated parameters provided in policy
    and param, respectively.

    All currently implemented scheduling policies have one scheduling
    parameter called sched_priority. For the policy you choose, you
    must specify an appropriate value in the sched_priority field of
    the sched_param structure.

    Changing the scheduling policy or priority, or both, of a thread
    can cause it either to start executing or to be preempted by
    another thread. A thread changes its own scheduling policy and
    priority by using the handle returned by the pthread_self()
    routine.

    This routine differs from pthread_attr_setschedpolicy() and
    pthread_attr_setschedparam(), in that those routines set the
    scheduling policy and parameter attributes that are used to
    establish the scheduling priority and scheduling policy of a
    new thread when it is created. However, this routine changes the
    scheduling policy and parameters of an existing thread.

1.87.4  –  Return Values

    If an error condition occurs, no scheduling policy or parameters
    are changed for the target thread, and this routine returns
    an integer value indicating the type of error. Possible return
    values are as follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by policy or param is invalid.
    [ENOTSUP]   An attempt was made to set the scheduling policy or a
                parameter to an unsupported value.
    [EPERM]     The caller does not have the appropriate privileges
                to set the scheduling policy or parameters of the
                specified thread.
    [ESRCH]     The value specified by thread does not refer to an
                existing thread.

1.87.5  –  Associated Routines

       pthread_attr_setschedparam()
       pthread_attr_setschedpolicy()
       pthread_create()
       pthread_self()
       sched_yield()

1.88  –  pthread_setspecific

    Sets the thread-specific data value associated with the specified
    key for the calling thread.

1.88.1  –  C Binding

    #include <pthread.h>

    int
    pthread_setspecific (
             pthread_key_t   key,
             const void   *value);

1.88.2  –  Arguments

 key

    Thread-specific key that identifies the thread-specific data to
    receive value. This key value must be obtained from pthread_key_
    create().

 value

    New thread-specific data value to associate with the specified
    key for the calling thread.

1.88.3  –  Description

    This routine sets the thread-specific data value associated with
    the specified key for the current thread. If a value is defined
    for the key in this thread (the current value is not NULL),
    the new value is substituted for it. The key is obtained by a
    previous call to pthread_key_create().

    Different threads can bind different values to the same key.
    These values are typically pointers to blocks of dynamically
    allocated memory that are reserved for use by the calling thread.

    Do not call this routine from a thread-specific data destructor
    function.

    Note that although the type for value (void *) implies that it
    represents an address, the type is being used as a "universal
    scalar type." The Threads Library simply stores value for later
    retrieval.

1.88.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The specified key is invalid.
    [ENOMEM]    Insufficient memory to associate the value with the
                key.

1.88.5  –  Associated Routines

       pthread_getspecific()
       pthread_key_create()
       pthread_key_delete()

1.89  –  pthread_testcancel

    Requests delivery of a pending cancelation request to the calling
    thread.

1.89.1  –  C Binding

    #include <pthread.h>

    void
    pthread_testcancel (void);

1.89.2  –  Arguments

    None

1.89.3  –  Description

    This routine requests delivery of a pending cancelation request
    to the calling thread. Thus, calling this routine creates a
    cancelation point within the calling thread.

    The cancelation request is delivered only if a request is pending
    for the calling thread and the calling thread's cancelability
    state is enabled. (A thread disables delivery of cancelation
    requests to itself by calling pthread_setcancelstate().)

    When called within very long loops, this routine ensures that
    a pending cancelation request is noticed by the calling thread
    within a reasonable amount of time.

1.89.4  –  Return Values

    None

1.89.5  –  Associated Routines

       pthread_setcancelstate()

1.90  –  pthread_unlock_global_np

    Unlocks the Threads Library global mutex.

1.90.1  –  C Binding

    #include <pthread.h>

    int
    pthread_unlock_global_np (void);

1.90.2  –  Arguments

    None

1.90.3  –  Description

    This routine unlocks the Threads Library global mutex. Because
    the global mutex is recursive, the unlock occurs when each call
    to pthread_lock_global_np() has been matched by a call to this
    routine. For example, if you called pthread_lock_global_np()
    three times, pthread_unlock_global_np() unlocks the global mutex
    when you call it the third time.

    If no threads are waiting for the global mutex, it becomes
    unlocked with no current owner. If one or more threads are
    waiting to lock the global mutex, this routine causes one thread
    to unblock and to try to acquire the global mutex. The scheduling
    policy is used by this routine to determine which thread is
    awakened. For the policies SCHED_FIFO and SCHED_RR, a blocked
    thread is chosen in priority order, using first-in/first-out
    (FIFO) within priorities.

1.90.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EPERM]     The mutex is unlocked or owned by another thread.

1.90.5  –  Associated Routines

       pthread_lock_global_np()

1.91  –  pthread_yield_np

    Notifies the scheduler that the current thread is willing to
    release its processor to other threads of the same or higher
    priority.

    Syntax

      pthread_yield_np();

1.91.1  –  C Binding

    int
    pthread_yield_np (void);

1.91.2  –  Arguments

    None

1.91.3  –  Description

    This routine notifies the thread scheduler that the current
    thread is willing to release its processor to other threads of
    equivalent or greater scheduling precedence. (A thread generally
    will release its processor to a thread of a greater scheduling
    precedence without calling this routine.) If no other threads of
    equivalent or greater scheduling precedence are ready to execute,
    the thread continues.

    This routine can allow knowledge of the details of an application
    to be used to improve its performance. If a thread does not call
    pthread_yield_np(), other threads may be given the opportunity
    to run at arbitrary points (possibly even when the interrupted
    thread holds a required resource). By making strategic calls to
    pthread_yield_np(), other threads can be given the opportunity
    to run when the resources are free. This improves performance by
    reducing contention for the resource.

    As a general guideline, consider calling this routine after a
    thread has released a resource (such as a mutex) which is heavily
    contended for by other threads. This can be especially important
    either if the program is running on a uniprocessor machine, or
    if the thread acquires and releases the resource inside a tight
    loop.

    Use this routine carefully and sparingly, because misuse can
    cause unnecessary context switching which will increase overhead
    and actually degrade performance. For example, it is counter-
    productive for a thread to yield while it holds a resource that
    the threads to which it is yielding will need. Likewise, it is
    pointless to yield unless there is likely to be another thread
    that is ready to run.

                                   NOTE

       pthread_yield_np() is equivalent to sched_yield(). Use
       sched_yield() since it is part of the standard portable
       POSIX Threads Library.

1.91.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [ENOSYS]    The routine pthread_yield_np()  is not supported by
                this implementation.

1.91.5  –  Associated Routines

       pthread_attr_setschedparam()
       pthread_getschedparam()
       pthread_setschedparam()

1.92  –  sched_get_priority_max

    Returns the maximum priority for the specified scheduling policy.

    Syntax

      sched_get_priority_max(

                             policy);

      Argument       Data Type            Access

      policy         integer              read

1.92.1  –  C Binding

    #include <sched.h>

    int
    sched_get_priority_max (
                int   policy);

1.92.2  –  Arguments

 policy

    One of the scheduling policies, as defined in sched.h.

1.92.3  –  Description

    This routine returns the maximum priority for the scheduling
    policy specified in the policy argument. The argument value
    must be one of the scheduling policies (SCHED_FIFO, SCHED_RR,
    or SCHED_OTHER), as defined in the sched.h header file.

    No special privileges are required to use this routine.

1.92.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value of the policy argument does not represent a
                defined scheduling policy.

1.93  –  sched_get_priority_min

    Returns the minimum priority for the specified scheduling policy.

    Syntax

      sched_get_priority_min(

                             policy);

      Argument       Data Type            Access

      policy         integer              read

1.93.1  –  C Binding

    #include <sched.h>

    int
    sched_get_priority_min (
                int   policy);

1.93.2  –  Arguments

 policy

    One of the scheduling policies, as defined in sched.h.

1.93.3  –  Description

    This routine returns the minimum priority for the scheduling
    policy specified in the policy argument. The argument value
    must be one of the scheduling policies (SCHED_FIFO, SCHED_RR,
    or SCHED_OTHER), as defined in the sched.h header file.

    No special privileges are required to use this routine.

1.93.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value of the policy argument does not represent a
                defined scheduling policy.

1.94  –  sched_yield

    Yields execution to another thread.

    Syntax

      sched_yield();

1.94.1  –  C Binding

    #include <sched.h>
    #include <unistd.h>

    int
    sched_yield (void);

1.94.2  –  Arguments

    None

1.94.3  –  Description

    In conformance with the IEEE POSIX.1-1996 standard, the sched_
    yield() function causes the calling thread to yield execution
    to another thread. It is useful when a thread running under the
    SCHED_FIFO scheduling policy must allow another thread at the
    same priority to run. The thread that is interrupted by sched_
    yield() goes to the end of the queue for its priority.

    If no other thread is runnable at the priority of the calling
    thread, the calling thread continues to run.

    Threads with higher priority are allowed to preempt the calling
    thread, so the sched_yield() function has no effect on the
    scheduling of higher- or lower-priority threads.

    The sched_yield() routine takes no arguments. No special
    privileges are needed to use the sched_yield() function.

1.94.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [ENOSYS]    The routine sched_yield()  is not supported by this
                implementation.

1.94.5  –  Associated Routines

       pthread_attr_setschedparam()
       pthread_getschedparam()
       pthread_setschedparam()

2  –  TIS routines

    The VSI proprietary TIS interface provides routines that you use
    to build thread-safe libraries whose own routines do not create
    threads, but which can safely be called from a multithreaded
    environment. TIS routines are functionally identical to their
    corresponding routines in the PTHREAD interface. See the Guide to
    the POSIX Threads Library documentation for more information.

    In a program that creates threads, TIS routines provide full
    thread synchronization and memory coherence. But, when run in
    a program that does not use threads, the same TIS calls provide
    low-overhead "stub" implementations of PTHREAD features. That
    is, the objects created using the TIS interface are the same as
    PTHREAD objects. When threads are present, the guidelines for
    using PTHREAD routines apply also to the use of the corresponding
    TIS routine.

2.1  –  tis_cond_broadcast

    Wakes all threads that are waiting on a condition variable.

2.1.1  –  C Binding

    #include <tis.h>

    int
    tis_cond_broadcast (
                pthread_cond_t   *cond);

2.1.2  –  Arguments

 cond

    Address of the condition variable (passed by reference) on which
    to broadcast.

2.1.3  –  Description

    When threads are not present, this routine has no effect.

    When threads are present, this routine unblocks all threads
    waiting on the specified condition variable cond.

    For further information about actions when threads are present,
    refer to the pthread_cond_broadcast() description.

2.1.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

2.1.5  –  Associated Routines

       tis_cond_destroy()
       tis_cond_init()
       tis_cond_signal()
       tis_cond_wait()

2.2  –  tis_cond_destroy

    Destroys the specified condition variable.

2.2.1  –  C Binding

    #include <tis.h>

    int
    tis_cond_destroy (
                pthread_cond_t   *cond);

2.2.2  –  Arguments

 cond

    Address of the condition variable (passed by reference) to be
    destroyed.

2.2.3  –  Description

    This routine destroys the condition variable specified by cond.
    After this routine is called, the Threads Library may reclaim
    internal storage used by the condition variable object. Call this
    routine when a condition variable will no longer be referenced.

    The results of this routine are unpredictable if the condition
    variable specified in cond does not exist or is not initialized.

    For more information about actions when threads are present,
    refer to the pthread_cond_destroy() description.

2.2.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EBUSY]     The object being referenced by cond is being
                referenced by another thread that is currently
                executing a
                tis_cond_wait()  on the condition variable specified
                in cond. (This error can only occur when threads are
                present.)
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

2.2.5  –  Associated Routines

       tis_cond_broadcast()
       tis_cond_init()
       tis_cond_signal()
       tis_cond_wait()

2.3  –  tis_cond_init

    Initializes a condition variable.

2.3.1  –  C Binding

    #include <tis.h>

    int
    tis_cond_init (
                pthread_cond_t   *cond);

2.3.2  –  Arguments

 cond

    Address of the condition variable (passed by reference) to be
    initialized.

2.3.3  –  Description

    This routine initializes a condition variable (cond) with the
    Threads Library default condition variable attributes.

    A condition variable is a synchronization object used with a
    mutex. A mutex controls access to shared data. When threads are
    present, a condition variable allows threads to wait for data to
    enter a defined state.

    For more information about actions taken when threads are
    present, refer to the pthread_cond_init() description.

    Your program can use the macro PTHREAD_COND_INITIALIZER to
    initialize statically allocated condition variables to the
    default condition variable attributes. Static initialization
    can be used only for a condition variable with storage class
    "extern" or "static" - "automatic" (stack local) objects must
    be initialized by calling tis_cond_init(). Use this macro as
    follows:

       pthread_cond_t condition = PTHREAD_COND_INITIALIZER;

    When statically initialized, a condition variable should not also
    be initialized using tis_cond_init().

2.3.4  –  Return Values

    If there is an error condition, the following occurs:

    o  The routine returns an integer value indicating the type of
       error.

    o  The condition variable is not initialized.

    o  The contents of condition variable cond are undefined.

    The possible return values are as follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacks the necessary resources to
                initialize another condition variable, or

                The system-imposed limit on the total number of
                condition variables under execution by a single user
                is exceeded.
    [EBUSY]     The implementation has detected an attempt to
                reinitialize the object referenced by cond, a
                previously initialized, but not yet destroyed
                condition variable.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.
    [ENOMEM]    Insufficient memory to initialize the condition
                variable.

2.3.5  –  Associated Routines

       tis_cond_broadcast()
       tis_cond_destroy()
       tis_cond_signal()
       tis_cond_wait()

2.4  –  tis_cond_signal

    Wakes at least one thread that is waiting on the specified
    condition variable.

2.4.1  –  C Binding

    #include <tis.h>

    int
    tis_cond_signal (
                pthread_cond_t   *cond);

2.4.2  –  Arguments

 cond

    Address of the condition variable (passed by reference) on which
    to signal.

2.4.3  –  Description

    When threads are present, this routine unblocks at least one
    thread that is waiting on the specified condition variable cond.
    When threads are not present, this routine has no effect.

    For more information about actions taken when threads are
    present, refer to the pthread_cond_signal() description.

2.4.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable.

2.4.5  –  Associated Routines

       tis_cond_broadcast()
       tis_cond_destroy()
       tis_cond_init()
       tis_cond_wait()

2.5  –  tis_cond_timedwait

    Causes a thread to wait for the specified condition variable
    to be signaled or broadcast, such that it will awake after a
    specified period of time.

2.5.1  –  C Binding

    #include <tis.h>

    int
    tis_cond_timedwait (
             pthread_cond_t   *cond,
             pthread_mutex_t   *mutex,
             const struct timespec   *abstime);

2.5.2  –  Arguments

 cond

    Condition variable that the calling thread waits on.

 mutex

    Mutex associated with the condition variable specified in cond.

 abstime

    Absolute time at which the wait expires, if the condition has not
    been signaled or broadcast. See the tis_get_expiration() routine,
    which is used to obtain a value for this argument.

    The abstime argument is specified in Universal Coordinated Time
    (UTC). In the UTC-based model, time is represented as seconds
    since the Epoch. The Epoch is defined as the time 0 hours, 0
    minutes, 0 seconds, January 1st, 1970 UTC.

2.5.3  –  Description

    If threads are not present, this function is equivalent to
    sleep().

    This routine causes a thread to wait until one of the following
    occurs:

    o  The specified condition variable is signaled or broadcast.

    o  The current system clock time is greater than or equal to the
       time specified by the abstime argument.

    This routine is identical to tis_cond_wait(), except that this
    routine can return before a condition variable is signaled or
    broadcast, specifically, when the specified time expires. For
    more information, see the tis_cond_wait() description.

    This routine atomically releases the mutex and causes the calling
    thread to wait on the condition. When the thread regains control
    after calling tis_cond_timedwait(), the mutex is locked and the
    thread is the owner. This is true regardless of why the wait
    ended. If general cancelability is enabled, the thread reacquires
    the mutex (blocking for it if necessary) before the cleanup
    handlers are run (or before the exception is raised).

    If the current time equals or exceeds the expiration time, this
    routine returns immediately, releasing and reacquiring the mutex.
    It might cause the calling thread to yield (see the sched_yield()
    description). Your code should check the return status whenever
    this routine returns and take the appropriate action. Otherwise,
    waiting on the condition variable can become a nonblocking loop.

    Call this routine after you have locked the mutex specified
    in mutex. The results of this routine are unpredictable if
    this routine is called without first locking the mutex. The
    only routines that are supported for use with asynchronous
    cancelability enabled are those that disable asynchronous
    cancelability.

2.5.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond, mutex, or abstime is
                invalid, or

                Different mutexes are supplied for concurrent
                tis_cond_timedwait()  operations or
                tis_cond_wait()  operations on the same condition
                variable, or

                The mutex was not owned by the calling thread at the
                time of the call.
    [ETIMEDOUT] The time specified by abstime expired.
    [ENOMEM]    The Threads Library cannot acquire memory needed
                to block using a statically initialized condition
                variable.

2.5.5  –  Associated Routines

       tis_cond_broadcast()
       tis_cond_destroy()
       tis_cond_init()
       tis_cond_signal()
       tis_cond_wait()
       tis_get_expiration()

2.6  –  tis_cond_wait

    Causes a thread to wait for the specified condition variable to
    be signaled or broadcast.

2.6.1  –  C Binding

    #include <tis.h>

    int
    tis_cond_wait (
                pthread_cond_t   *cond,
                pthread_mutex_t   *mutex);

2.6.2  –  Arguments

 cond

    Address of the condition variable (passed by reference) on which
    to wait.

 mutex

    Address of the mutex (passed by reference) that is associated
    with the condition variable specified in cond.

2.6.3  –  Description

    When threads are present, this routine causes a thread to wait
    for the specified condition variable cond to be signaled or
    broadcast.

    Calling this routine in a single-threaded environment is a coding
    error. Because no other thread exists to issue a call to tis_
    cond_signal() or tis_cond_broadcast(),  using this routine in a
    single-threaded environment forces the program to exit.

    For further information about actions taken when threads are
    present, refer to the pthread_cond_wait() description.

2.6.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by cond is not a valid condition
                variable or the value specified by mutex is not a
                valid mutex, or

                Different mutexes are supplied for concurrent
                tis_cond_wait()  operations on the same condition
                variable, or

                The mutex was not owned by the calling thread at the
                time of the call.

2.6.5  –  Associated Routines

       tis_cond_broadcast()
       tis_cond_destroy()
       tis_cond_init()
       tis_cond_signal()

2.7  –  tis_getspecific

    Obtains the data associated with the specified thread-specific
    data key.

2.7.1  –  C Binding

    #include <tis.h>

    void *
    tis_getspecific (
                pthread_key_t   key);

2.7.2  –  Arguments

 key

    Identifies a value returned by a call to tis_key_create().
    This routine returns the data value associated with the thread-
    specific data key.

2.7.3  –  Description

    This routine returns the value currently bound to the specified
    thread-specific data key.

    This routine can be called from a data destructor function.

    When threads are present, the data and keys are thread specific;
    they enable a library to maintain context on a per-thread basis.

2.7.4  –  Return Values

    No errors are returned. This routine returns the data value
    associated with the specified thread-specific data key key. If
    no data value is associated with key, or if key is not defined,
    then a NULL value is returned.

2.7.5  –  Associated Routines

       tis_key_create()
       tis_key_delete()
       tis_setspecific()

2.8  –  tis_get_expiration

    Obtains a value representing a desired expiration time.

2.8.1  –  C Binding

    #include <tis.h>

    int
    tis_get_expiration (
                const struct timespec   *delta,
                struct timespec   *abstime);

2.8.2  –  Arguments

 delta

    Number of seconds and nanoseconds to add to the current system
    time. (The result is the time in the future.) This result will be
    placed in abstime.

 abstime

    Value representing the absolute expiration time. The absolute
    expiration time is obtained by adding delta to the current system
    time. The resulting abstime is in Universal Coordinated Time
    (UTC).

2.8.3  –  Description

    If threads are not present, this routine has no effect.

    This routine adds a specified interval to the current absolute
    system time and returns a new absolute time. This new absolute
    time is used as the expiration time in a call to tis_cond_
    timedwait().

    The timespec structure contains the following two fields:

    o  tv_sec is an integral number of seconds.

    o  tv_nsec is an integral number of nanoseconds.

2.8.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by delta is invalid.

2.8.5  –  Associated Routines

       tis_cond_timedwait()

2.9  –  tis_io_complete

    AST completion routine to VMS I/O system services.
    This routine is for OpenVMS systems only.

2.9.1  –  C Binding

    #include <tis.h>

    int
    tis_io_complete (void);

2.9.2  –  Description

    When you are performing thread-synchronous "wait-form" system
    service calls on OpenVMS such as $QIOW, $ENQW, $GETJPIW, and
    so on, you should use this routine and tis_sync() with the
    asynchronous form of the service (in other words, without the
    "W"), and specify the address of tis_io_complete() as the
    completion AST routine (the AST argument if any is ignored).
    That must also specify an IOSB (or equivalent, such as an LKSB)
    and if possible a unique event flag (see lib$get_ef). Once the
    library code is ready to wait for the I/O, it simply calls tis_
    sync() (just as if it were calling $SYNC).

2.9.3  –  Return Values

    None.

2.9.4  –  Associated Routines

       tis_sync()

2.10  –  tis_key_create

    Generates a unique thread-specific data key.

2.10.1  –  C Binding

    #include <tis.h>

    int
    tis_key_create (
       pthread_key_t   *key,
       void   (*destructor)(void *));

2.10.2  –  Arguments

 key

    Address of a variable that receives the key value. This value
    is used in calls to tis_getspecific() and tis_setspecific()  to
    obtain and set the value associated with this key.

 destructor

    Address of a routine that is called to destroy the context value
    when a thread terminates with a non-NULL value for the key. Note
    that this argument is used only when threads are present.

2.10.3  –  Description

    This routine generates a unique thread-specific data key. The key
    argument points to an opaque object used to locate data.

    This routine generates and returns a new key value. The key
    reserves a cell. Each call to this routine creates a new cell
    that is unique within an application invocation. Keys must
    be generated from initialization code that is guaranteed to
    be called only once within each process. (See the tis_once()
    description for more information.)

    Your program can associate an optional destructor function with
    each key. At thread exit, if a key has a non-NULL destructor
    function pointer, and the thread has a non-NULL value associated
    with that key, the function pointed to is called with the current
    associated value as its sole argument. The order in which data
    destructors are called at thread termination is undefined.

    When threads are present, keys and any corresponding data are
    thread specific; they enable the context to be maintained on a
    per-thread basis. For more information about the use of tis_key_
    create() in a threaded environment, refer to the pthread_key_
    create() description.

    The Threads Library imposes a maximum number of thread-specific
    data keys, equal to the symbolic constant PTHREAD_KEYS_MAX.

2.10.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacked the necessary resources to create
                another thread-specific data key, or the limit on the
                total number of keys per process (PTHREAD_KEYS_MAX)
                has been exceeded.
    [EINVAL]    The value specified by key is invalid.
    [ENOMEM]    Insufficient memory to create the key.

2.10.5  –  Associated Routines

       tis_getspecific()
       tis_key_delete()
       tis_setspecific()
       tis_once()

2.11  –  tis_key_delete

    Deletes the specified thread-specific data key.

2.11.1  –  C Binding

    #include <tis.h>

    int
    tis_key_delete (
                pthread_key_t   key);

2.11.2  –  Arguments

 key

    Thread-specific data key to be deleted.

2.11.3  –  Description

    This routine deletes a thread-specific data key key previously
    returned by a call to the tis_key_create() routine. The data
    values associated with key need not be NULL at the time this
    routine is called. The application must free any application
    storage or perform any cleanup actions for data structures
    related to the deleted key or associated data. This cleanup can
    be done before or after this routine is called. If the cleanup
    is done after this routine is called, the application must have a
    private mechanism to access any and all thread-specific values,
    contexts, and so on.

    Attempting to use the thread-specific data key key after calling
    this routine results in unpredictable behavior.

    No destructor functions are invoked by this routine. Any
    destructor functions that may have been associated with key will
    no longer be called upon thread exit.

    This routine can be called from destructor functions.

2.11.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value for key is invalid.

2.11.5  –  Associated Routines

       tis_getspecific()
       tis_key_create()
       tis_setspecific()

2.12  –  tis_lock_global

    Locks the Threads Library global mutex.

2.12.1  –  C Binding

    #include <tis.h>

    int
    tis_lock_global (void);

2.12.2  –  Arguments

    None

2.12.3  –  Description

    This routine locks the global mutex. The global mutex is
    recursive. For example, if you called tis_lock_global() three
    times, tis_unlock_global() unlocks the global mutex when you call
    it the third time.

    For more information about actions taken when threads are
    present, refer to the pthread_lock_global_np() description.

2.12.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.

2.12.5  –  Associated Routines

       tis_unlock_global()

2.13  –  tis_mutex_destroy

    Destroys the specified mutex object.

2.13.1  –  C Binding

    #include <tis.h>

    int
    tis_mutex_destroy (
                pthread_mutex_t   *mutex);

2.13.2  –  Arguments

 mutex

    Address of the mutex object (passed by reference) to be
    destroyed.

2.13.3  –  Description

    This routine destroys a mutex object by uninitializing it, and
    should be called when a mutex object is no longer referenced.
    After this routine is called, the Threads Library can reclaim
    internal storage used by the mutex object.

    It is safe to destroy an initialized mutex object that is
    unlocked. However, it is illegal to destroy a locked mutex
    object.

    The results of this routine are unpredictable if the mutex object
    specified in the mutex argument either does not currently exist
    or is not initialized.

2.13.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EBUSY]     An attempt was made to destroy the object referenced
                by mutex while it is locked or referenced.
    [EINVAL]    The value specified by mutex is not a valid mutex.
    [EPERM]     The caller does not have privileges to perform the
                operation.

2.13.5  –  Associated Routines

       tis_mutex_init()
       tis_mutex_lock()
       tis_mutex_trylock()
       tis_mutex_unlock()

2.14  –  tis_mutex_init

    Initializes the specified mutex object.

2.14.1  –  C Binding

    #include <tis.h>

    int
    tis_mutex_init (
                pthread_mutex_t   *mutex );

2.14.2  –  Arguments

 mutex

    Pointer to a mutex object (passed by reference) to be
    initialized.

2.14.3  –  Description

    This routine initializes a mutex object with the Threads Library
    default mutex attributes. A mutex is a synchronization object
    that allows multiple threads to serialize their access to shared
    data.

    The mutex object is initialized and set to the unlocked state.

    Your program can use the PTHREAD_MUTEX_INITIALIZER macro to
    statically initialize a mutex object without calling this
    routine. Static initialization can be used only for a condition
    variable with storage class "extern" or "static" - "automatic"
    (stack local) objects must be initialized by calling tis_mutex_
    init(). Use this macro as follows:

       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

2.14.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EAGAIN]    The system lacks the necessary resources to
                initialize a mutex.
    [EBUSY]     The implementation has detected an attempt to
                reinitialize mutex (a previously initialized, but
                not yet destroyed, mutex).
    [EINVAL]    The value specified by mutex is not a valid mutex.
    [ENOMEM]    Insufficient memory to initialize the mutex.
    [EPERM]     The caller does not have privileges to perform this
                operation.

2.14.5  –  Associated Routines

       tis_mutex_destroy()
       tis_mutex_lock()
       tis_mutex_trylock()
       tis_mutex_unlock()

2.15  –  tis_mutex_lock

    Locks an unlocked mutex.

2.15.1  –  C Binding

    #include <tis.h>

    int
    tis_mutex_lock (
                pthread_mutex_t   *mutex);

2.15.2  –  Arguments

 mutex

    Address of the mutex (passed by reference) to be locked.

2.15.3  –  Description

    This routine locks the specified mutex mutex. A deadlock can
    result if the owner of a mutex calls this routine in an attempt
    to lock the same mutex a second time. (The Threads Library may
    not detect or report the deadlock.)

    In a threaded environment, the thread that has locked a mutex
    becomes its current owner and remains the owner until the same
    thread has unlocked it. This routine returns with the mutex
    in the locked state and with the current thread as the mutex's
    current owner.

2.15.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EDEADLK]   A deadlock condition is detected.
    [EINVAL]    The value specified by mutex is not a valid mutex.

2.15.5  –  Associated Routines

       tis_mutex_destroy()
       tis_mutex_init()
       tis_mutex_trylock()
       tis_mutex_unlock()

2.16  –  tis_mutex_trylock

    Attempts to lock the specified mutex.

2.16.1  –  C Binding

    #include <tis.h>

    int
    tis_mutex_trylock (
                pthread_mutex_t   *mutex);

2.16.2  –  Arguments

 mutex

    Address of the mutex (passed by reference) to be locked.

2.16.3  –  Description

    This routine attempts to lock the specified mutex mutex. When
    this routine is called, an attempt is made immediately to lock
    the mutex. If the mutex is successfully locked, zero (0) is
    returned.

    If the specified mutex is already locked when this routine
    is called, the caller does not wait for the mutex to become
    available. [EBUSY] is returned, and the thread does not wait
    to acquire the lock.

2.16.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EBUSY]     The mutex is already locked; therefore, it was not
                acquired.
    [EINVAL]    The value specified by mutex is not a valid mutex.

2.16.5  –  Associated Routines

       tis_mutex_destroy()
       tis_mutex_init()
       tis_mutex_lock()
       tis_mutex_unlock()

2.17  –  tis_mutex_unlock

    Unlocks the specified mutex.

2.17.1  –  C Binding

    #include <tis.h>

    int
    tis_mutex_unlock (
                pthread_mutex_t   *mutex);

2.17.2  –  Arguments

 mutex

    Address of the mutex (passed by reference) to be unlocked.

2.17.3  –  Description

    This routine unlocks the specified mutex mutex.

    For more information about actions taken when threads are
    present, refer to the pthread_mutex_unlock() description.

2.17.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by mutex is not a valid mutex.
    [EPERM]     The caller does not own the mutex.

2.17.5  –  Associated Routines

       tis_mutex_destroy()
       tis_mutex_init()
       tis_mutex_lock()
       tis_mutex_trylock()

2.18  –  tis_once

    Calls a one-time initialization routine that can be executed by
    only one thread, once.

2.18.1  –  C Binding

    #include <tis.h>

    int
    tis_once (
          pthread_once_t   *once_control,
          void   (*init_routine) (void));

2.18.2  –  Arguments

 once_control

    Address of a record (control block) that defines the one-time
    initialization code. Any one-time initialization routine in
    static storage specified by once_control must have its own unique
    pthread_once_t record.

 init_routine

    Address of a procedure that performs the initialization. This
    routine is called only once, regardless of the number of times it
    and its associated once_control are passed to tis_once().

2.18.3  –  Description

    The first call to this routine by a process with a given once_
    control calls the init_routine with no arguments. Thereafter,
    subsequent calls to tis_once() with the same once_control do
    not call the init_routine. On return from tis_once(), it is
    guaranteed that the initialization routine has completed.

    For example, a mutex or a thread-specific data key must be
    created exactly once. In a threaded environment, calling tis_
    once() ensures that the initialization is serialized across
    multiple threads.

                                   NOTE

       If you specify an init_routine that directly or indirectly
       results in a recursive call to tis_once() and that specifies
       the same init_block argument, the recursive call results in
       a deadlock.

    The PTHREAD_ONCE_INIT macro, defined in the pthread.h header
    file, must be used to initialize a once_control record. Thus,
    your program must declare a once_control record as follows:

    pthread_once_t  once_control = PTHREAD_ONCE_INIT;

    Note that it is often easier to simply lock a statically
    initialized mutex, check a control flag, and perform necessary
    initialization (in-line) rather than using tis_once(). For
    example, you can code an "init" routine that begins with the
    following basic logic:

      init()
      {
       static pthread_mutex_t    mutex = PTHREAD_MUTEX_INIT;
       static int                flag = FALSE;

       tis_mutex_lock(&mutex);
       if(!flag)
         {
          flag = TRUE;
          /* initialize code */
         }
       tis_mutex_unlock(&mutex);
      }

2.18.4  –  Return Values

    If an error occurs, this routine returns an integer indicating
    the type of error. Possible return values are as follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    Invalid argument.

2.19  –  tis_read_lock

    Acquires a read-write lock for read access.

2.19.1  –  C Binding

    #include <tis.h>

    int
    tis_read_lock (
             tis_rwlock_t   *lock);

2.19.2  –  Arguments

 lock

    Address of the read-write lock.

2.19.3  –  Description

    This routine acquires a read-write lock for read access. This
    routine waits for any existing lock holder for write access to
    relinquish its lock before granting the lock for read access.
    This routine returns when the lock is acquired. If the lock is
    already held simply for read access, the lock is granted.

    For each call to tis_read_lock() that successfully acquires the
    lock for read access, a corresponding call to tis_read_unlock()
    must be issued.

2.19.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.

2.19.5  –  Associated Routines

       tis_read_trylock()
       tis_read_unlock()
       tis_rwlock_destroy()
       tis_rwlock_init()
       tis_write_lock()
       tis_write_trylock()
       tis_write_unlock()

2.20  –  tis_read_trylock

    Attempts to acquire a read-write lock for read access. Does not
    wait if the lock cannot be immediately granted.

2.20.1  –  C Binding

    #include <tis.h>

    int
    tis_read_trylock (
             tis_rwlock_t    *lock);

2.20.2  –  Arguments

 lock

    Address of the read-write lock to be acquired.

2.20.3  –  Description

    This routine attempts to acquire a read-write lock for read
    access. If the lock cannot be granted, the routine returns
    without waiting.

    When a thread calls this routine, an attempt is made to
    immediately acquire the lock for read access. If the lock is
    acquired, zero (0) is returned. If a holder of the lock for write
    access exists, [EBUSY] is returned.

    If the lock cannot be acquired for read access immediately, the
    calling program does not wait for the lock to be released.

2.20.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion; the lock was acquired.
    [EBUSY]     The lock is being held for write access. The lock for
                read access was not acquired.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.

2.20.5  –  Associated Routines

       tis_read_lock()
       tis_read_unlock()
       tis_rwlock_destroy()
       tis_rwlock_init()
       tis_write_lock()
       tis_write_trylock()
       tis_write_unlock()

2.21  –  tis_read_unlock

    Unlocks a read-write lock that was acquired for read access.

2.21.1  –  C Binding

    #include <tis.h>

    int
    tis_read_unlock (
             tis_rwlock_t   *lock);

2.21.2  –  Arguments

 lock

    Address of the read-write lock to be unlocked.

2.21.3  –  Description

    This routine unlocks a read-write lock that was acquired for
    read access. If there are no other holders of the lock for read
    access and another thread is waiting to acquire the lock for
    write access, that lock acquisition is granted.

2.21.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.

2.21.5  –  Associated Routines

       tis_read_lock()
       tis_read_trylock()
       tis_rwlock_destroy()
       tis_rwlock_init()
       tis_write_lock()
       tis_write_trylock()
       tis_write_unlock()

2.22  –  tis_rwlock_destroy

    Destroys the specified read-write lock object.

2.22.1  –  C Binding

    #include <tis.h>

    int
    tis_rwlock_destroy (
             tis_rwlock_t   *lock);

2.22.2  –  Arguments

 lock

    Address of the read-write lock object to be destroyed.

2.22.3  –  Description

    This routine destroys the specified read-write lock object. Prior
    to calling this routine, ensure that there are no locks granted
    to the specified read-write lock and that there are no threads
    waiting for pending lock acquisitions on the specified read-write
    lock.

    This routine should be called only after all reader threads (and
    perhaps one writer thread) have finished using the specified
    read-write lock.

2.22.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EBUSY]     The lock is in use.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.

2.22.5  –  Associated Routines

       tis_read_lock()
       tis_read_trylock()
       tis_read_unlock()
       tis_rwlock_init()
       tis_write_lock()
       tis_write_trylock()
       tis_write_unlock()

2.23  –  tis_rwlock_init

    Initializes a read-write lock object.

2.23.1  –  C Binding

    #include <tis.h>

    int
    tis_rwlock_init (
             tis_rwlock_t   *lock);

2.23.2  –  Arguments

 lock

    Address of a read-write lock object.

2.23.3  –  Description

    This routine initializes a read-write lock object. The routine
    initializes the tis_rwlock_t structure that holds the object's
    lock states.

    To destroy a read-write lock object, call the tis_rwlock_
    destroy() routine.

                                   NOTE

       The tis read-write lock has no relationship to the Single
       UNIX Specification, Version 2 (SUSV2, or UNIX98) read-
       write lock routines (such as pthread_rwlock_init()). The
       tis_rwlock_t type, in particular, cannot be used with the
       pthread read-write lock functions, nor can a pthread_rwlock_
       t type be used with the tis read-write lock functions.

2.23.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.
    [ENOMEM]    Insufficient memory to initialize lock.

2.23.5  –  Associated Routines

       tis_read_lock()
       tis_read_trylock()
       tis_read_unlock()
       tis_rwlock_destroy()
       tis_write_lock()
       tis_write_trylock()
       tis_write_unlock()

2.24  –  tis_self

    Returns the identifier of the calling thread.

2.24.1  –  C Binding

    #include <tis.h>

    pthread_t
    tis_self (void);

2.24.2  –  Arguments

    None

2.24.3  –  Description

    This routine allows a thread to obtain its own thread identifier.

    This value becomes meaningless when the thread is destroyed.

    Note that the initial thread in a process can "change identity"
    when thread system initialization completes-that is, when the
    multithreading run-time environment is loaded.

2.24.4  –  Return Values

    Returns the thread identifier of the calling thread.

2.24.5  –  Associated Routines

       pthread_create()

2.25  –  tis_setcancelstate

    Changes the calling thread's cancelability state.

2.25.1  –  C Binding

    #include <tis.h>

    int
    tis_setcancelstate (
                int   state,
                int   *oldstate );

2.25.2  –  Arguments

 state

    State of general cancelability to set for the calling thread.
    Valid state values are as follows:

       PTHREAD_CANCEL_ENABLE
       PTHREAD_CANCEL_DISABLE

 oldstate

    Receives the value of the calling thread's previous cancelability
    state.

2.25.3  –  Description

    This routine sets the calling thread's cancelability state to
    the value specified in the state argument and returns the calling
    thread's previous cancelability state in the location referenced
    by the oldstate argument.

    When a thread's cancelability state is set to PTHREAD_CANCEL_
    DISABLE, a cancelation request cannot be delivered to the
    thread, even if a cancelable routine is called or asynchronous
    cancelability is enabled.

    When a thread is created, its default cancelability state is
    PTHREAD_CANCEL_ENABLE. When this routine is called prior to
    loading threads, the cancelability state propagates to the
    initial thread in the executing program.
    Possible Problems When Disabling Cancelability
    The most important use of a cancelation request is to ensure that
    indefinite wait operations are terminated. For example, a thread
    waiting on some network connection, which might take days to
    respond (or might never respond), should be made cancelable.

    When a thread's cancelability state is disabled, no routine
    called within that thread is cancelable. As a result, the user
    is unable to cancel the operation. When disabling cancelability,
    be sure that no long waits can occur or that it is necessary
    for other reasons to defer cancelation requests around that
    particular region of code.

2.25.4  –  Return Values

    On successful completion, this routine returns the calling
    thread's previous cancelability state in the oldstate argument.

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The specified state is not PTHREAD_CANCEL_ENABLE or
                PTHREAD_CANCEL_DISABLE.

2.25.5  –  Associated Routines

       tis_testcancel()

2.26  –  tis_setspecific

    Changes the value associated with the specified thread-specific
    data key.

2.26.1  –  C Binding

    #include <tis.h>

    int
    tis_setspecific (
                pthread_key_t   key,
                const void   *value);

2.26.2  –  Arguments

 key

    Thread-specific data key that identifies the data to receive
    value. Must be obtained from a call to tis_key_create().

 value

    New value to associate with the specified key. Once set, this
    value can be retrieved using the same key in a call to tis_
    getspecific().

2.26.3  –  Description

    This routine sets the value associated with the specified thread-
    specific data key. If a value is defined for the key (that is,
    the current value is not NULL), the new value is substituted for
    it. The key is obtained by a previous call to tis_key_create().

    Do not call this routine from a data destructor function. Doing
    so could lead to a memory leak or an infinite loop.

2.26.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by key is not a valid key.
    [ENOMEM]    Insufficient memory to associate the value with the
                key.

2.26.5  –  Associated Routines

       tis_getspecific()
       tis_key_create()
       tis_key_delete()

2.27  –  tis_sync

    Used as the synchronization point for asynchronous I/O system
    services. This routine is for OpenVMS systems only.

2.27.1  –  C Binding

    #include <tis.h>

    int
    tis_sync (
          unsigned long   efn,
          void   *iosb);

2.27.2  –  Arguments

 efn

    The event flag specified with the OpenVMS system service routine.

 iosb

    The IOSB specified with the OpenVMS system service routine.

2.27.3  –  Description

    When you are performing thread-synchronous "wait-form" system
    service calls on OpenVMS such as $QIOW, $ENQW, $GETJPIW, and so
    on, you should use this routine and tis_io_complete() with the
    asynchronous form of the service (that is, without the "W") and
    specify the address of tis_io_complete() as the completion AST
    routine (the AST argument, if any, is ignored). The call must
    also specify an IOSB (or equivalent, such as an LKSB) and if
    possible a unique event flag (see lib$get_ef). Once the library
    code is ready to wait for the I/O, it simply calls tis_sync()
    (just as if it were calling $SYNC).

2.27.4  –  Return Values

    This routine has the same return values as the OpenVMS $SYNC()
    routine.

2.27.5  –  Associated Routines

       tis_io_complete()

2.28  –  tis_testcancel

    Creates a cancelation point in the calling thread.

2.28.1  –  C Binding

    #include <tis.h>

    void
    tis_testcancel (void);

2.28.2  –  Arguments

    None

2.28.3  –  Description

    This routine requests delivery of a pending cancelation request
    to the calling thread. Thus, this routine creates a cancelation
    point in the calling thread. The cancelation request is delivered
    only if a request is pending for the calling thread and the
    calling thread's cancelability state is enabled. (A thread
    disables delivery of cancelation requests to itself by calling
    tis_setcancelstate().)

    This routine, when called within very long loops, ensures that a
    pending cancelation request is noticed within a reasonable amount
    of time.

2.28.4  –  Return Values

    None

2.28.5  –  Associated Routines

       tis_setcancelstate()

2.29  –  tis_unlock_global

    Unlocks the Threads Library global mutex.

2.29.1  –  C Binding

    #include <tis.h>

    int
    tis_unlock_global (void);

2.29.2  –  Arguments

    None

2.29.3  –  Description

    This routine unlocks the global mutex. Because the global mutex
    is recursive, the unlock occurs when each call to tis_lock_
    global() has been matched by a call to this routine. For example,
    if your program called tis_lock_global() three times, tis_unlock_
    global() unlocks the global mutex when you call it the third
    time.

    For more information about actions taken when threads are
    present, refer to the pthread_unlock_global_np() description.

2.29.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EPERM]     The global mutex is unlocked or locked by another
                thread.

2.29.5  –  Associated Routines

       tis_lock_global()

2.30  –  tis_write_lock

    Acquires a read-write lock for write access.

2.30.1  –  C Binding

    #include <tis.h>

    int
    tis_write_lock (
             tis_rwlock_t   *lock);

2.30.2  –  Arguments

 lock

    Address of the read-write lock to be acquired for write access.

2.30.3  –  Description

    This routine acquires a read-write lock for write access. This
    routine waits for any other active locks (for either read or
    write access) to be unlocked before this acquisition request is
    granted.

    This routine returns when the specified read-write lock is
    acquired for write access.

2.30.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.

2.30.5  –  Associated Routines

       tis_read_lock()
       tis_read_trylock()
       tis_read_unlock()
       tis_rwlock_destroy()
       tis_rwlock_init()
       tis_write_trylock()
       tis_write_unlock()

2.31  –  tis_write_trylock

    Attempts to acquire a read-write lock for write access.

2.31.1  –  C Binding

    #include <tis.h>

    int
    tis_write_trylock (
             tis_rwlock_t   *lock);

2.31.2  –  Arguments

 lock

    Address of the read-write lock to be acquired for write access.

2.31.3  –  Description

    This routine attempts to acquire a read-write lock for write
    access. The routine attempts to immediately acquire the lock.
    If the lock is acquired, zero (0) is returned. If the lock is
    held by another thread (for either read or write access), [EBUSY]
    is returned and the calling thread does not wait for the write-
    access lock to be acquired.

    Note that it is a coding error to attempt to acquire the lock
    for write access if the lock is already held by the calling
    thread. (However, this routine returns [EBUSY] anyway, because
    no ownership error-checking takes place.)

2.31.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion, the lock is acquired for write
                access.
    [EBUSY]     The lock was not acquired for write access, as it is
                already held by another thread.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.

2.31.5  –  Associated Routines

       tis_read_lock()
       tis_read_trylock()
       tis_read_unlock()
       tis_rwlock_destroy()
       tis_rwlock_init()
       tis_write_lock()
       tis_write_unlock()

2.32  –  tis_write_unlock

    Unlocks a read-write lock that was acquired for write access.

2.32.1  –  C Binding

    #include <tis.h>

    int
    tis_write_unlock (
             tis_rwlock_t   *lock);

2.32.2  –  Arguments

 lock

    Address of the read-write lock to be unlocked.

2.32.3  –  Description

    This routine unlocks a read-write lock that was acquired for
    write access.

    Upon completion of this routine, any thread waiting to acquire
    the lock for read access will have those acquisitions granted. If
    no threads are waiting to acquire the lock for read access, then
    a thread waiting to acquire it for write access will have that
    acquisition granted.

2.32.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [EINVAL]    The value specified by lock is not a valid read-write
                lock.

2.32.5  –  Associated Routines

       tis_read_lock()
       tis_read_trylock()
       tis_read_unlock()
       tis_rwlock_init()
       tis_rwlock_destroy()
       tis_write_lock()
       tis_write_trylock()

2.33  –  tis_yield

    Notifies the scheduler that the current thread is willing to
    release its processor to other threads of the same or higher
    priority.

    Syntax

      tis_yield();

2.33.1  –  C Binding

    int
    tis_yield (void);

2.33.2  –  Arguments

    None

2.33.3  –  Description

    When threads are not present, this routine has no effect.

    This routine notifies the thread scheduler that the current
    thread is willing to release its processor to other threads of
    equivalent or greater scheduling precedence. (A thread generally
    will release its processor to a thread of a greater scheduling
    precedence without calling this routine.) If no other threads of
    equivalent or greater scheduling precedence are ready to execute,
    the thread continues.

    This routine can allow knowledge of the details of an application
    to be used to improve its performance. If a thread does not call
    tis_yield(), other threads may be given the opportunity to run
    at arbitrary points (possibly even when the interrupted thread
    holds a required resource). By making strategic calls to tis_
    yield(), other threads can be given the opportunity to run when
    the resources are free. This improves performance by reducing
    contention for the resource.

    As a general guideline, consider calling this routine after a
    thread has released a resource (such as a mutex) which is heavily
    contended for by other threads. This can be especially important
    if the program is running on a uniprocessor machine, or if the
    thread acquires and releases the resource inside a tight loop.

    Use this routine carefully and sparingly, because misuse can
    cause unnecessary context switching that will increase overhead
    and actually degrade performance. For example, it is counter-
    productive for a thread to yield while it holds a resource that
    the threads to which it is yielding will need. Likewise, it is
    pointless to yield unless there is likely to be another thread
    that is ready to run.

2.33.4  –  Return Values

    If an error condition occurs, this routine returns an integer
    value indicating the type of error. Possible return values are as
    follows:

    Return      Description

    0           Successful completion.
    [ENOSYS]    The routine tis_yield()  is not supported by this
                implementation.
Close Help