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. 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. 4 Associated_Routines tis_read_lock() tis_read_unlock() tis_rwlock_destroy() tis_rwlock_init() tis_write_lock() tis_write_trylock() tis_write_unlock() 3 tis_read_unlock Unlocks a read-write lock that was acquired for read access. 4 C_Binding #include int tis_read_unlock ( tis_rwlock_t *lock); 4 Arguments lock Address of the read-write lock to be unlocked. 4 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. 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. 4 Associated_Routines tis_read_lock() tis_read_trylock() tis_rwlock_destroy() tis_rwlock_init() tis_write_lock() tis_write_trylock() tis_write_unlock() 3 tis_rwlock_destroy Destroys the specified read-write lock object. 4 C_Binding #include int tis_rwlock_destroy ( tis_rwlock_t *lock); 4 Arguments lock Address of the read-write lock object to be destroyed. 4 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. 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. 4 Associated_Routines tis_read_lock() tis_read_trylock() tis_read_unlock() tis_rwlock_init() tis_write_lock() tis_write_trylock() tis_write_unlock() 3 tis_rwlock_init Initializes a read-write lock object. 4 C_Binding #include int tis_rwlock_init ( tis_rwlock_t *lock); 4 Arguments lock Address of a read-write lock object. 4 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. 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. 4 Associated_Routines tis_read_lock() tis_read_trylock() tis_read_unlock() tis_rwlock_destroy() tis_write_lock() tis_write_trylock() tis_write_unlock() 3 tis_self Returns the identifier of the calling thread. 4 C_Binding #include pthread_t tis_self (void); 4 Arguments None 4 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. 4 Return_Values Returns the thread identifier of the calling thread. 4 Associated_Routines pthread_create() 3 tis_setcancelstate Changes the calling thread's cancelability state. 4 C_Binding #include int tis_setcancelstate ( int state, int *oldstate ); 4 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. 4 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. 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. 4 Associated_Routines tis_testcancel() 3 tis_setspecific Changes the value associated with the specified thread-specific data key. 4 C_Binding #include int tis_setspecific ( pthread_key_t key, const void *value); 4 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(). 4 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. 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. 4 Associated_Routines tis_getspecific() tis_key_create() tis_key_delete() 3 tis_sync Used as the synchronization point for asynchronous I/O system services. This routine is for OpenVMS systems only. 4 C_Binding #include int tis_sync ( unsigned long efn, void *iosb); 4 Arguments efn The event flag specified with the OpenVMS system service routine. iosb The IOSB specified with the OpenVMS system service routine. 4 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). 4 Return_Values This routine has the same return values as the OpenVMS $SYNC() routine. 4 Associated_Routines tis_io_complete() 3 tis_testcancel Creates a cancelation point in the calling thread. 4 C_Binding #include void tis_testcancel (void); 4 Arguments None 4 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. 4 Return_Values None 4 Associated_Routines tis_setcancelstate() 3 tis_unlock_global Unlocks the Threads Library global mutex. 4 C_Binding #include int tis_unlock_global (void); 4 Arguments None 4 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. 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. 4 Associated_Routines tis_lock_global() 3 tis_write_lock Acquires a read-write lock for write access. 4 C_Binding #include int tis_write_lock ( tis_rwlock_t *lock); 4 Arguments lock Address of the read-write lock to be acquired for write access. 4 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. 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. 4 Associated_Routines tis_read_lock() tis_read_trylock() tis_read_unlock() tis_rwlock_destroy() tis_rwlock_init() tis_write_trylock() tis_write_unlock() 3 tis_write_trylock Attempts to acquire a read-write lock for write access. 4 C_Binding #include int tis_write_trylock ( tis_rwlock_t *lock); 4 Arguments lock Address of the read-write lock to be acquired for write access. 4 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.) 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. 4 Associated_Routines tis_read_lock() tis_read_trylock() tis_read_unlock() tis_rwlock_destroy() tis_rwlock_init() tis_write_lock() tis_write_unlock() 3 tis_write_unlock Unlocks a read-write lock that was acquired for write access. 4 C_Binding #include int tis_write_unlock ( tis_rwlock_t *lock); 4 Arguments lock Address of the read-write lock to be unlocked. 4 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. 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. 4 Associated_Routines tis_read_lock() tis_read_trylock() tis_read_unlock() tis_rwlock_init() tis_rwlock_destroy() tis_write_lock() tis_write_trylock() 3 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(); 4 C_Binding int tis_yield (void); 4 Arguments None 4 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. 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.