Document revision date: 30 March 2001

## Guide to the POSIX Threads Library

Previous | Contents | Index

## tis_setspecific

> Changes the value associated with the specified thread-specific data key.

### Syntax

> tis_setspecific(
> key ,
> value );

> Argument | Data Type | Access
> --- | --- | ---
> key | opaque pthread_key_t | read
> value | void * | read

C Binding #include <tis.h>

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

### 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()` .

### 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.

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.

#### Associated Routines

> `tis_getspecific()`
> `tis_key_create()`
> `tis_key_delete()`

## tis_sync

> Used as the synchronization point for asynchronous I/O system services. This routine is for OpenVMS systems only.

### Syntax

> tis_sync(
> efn ,
> iosb );

> Argument | Data Type | Access
> --- | --- | ---
> efn | unsigned long | read
> iosb | void * | read

C Binding #include <tis.h>

int
tis_sync (
unsigned long efn,
void *iosb);

### Arguments

> #### efn

> The event flag specified with the OpenVMS system service routine.

> #### iosb

> The IOSB specified with the OpenVMS system service routine.

### 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` ).

Return Values This routine has the same return values as the OpenVMS `$SYNC()` routine.

#### Associated Routines

> `tis_io_complete()`

## tis_testcancel

> Creates a cancelation point in the calling thread.

### Syntax

> tis_testcancel( );

C Binding #include <tis.h>

void
tis_testcancel (void);

### Arguments

> ####

> None

### 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.

Return Values None

#### Associated Routines

> `tis_setcancelstate()`

## tis_unlock_global

> Unlocks the Threads Library global mutex.

### Syntax

> tis_unlock_global( );

C Binding #include <tis.h>

int
tis_unlock_global (void);

### Arguments

> ####

> None

### 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.

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.

#### Associated Routines

> `tis_lock_global()`

## tis_write_lock

> Acquires a read-write lock for write access.

### Syntax

> tis_write_lock(
> lock );

> Argument | Data Type | Access
> --- | --- | ---
> lock | opaque tis_rwlock_t | write

C Binding #include <tis.h>

int
tis_write_lock (
tis_rwlock_t *lock);

### Arguments

> #### lock

> Address of the read-write lock to be acquired for write access.

### 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.

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.

#### Associated Routines

> `tis_read_lock()`
> `tis_read_trylock()`
> `tis_read_unlock()`
> `tis_rwlock_destroy()`
> `tis_rwlock_init()`
> `tis_write_trylock()`
> `tis_write_unlock()`

## tis_write_trylock

> Attempts to acquire a read-write lock for write access.

### Syntax

> tis_write_trylock(
> lock );

> Argument | Data Type | Access
> --- | --- | ---
> lock | opaque tis_rwlock_t | write

C Binding #include <tis.h>

int
tis_write_trylock (
tis_rwlock_t *lock);

### Arguments

> #### lock

> Address of the read-write lock to be acquired for write access.

### 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.)

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.

#### Associated Routines

> `tis_read_lock()`
> `tis_read_trylock()`
> `tis_read_unlock()`
> `tis_rwlock_destroy()`
> `tis_rwlock_init()`
> `tis_write_lock()`
> `tis_write_unlock()`

## tis_write_unlock

> Unlocks a read-write lock that was acquired for write access.

### Syntax

> tis_write_unlock(
> lock );

> Argument | Data Type | Access
> --- | --- | ---
> lock | opaque tis_rwlock_t | write

C Binding #include <tis.h>

int
tis_write_unlock (
tis_rwlock_t *lock);

### Arguments

> #### lock

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

### 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.

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.

#### Associated Routines

> `tis_read_lock()`
> `tis_read_trylock()`
> `tis_read_unlock()`
> `tis_rwlock_init()`
> `tis_rwlock_destroy()`
> `tis_write_lock()`
> `tis_write_trylock()`

## 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( );

C Binding int
tis_yield (void);

### Arguments

> ####

> None

### 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.

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.

## Part 4
Appendixes

Part 4 contains appendixes that provide supporting information about the POSIX Threads Library, such as operating system-specific information, debugging information, and additional reference information.

## Appendix A
Considerations for Tru64 UNIX Systems

This appendix discusses Threads Library issues specific to Tru64 UNIX systems.

## A.1 Overview

The Tru64 UNIX operating system supports multiple concurrent "execution contexts" within a process. The Threads Library uses these kernel execution contexts to implement user threads. One important benefit of this is that user threads can run simultaneously on separate processors in a multiprocessor system. Review Section 3.1 for tips for ensuring that your application will work correctly with kernel threads and multiprocessing.

## A.2 Building Threaded Applications

The following sections discuss points to consider when building using the Threads Library.

### A.2.1 Including Threads Header Files

Include one of the Threads Library header files shown in Table A-1 in your program to use the appropriate Threads library.

Table A-1 Header Files
Header File | Interface
--- | ---
`pthread.h` | POSIX routines
`tis.h` | Thread-independent services routines

Do not include more than one of these header files in your module.

### A.2.2 Building Multithreaded Applications from Threads Libraries

Multithreaded applications are built using shared libraries. For a description of shared libraries, see the Tru64 UNIX Programmer's Guide.

Table A-2 contains the libraries supported for multithreaded programming.

Table A-2 Tru64 UNIX Shared Libraries for Multithreaded Programs
`libpthreads.so` | Shared version of Threads Library "legacy" package, implementing the Compaq-proprietary CMA (or cma) and POSIX 1003.4a/Draft 4 ( d4 or DCEthreads) interfaces.
`libpthread.so` | Shared version of the POSIX threads package. Requires `libexc.so` and `libc.so`
`libexc.so` | Shared version of Tru64 UNIX exception support package.
`libc.so` | Shared version of the C language run-time library ( `libc.so` ).

Build a multithreaded application using shared versions of `libexc` , `libpthread` , and `libc` using this command:

    % cc -o myprog myprog.c -pthread

If you use a compiler front-end or other (not C) language environment that does not support the `-pthread` compilation switch, you must provide the `-D_REENTRANT` compilation switch (or equivalent) at compilation, and link as shown in Section A.2.3.

### A.2.3 Linking Multithreaded Shared Libraries

The `ld` command does not support the `-pthread` or `-threads` switch. Normally, programs can be compiled and linked from the `cc` command. If you must link using the `ld` command, you must list the shared libraries in the proper order. The `libc` library should be the last library referenced, `libexc` should immediately precede `libc` , and the thread libraries should precede `libexc` .

For libraries that use only the pthread interface, use the following:

       ld <...> -lpthread -lexc -lc

If using the cma or d4 interfaces, use the following:

       ld <...> -lpthreads -lpthread -lexc -lc

Also, `cc -pthread` (or `cc -threads` ) causes the compiler to replace any libraries that have special thread-safe alternatives. These libraries have the same name ending in `-r` . For example, `cc -pthread -o foo -lbar` , if there is a `libbar.so` and `libbar_r.so` , would use the latter. When linking with the `ld` command, you must perform that search and replacement yourself.

Note If you build software (whether applications or libraries) that links against the static version of a Threads library, you must not require developers who use your software to link against any library that dynamically loads any Threads shared library, such as `libpthread.so` .

Previous | Next | Contents | Index

| privacy and legal statement |
6101PRO_029.HTML