| @node POSIX Threads | 
 | @c @node POSIX Threads, , Top, Top | 
 | @chapter POSIX Threads | 
 | @c %MENU% The standard threads library | 
 |  | 
 | @c This chapter needs more work bigtime. -zw | 
 |  | 
 | This chapter describes the pthreads (POSIX threads) library.  This | 
 | library provides support functions for multithreaded programs: thread | 
 | primitives, synchronization objects, and so forth.  It also implements | 
 | POSIX 1003.1b semaphores (not to be confused with System V semaphores). | 
 |  | 
 | The threads operations (@samp{pthread_*}) do not use @var{errno}. | 
 | Instead they return an error code directly.  The semaphore operations do | 
 | use @var{errno}. | 
 |  | 
 | @menu | 
 | * Basic Thread Operations::     Creating, terminating, and waiting for threads. | 
 | * Thread Attributes::           Tuning thread scheduling. | 
 | * Cancellation::                Stopping a thread before it's done. | 
 | * Cleanup Handlers::            Deallocating resources when a thread is | 
 |                                   canceled. | 
 | * Mutexes::                     One way to synchronize threads. | 
 | * Condition Variables::         Another way. | 
 | * POSIX Semaphores::            And a third way. | 
 | * Thread-Specific Data::        Variables with different values in | 
 |                                   different threads. | 
 | * Threads and Signal Handling:: Why you should avoid mixing the two, and | 
 |                                   how to do it if you must. | 
 | * Threads and Fork::            Interactions between threads and the | 
 |                                   @code{fork} function. | 
 | * Streams and Fork::            Interactions between stdio streams and | 
 |                                   @code{fork}. | 
 | * Miscellaneous Thread Functions:: A grab bag of utility routines. | 
 | @end menu | 
 |  | 
 | @node Basic Thread Operations | 
 | @section Basic Thread Operations | 
 |  | 
 | These functions are the thread equivalents of @code{fork}, @code{exit}, | 
 | and @code{wait}. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_create (pthread_t * @var{thread}, pthread_attr_t * @var{attr}, void * (*@var{start_routine})(void *), void * @var{arg}) | 
 | @code{pthread_create} creates a new thread of control that executes | 
 | concurrently with the calling thread. The new thread calls the | 
 | function @var{start_routine}, passing it @var{arg} as first argument. The | 
 | new thread terminates either explicitly, by calling @code{pthread_exit}, | 
 | or implicitly, by returning from the @var{start_routine} function. The | 
 | latter case is equivalent to calling @code{pthread_exit} with the result | 
 | returned by @var{start_routine} as exit code. | 
 |  | 
 | The @var{attr} argument specifies thread attributes to be applied to the | 
 | new thread. @xref{Thread Attributes}, for details. The @var{attr} | 
 | argument can also be @code{NULL}, in which case default attributes are | 
 | used: the created thread is joinable (not detached) and has an ordinary | 
 | (not realtime) scheduling policy. | 
 |  | 
 | On success, the identifier of the newly created thread is stored in the | 
 | location pointed by the @var{thread} argument, and a 0 is returned. On | 
 | error, a non-zero error code is returned. | 
 |  | 
 | This function may return the following errors: | 
 | @table @code | 
 | @item EAGAIN | 
 | Not enough system resources to create a process for the new thread, | 
 | or more than @code{PTHREAD_THREADS_MAX} threads are already active. | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun void pthread_exit (void *@var{retval}) | 
 | @code{pthread_exit} terminates the execution of the calling thread.  All | 
 | cleanup handlers (@pxref{Cleanup Handlers}) that have been set for the | 
 | calling thread with @code{pthread_cleanup_push} are executed in reverse | 
 | order (the most recently pushed handler is executed first). Finalization | 
 | functions for thread-specific data are then called for all keys that | 
 | have non-@code{NULL} values associated with them in the calling thread | 
 | (@pxref{Thread-Specific Data}).  Finally, execution of the calling | 
 | thread is stopped. | 
 |  | 
 | The @var{retval} argument is the return value of the thread. It can be | 
 | retrieved from another thread using @code{pthread_join}. | 
 |  | 
 | The @code{pthread_exit} function never returns. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_cancel (pthread_t @var{thread}) | 
 |  | 
 | @code{pthread_cancel} sends a cancellation request to the thread denoted | 
 | by the @var{thread} argument.  If there is no such thread, | 
 | @code{pthread_cancel} fails and returns @code{ESRCH}.  Otherwise it | 
 | returns 0. @xref{Cancellation}, for details. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_join (pthread_t @var{th}, void **thread_@var{return}) | 
 | @code{pthread_join} suspends the execution of the calling thread until | 
 | the thread identified by @var{th} terminates, either by calling | 
 | @code{pthread_exit} or by being canceled. | 
 |  | 
 | If @var{thread_return} is not @code{NULL}, the return value of @var{th} | 
 | is stored in the location pointed to by @var{thread_return}.  The return | 
 | value of @var{th} is either the argument it gave to @code{pthread_exit}, | 
 | or @code{PTHREAD_CANCELED} if @var{th} was canceled. | 
 |  | 
 | The joined thread @code{th} must be in the joinable state: it must not | 
 | have been detached using @code{pthread_detach} or the | 
 | @code{PTHREAD_CREATE_DETACHED} attribute to @code{pthread_create}. | 
 |  | 
 | When a joinable thread terminates, its memory resources (thread | 
 | descriptor and stack) are not deallocated until another thread performs | 
 | @code{pthread_join} on it. Therefore, @code{pthread_join} must be called | 
 | once for each joinable thread created to avoid memory leaks. | 
 |  | 
 | At most one thread can wait for the termination of a given | 
 | thread. Calling @code{pthread_join} on a thread @var{th} on which | 
 | another thread is already waiting for termination returns an error. | 
 |  | 
 | @code{pthread_join} is a cancellation point. If a thread is canceled | 
 | while suspended in @code{pthread_join}, the thread execution resumes | 
 | immediately and the cancellation is executed without waiting for the | 
 | @var{th} thread to terminate. If cancellation occurs during | 
 | @code{pthread_join}, the @var{th} thread remains not joined. | 
 |  | 
 | On success, the return value of @var{th} is stored in the location | 
 | pointed to by @var{thread_return}, and 0 is returned. On error, one of | 
 | the following values is returned: | 
 | @table @code | 
 | @item ESRCH | 
 | No thread could be found corresponding to that specified by @var{th}. | 
 | @item EINVAL | 
 | The @var{th} thread has been detached, or another thread is already | 
 | waiting on termination of @var{th}. | 
 | @item EDEADLK | 
 | The @var{th} argument refers to the calling thread. | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @node Thread Attributes | 
 | @section Thread Attributes | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 |  | 
 | Threads have a number of attributes that may be set at creation time. | 
 | This is done by filling a thread attribute object @var{attr} of type | 
 | @code{pthread_attr_t}, then passing it as second argument to | 
 | @code{pthread_create}. Passing @code{NULL} is equivalent to passing a | 
 | thread attribute object with all attributes set to their default values. | 
 |  | 
 | Attribute objects are consulted only when creating a new thread.  The | 
 | same attribute object can be used for creating several threads. | 
 | Modifying an attribute object after a call to @code{pthread_create} does | 
 | not change the attributes of the thread previously created. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_attr_init (pthread_attr_t *@var{attr}) | 
 | @code{pthread_attr_init} initializes the thread attribute object | 
 | @var{attr} and fills it with default values for the attributes. (The | 
 | default values are listed below for each attribute.) | 
 |  | 
 | Each attribute @var{attrname} (see below for a list of all attributes) | 
 | can be individually set using the function | 
 | @code{pthread_attr_set@var{attrname}} and retrieved using the function | 
 | @code{pthread_attr_get@var{attrname}}. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_attr_destroy (pthread_attr_t *@var{attr}) | 
 | @code{pthread_attr_destroy} destroys the attribute object pointed to by | 
 | @var{attr} releasing any resources associated with it.  @var{attr} is | 
 | left in an undefined state, and you must not use it again in a call to | 
 | any pthreads function until it has been reinitialized. | 
 | @end deftypefun | 
 |  | 
 | @findex pthread_attr_setdetachstate | 
 | @findex pthread_attr_setguardsize | 
 | @findex pthread_attr_setinheritsched | 
 | @findex pthread_attr_setschedparam | 
 | @findex pthread_attr_setschedpolicy | 
 | @findex pthread_attr_setscope | 
 | @findex pthread_attr_setstack | 
 | @findex pthread_attr_setstackaddr | 
 | @findex pthread_attr_setstacksize | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_attr_setattr (pthread_attr_t *@var{obj}, int @var{value}) | 
 | Set attribute @var{attr} to @var{value} in the attribute object pointed | 
 | to by @var{obj}.  See below for a list of possible attributes and the | 
 | values they can take. | 
 |  | 
 | On success, these functions return 0.  If @var{value} is not meaningful | 
 | for the @var{attr} being modified, they will return the error code | 
 | @code{EINVAL}.  Some of the functions have other failure modes; see | 
 | below. | 
 | @end deftypefun | 
 |  | 
 | @findex pthread_attr_getdetachstate | 
 | @findex pthread_attr_getguardsize | 
 | @findex pthread_attr_getinheritsched | 
 | @findex pthread_attr_getschedparam | 
 | @findex pthread_attr_getschedpolicy | 
 | @findex pthread_attr_getscope | 
 | @findex pthread_attr_getstack | 
 | @findex pthread_attr_getstackaddr | 
 | @findex pthread_attr_getstacksize | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_attr_getattr (const pthread_attr_t *@var{obj}, int *@var{value}) | 
 | Store the current setting of @var{attr} in @var{obj} into the variable | 
 | pointed to by @var{value}. | 
 |  | 
 | These functions always return 0. | 
 | @end deftypefun | 
 |  | 
 | The following thread attributes are supported: | 
 | @table @samp | 
 | @item detachstate | 
 | Choose whether the thread is created in the joinable state (value | 
 | @code{PTHREAD_CREATE_JOINABLE}) or in the detached state | 
 | (@code{PTHREAD_CREATE_DETACHED}).  The default is | 
 | @code{PTHREAD_CREATE_JOINABLE}. | 
 |  | 
 | In the joinable state, another thread can synchronize on the thread | 
 | termination and recover its termination code using @code{pthread_join}, | 
 | but some of the thread resources are kept allocated after the thread | 
 | terminates, and reclaimed only when another thread performs | 
 | @code{pthread_join} on that thread. | 
 |  | 
 | In the detached state, the thread resources are immediately freed when | 
 | it terminates, but @code{pthread_join} cannot be used to synchronize on | 
 | the thread termination. | 
 |  | 
 | A thread created in the joinable state can later be put in the detached | 
 | thread using @code{pthread_detach}. | 
 |  | 
 | @item schedpolicy | 
 | Select the scheduling policy for the thread: one of @code{SCHED_OTHER} | 
 | (regular, non-realtime scheduling), @code{SCHED_RR} (realtime, | 
 | round-robin) or @code{SCHED_FIFO} (realtime, first-in first-out). | 
 | The default is @code{SCHED_OTHER}. | 
 | @c Not doc'd in our manual: FIXME. | 
 | @c See @code{sched_setpolicy} for more information on scheduling policies. | 
 |  | 
 | The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO} | 
 | are available only to processes with superuser privileges. | 
 | @code{pthread_attr_setschedparam} will fail and return @code{ENOTSUP} if | 
 | you try to set a realtime policy when you are unprivileged. | 
 |  | 
 | The scheduling policy of a thread can be changed after creation with | 
 | @code{pthread_setschedparam}. | 
 |  | 
 | @item schedparam | 
 | Change the scheduling parameter (the scheduling priority) | 
 | for the thread.  The default is 0. | 
 |  | 
 | This attribute is not significant if the scheduling policy is | 
 | @code{SCHED_OTHER}; it only matters for the realtime policies | 
 | @code{SCHED_RR} and @code{SCHED_FIFO}. | 
 |  | 
 | The scheduling priority of a thread can be changed after creation with | 
 | @code{pthread_setschedparam}. | 
 |  | 
 | @item inheritsched | 
 | Choose whether the scheduling policy and scheduling parameter for the | 
 | newly created thread are determined by the values of the | 
 | @var{schedpolicy} and @var{schedparam} attributes (value | 
 | @code{PTHREAD_EXPLICIT_SCHED}) or are inherited from the parent thread | 
 | (value @code{PTHREAD_INHERIT_SCHED}).  The default is | 
 | @code{PTHREAD_EXPLICIT_SCHED}. | 
 |  | 
 | @item scope | 
 | Choose the scheduling contention scope for the created thread.  The | 
 | default is @code{PTHREAD_SCOPE_SYSTEM}, meaning that the threads contend | 
 | for CPU time with all processes running on the machine. In particular, | 
 | thread priorities are interpreted relative to the priorities of all | 
 | other processes on the machine. The other possibility, | 
 | @code{PTHREAD_SCOPE_PROCESS}, means that scheduling contention occurs | 
 | only between the threads of the running process: thread priorities are | 
 | interpreted relative to the priorities of the other threads of the | 
 | process, regardless of the priorities of other processes. | 
 |  | 
 | @code{PTHREAD_SCOPE_PROCESS} is not supported in LinuxThreads.  If you | 
 | try to set the scope to this value, @code{pthread_attr_setscope} will | 
 | fail and return @code{ENOTSUP}. | 
 |  | 
 | @item stackaddr | 
 | Provide an address for an application managed stack.  The size of the | 
 | stack must be at least @code{PTHREAD_STACK_MIN}. | 
 |  | 
 | @item stacksize | 
 | Change the size of the stack created for the thread.  The value defines | 
 | the minimum stack size, in bytes. | 
 |  | 
 | If the value exceeds the system's maximum stack size, or is smaller | 
 | than @code{PTHREAD_STACK_MIN}, @code{pthread_attr_setstacksize} will | 
 | fail and return @code{EINVAL}. | 
 |  | 
 | @item stack | 
 | Provide both the address and size of an application managed stack to | 
 | use for the new thread.  The base of the memory area is @var{stackaddr} | 
 | with the size of the memory area, @var{stacksize}, measured in bytes. | 
 |  | 
 | If the value of @var{stacksize} is less than @code{PTHREAD_STACK_MIN}, | 
 | or greater than the system's maximum stack size, or if the value of | 
 | @var{stackaddr} lacks the proper alignment, @code{pthread_attr_setstack} | 
 | will fail and return @code{EINVAL}. | 
 |  | 
 | @item guardsize | 
 | Change the minimum size in bytes of the guard area for the thread's | 
 | stack.  The default size is a single page.  If this value is set, it | 
 | will be rounded up to the nearest page size.  If the value is set to 0, | 
 | a guard area will not be created for this thread.  The space allocated | 
 | for the guard area is used to catch stack overflow.  Therefore, when | 
 | allocating large structures on the stack, a larger guard area may be | 
 | required to catch a stack overflow. | 
 |  | 
 | If the caller is managing their own stacks (if the @code{stackaddr} | 
 | attribute has been set), then the @code{guardsize} attribute is ignored. | 
 |  | 
 | If the value exceeds the @code{stacksize}, @code{pthread_atrr_setguardsize} | 
 | will fail and return @code{EINVAL}. | 
 | @end table | 
 |  | 
 | @node Cancellation | 
 | @section Cancellation | 
 |  | 
 | Cancellation is the mechanism by which a thread can terminate the | 
 | execution of another thread. More precisely, a thread can send a | 
 | cancellation request to another thread. Depending on its settings, the | 
 | target thread can then either ignore the request, honor it immediately, | 
 | or defer it till it reaches a cancellation point.  When threads are | 
 | first created by @code{pthread_create}, they always defer cancellation | 
 | requests. | 
 |  | 
 | When a thread eventually honors a cancellation request, it behaves as if | 
 | @code{pthread_exit(PTHREAD_CANCELED)} was called.  All cleanup handlers | 
 | are executed in reverse order, finalization functions for | 
 | thread-specific data are called, and finally the thread stops executing. | 
 | If the canceled thread was joinable, the return value | 
 | @code{PTHREAD_CANCELED} is provided to whichever thread calls | 
 | @var{pthread_join} on it. See @code{pthread_exit} for more information. | 
 |  | 
 | Cancellation points are the points where the thread checks for pending | 
 | cancellation requests and performs them.  The POSIX threads functions | 
 | @code{pthread_join}, @code{pthread_cond_wait}, | 
 | @code{pthread_cond_timedwait}, @code{pthread_testcancel}, | 
 | @code{sem_wait}, and @code{sigwait} are cancellation points.  In | 
 | addition, these system calls are cancellation points: | 
 |  | 
 | @multitable @columnfractions .33 .33 .33 | 
 | @item @t{accept}	@tab @t{open}		@tab @t{sendmsg} | 
 | @item @t{close}		@tab @t{pause}		@tab @t{sendto} | 
 | @item @t{connect}	@tab @t{read}		@tab @t{system} | 
 | @item @t{fcntl}		@tab @t{recv}		@tab @t{tcdrain} | 
 | @item @t{fsync}		@tab @t{recvfrom}	@tab @t{wait} | 
 | @item @t{lseek}		@tab @t{recvmsg}	@tab @t{waitpid} | 
 | @item @t{msync}		@tab @t{send}		@tab @t{write} | 
 | @item @t{nanosleep} | 
 | @end multitable | 
 |  | 
 | @noindent | 
 | All library functions that call these functions (such as | 
 | @code{printf}) are also cancellation points. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_setcancelstate (int @var{state}, int *@var{oldstate}) | 
 | @code{pthread_setcancelstate} changes the cancellation state for the | 
 | calling thread -- that is, whether cancellation requests are ignored or | 
 | not. The @var{state} argument is the new cancellation state: either | 
 | @code{PTHREAD_CANCEL_ENABLE} to enable cancellation, or | 
 | @code{PTHREAD_CANCEL_DISABLE} to disable cancellation (cancellation | 
 | requests are ignored). | 
 |  | 
 | If @var{oldstate} is not @code{NULL}, the previous cancellation state is | 
 | stored in the location pointed to by @var{oldstate}, and can thus be | 
 | restored later by another call to @code{pthread_setcancelstate}. | 
 |  | 
 | If the @var{state} argument is not @code{PTHREAD_CANCEL_ENABLE} or | 
 | @code{PTHREAD_CANCEL_DISABLE}, @code{pthread_setcancelstate} fails and | 
 | returns @code{EINVAL}.  Otherwise it returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_setcanceltype (int @var{type}, int *@var{oldtype}) | 
 | @code{pthread_setcanceltype} changes the type of responses to | 
 | cancellation requests for the calling thread: asynchronous (immediate) | 
 | or deferred.  The @var{type} argument is the new cancellation type: | 
 | either @code{PTHREAD_CANCEL_ASYNCHRONOUS} to cancel the calling thread | 
 | as soon as the cancellation request is received, or | 
 | @code{PTHREAD_CANCEL_DEFERRED} to keep the cancellation request pending | 
 | until the next cancellation point. If @var{oldtype} is not @code{NULL}, | 
 | the previous cancellation state is stored in the location pointed to by | 
 | @var{oldtype}, and can thus be restored later by another call to | 
 | @code{pthread_setcanceltype}. | 
 |  | 
 | If the @var{type} argument is not @code{PTHREAD_CANCEL_DEFERRED} or | 
 | @code{PTHREAD_CANCEL_ASYNCHRONOUS}, @code{pthread_setcanceltype} fails | 
 | and returns @code{EINVAL}.  Otherwise it returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun void pthread_testcancel (@var{void}) | 
 | @code{pthread_testcancel} does nothing except testing for pending | 
 | cancellation and executing it. Its purpose is to introduce explicit | 
 | checks for cancellation in long sequences of code that do not call | 
 | cancellation point functions otherwise. | 
 | @end deftypefun | 
 |  | 
 | @node Cleanup Handlers | 
 | @section Cleanup Handlers | 
 |  | 
 | Cleanup handlers are functions that get called when a thread terminates, | 
 | either by calling @code{pthread_exit} or because of | 
 | cancellation. Cleanup handlers are installed and removed following a | 
 | stack-like discipline. | 
 |  | 
 | The purpose of cleanup handlers is to free the resources that a thread | 
 | may hold at the time it terminates. In particular, if a thread exits or | 
 | is canceled while it owns a locked mutex, the mutex will remain locked | 
 | forever and prevent other threads from executing normally. The best way | 
 | to avoid this is, just before locking the mutex, to install a cleanup | 
 | handler whose effect is to unlock the mutex. Cleanup handlers can be | 
 | used similarly to free blocks allocated with @code{malloc} or close file | 
 | descriptors on thread termination. | 
 |  | 
 | Here is how to lock a mutex @var{mut} in such a way that it will be | 
 | unlocked if the thread is canceled while @var{mut} is locked: | 
 |  | 
 | @smallexample | 
 | pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut); | 
 | pthread_mutex_lock(&mut); | 
 | /* do some work */ | 
 | pthread_mutex_unlock(&mut); | 
 | pthread_cleanup_pop(0); | 
 | @end smallexample | 
 |  | 
 | Equivalently, the last two lines can be replaced by | 
 |  | 
 | @smallexample | 
 | pthread_cleanup_pop(1); | 
 | @end smallexample | 
 |  | 
 | Notice that the code above is safe only in deferred cancellation mode | 
 | (see @code{pthread_setcanceltype}). In asynchronous cancellation mode, a | 
 | cancellation can occur between @code{pthread_cleanup_push} and | 
 | @code{pthread_mutex_lock}, or between @code{pthread_mutex_unlock} and | 
 | @code{pthread_cleanup_pop}, resulting in both cases in the thread trying | 
 | to unlock a mutex not locked by the current thread. This is the main | 
 | reason why asynchronous cancellation is difficult to use. | 
 |  | 
 | If the code above must also work in asynchronous cancellation mode, | 
 | then it must switch to deferred mode for locking and unlocking the | 
 | mutex: | 
 |  | 
 | @smallexample | 
 | pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); | 
 | pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut); | 
 | pthread_mutex_lock(&mut); | 
 | /* do some work */ | 
 | pthread_cleanup_pop(1); | 
 | pthread_setcanceltype(oldtype, NULL); | 
 | @end smallexample | 
 |  | 
 | The code above can be rewritten in a more compact and efficient way, | 
 | using the non-portable functions @code{pthread_cleanup_push_defer_np} | 
 | and @code{pthread_cleanup_pop_restore_np}: | 
 |  | 
 | @smallexample | 
 | pthread_cleanup_push_defer_np(pthread_mutex_unlock, (void *) &mut); | 
 | pthread_mutex_lock(&mut); | 
 | /* do some work */ | 
 | pthread_cleanup_pop_restore_np(1); | 
 | @end smallexample | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun void pthread_cleanup_push (void (*@var{routine}) (void *), void *@var{arg}) | 
 |  | 
 | @code{pthread_cleanup_push} installs the @var{routine} function with | 
 | argument @var{arg} as a cleanup handler. From this point on to the | 
 | matching @code{pthread_cleanup_pop}, the function @var{routine} will be | 
 | called with arguments @var{arg} when the thread terminates, either | 
 | through @code{pthread_exit} or by cancellation. If several cleanup | 
 | handlers are active at that point, they are called in LIFO order: the | 
 | most recently installed handler is called first. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun void pthread_cleanup_pop (int @var{execute}) | 
 | @code{pthread_cleanup_pop} removes the most recently installed cleanup | 
 | handler. If the @var{execute} argument is not 0, it also executes the | 
 | handler, by calling the @var{routine} function with arguments | 
 | @var{arg}. If the @var{execute} argument is 0, the handler is only | 
 | removed but not executed. | 
 | @end deftypefun | 
 |  | 
 | Matching pairs of @code{pthread_cleanup_push} and | 
 | @code{pthread_cleanup_pop} must occur in the same function, at the same | 
 | level of block nesting.  Actually, @code{pthread_cleanup_push} and | 
 | @code{pthread_cleanup_pop} are macros, and the expansion of | 
 | @code{pthread_cleanup_push} introduces an open brace @code{@{} with the | 
 | matching closing brace @code{@}} being introduced by the expansion of the | 
 | matching @code{pthread_cleanup_pop}. | 
 |  | 
 | @comment pthread.h | 
 | @comment GNU | 
 | @deftypefun void pthread_cleanup_push_defer_np (void (*@var{routine}) (void *), void *@var{arg}) | 
 | @code{pthread_cleanup_push_defer_np} is a non-portable extension that | 
 | combines @code{pthread_cleanup_push} and @code{pthread_setcanceltype}. | 
 | It pushes a cleanup handler just as @code{pthread_cleanup_push} does, | 
 | but also saves the current cancellation type and sets it to deferred | 
 | cancellation. This ensures that the cleanup mechanism is effective even | 
 | if the thread was initially in asynchronous cancellation mode. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment GNU | 
 | @deftypefun void pthread_cleanup_pop_restore_np (int @var{execute}) | 
 | @code{pthread_cleanup_pop_restore_np} pops a cleanup handler introduced | 
 | by @code{pthread_cleanup_push_defer_np}, and restores the cancellation | 
 | type to its value at the time @code{pthread_cleanup_push_defer_np} was | 
 | called. | 
 | @end deftypefun | 
 |  | 
 | @code{pthread_cleanup_push_defer_np} and | 
 | @code{pthread_cleanup_pop_restore_np} must occur in matching pairs, at | 
 | the same level of block nesting. | 
 |  | 
 | The sequence | 
 |  | 
 | @smallexample | 
 | pthread_cleanup_push_defer_np(routine, arg); | 
 | ... | 
 | pthread_cleanup_pop_restore_np(execute); | 
 | @end smallexample | 
 |  | 
 | @noindent | 
 | is functionally equivalent to (but more compact and efficient than) | 
 |  | 
 | @smallexample | 
 | @{ | 
 |   int oldtype; | 
 |   pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); | 
 |   pthread_cleanup_push(routine, arg); | 
 |   ... | 
 |   pthread_cleanup_pop(execute); | 
 |   pthread_setcanceltype(oldtype, NULL); | 
 | @} | 
 | @end smallexample | 
 |  | 
 |  | 
 | @node Mutexes | 
 | @section Mutexes | 
 |  | 
 | A mutex is a MUTual EXclusion device, and is useful for protecting | 
 | shared data structures from concurrent modifications, and implementing | 
 | critical sections and monitors. | 
 |  | 
 | A mutex has two possible states: unlocked (not owned by any thread), | 
 | and locked (owned by one thread). A mutex can never be owned by two | 
 | different threads simultaneously. A thread attempting to lock a mutex | 
 | that is already locked by another thread is suspended until the owning | 
 | thread unlocks the mutex first. | 
 |  | 
 | None of the mutex functions is a cancellation point, not even | 
 | @code{pthread_mutex_lock}, in spite of the fact that it can suspend a | 
 | thread for arbitrary durations. This way, the status of mutexes at | 
 | cancellation points is predictable, allowing cancellation handlers to | 
 | unlock precisely those mutexes that need to be unlocked before the | 
 | thread stops executing. Consequently, threads using deferred | 
 | cancellation should never hold a mutex for extended periods of time. | 
 |  | 
 | It is not safe to call mutex functions from a signal handler.  In | 
 | particular, calling @code{pthread_mutex_lock} or | 
 | @code{pthread_mutex_unlock} from a signal handler may deadlock the | 
 | calling thread. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutex_init (pthread_mutex_t *@var{mutex}, const pthread_mutexattr_t *@var{mutexattr}) | 
 |  | 
 | @code{pthread_mutex_init} initializes the mutex object pointed to by | 
 | @var{mutex} according to the mutex attributes specified in @var{mutexattr}. | 
 | If @var{mutexattr} is @code{NULL}, default attributes are used instead. | 
 |  | 
 | The LinuxThreads implementation supports only one mutex attribute, | 
 | the @var{mutex type}, which is either ``fast'', ``recursive'', or | 
 | ``error checking''. The type of a mutex determines whether | 
 | it can be locked again by a thread that already owns it. | 
 | The default type is ``fast''. | 
 |  | 
 | Variables of type @code{pthread_mutex_t} can also be initialized | 
 | statically, using the constants @code{PTHREAD_MUTEX_INITIALIZER} (for | 
 | timed mutexes), @code{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} (for | 
 | recursive mutexes), @code{PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP} | 
 | (for fast mutexes(, and @code{PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP} | 
 | (for error checking mutexes). | 
 |  | 
 | @code{pthread_mutex_init} always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutex_lock (pthread_mutex_t *mutex)) | 
 | @code{pthread_mutex_lock} locks the given mutex. If the mutex is | 
 | currently unlocked, it becomes locked and owned by the calling thread, | 
 | and @code{pthread_mutex_lock} returns immediately. If the mutex is | 
 | already locked by another thread, @code{pthread_mutex_lock} suspends the | 
 | calling thread until the mutex is unlocked. | 
 |  | 
 | If the mutex is already locked by the calling thread, the behavior of | 
 | @code{pthread_mutex_lock} depends on the type of the mutex. If the mutex | 
 | is of the ``fast'' type, the calling thread is suspended.  It will | 
 | remain suspended forever, because no other thread can unlock the mutex. | 
 | If  the mutex is of the ``error checking'' type, @code{pthread_mutex_lock} | 
 | returns immediately with the error code @code{EDEADLK}.  If the mutex is | 
 | of the ``recursive'' type, @code{pthread_mutex_lock} succeeds and | 
 | returns immediately, recording the number of times the calling thread | 
 | has locked the mutex. An equal number of @code{pthread_mutex_unlock} | 
 | operations must be performed before the mutex returns to the unlocked | 
 | state. | 
 | @c This doesn't discuss PTHREAD_MUTEX_TIMED_NP mutex attributes. FIXME | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutex_trylock (pthread_mutex_t *@var{mutex}) | 
 | @code{pthread_mutex_trylock} behaves identically to | 
 | @code{pthread_mutex_lock}, except that it does not block the calling | 
 | thread if the mutex is already locked by another thread (or by the | 
 | calling thread in the case of a ``fast'' mutex). Instead, | 
 | @code{pthread_mutex_trylock} returns immediately with the error code | 
 | @code{EBUSY}. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutex_timedlock (pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime}) | 
 | The @code{pthread_mutex_timedlock} is similar to the | 
 | @code{pthread_mutex_lock} function but instead of blocking for in | 
 | indefinite time if the mutex is locked by another thread, it returns | 
 | when the time specified in @var{abstime} is reached. | 
 |  | 
 | This function can only be used on standard (``timed'') and ``error | 
 | checking'' mutexes.  It behaves just like @code{pthread_mutex_lock} for | 
 | all other types. | 
 |  | 
 | If the mutex is successfully locked, the function returns zero.  If the | 
 | time specified in @var{abstime} is reached without the mutex being locked, | 
 | @code{ETIMEDOUT} is returned. | 
 |  | 
 | This function was introduced in the POSIX.1d revision of the POSIX standard. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutex_unlock (pthread_mutex_t *@var{mutex}) | 
 | @code{pthread_mutex_unlock} unlocks the given mutex. The mutex is | 
 | assumed to be locked and owned by the calling thread on entrance to | 
 | @code{pthread_mutex_unlock}. If the mutex is of the ``fast'' type, | 
 | @code{pthread_mutex_unlock} always returns it to the unlocked state. If | 
 | it is of the ``recursive'' type, it decrements the locking count of the | 
 | mutex (number of @code{pthread_mutex_lock} operations performed on it by | 
 | the calling thread), and only when this count reaches zero is the mutex | 
 | actually unlocked. | 
 |  | 
 | On ``error checking'' mutexes, @code{pthread_mutex_unlock} actually | 
 | checks at run-time that the mutex is locked on entrance, and that it was | 
 | locked by the same thread that is now calling | 
 | @code{pthread_mutex_unlock}.  If these conditions are not met, | 
 | @code{pthread_mutex_unlock} returns @code{EPERM}, and the mutex remains | 
 | unchanged.  ``Fast'' and ``recursive'' mutexes perform no such checks, | 
 | thus allowing a locked mutex to be unlocked by a thread other than its | 
 | owner. This is non-portable behavior and must not be relied upon. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutex_destroy (pthread_mutex_t *@var{mutex}) | 
 | @code{pthread_mutex_destroy} destroys a mutex object, freeing the | 
 | resources it might hold. The mutex must be unlocked on entrance. In the | 
 | LinuxThreads implementation, no resources are associated with mutex | 
 | objects, thus @code{pthread_mutex_destroy} actually does nothing except | 
 | checking that the mutex is unlocked. | 
 |  | 
 | If the mutex is locked by some thread, @code{pthread_mutex_destroy} | 
 | returns @code{EBUSY}.  Otherwise it returns 0. | 
 | @end deftypefun | 
 |  | 
 | If any of the above functions (except @code{pthread_mutex_init}) | 
 | is applied to an uninitialized mutex, they will simply return | 
 | @code{EINVAL} and do nothing. | 
 |  | 
 | A shared global variable @var{x} can be protected by a mutex as follows: | 
 |  | 
 | @smallexample | 
 | int x; | 
 | pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | 
 | @end smallexample | 
 |  | 
 | All accesses and modifications to @var{x} should be bracketed by calls to | 
 | @code{pthread_mutex_lock} and @code{pthread_mutex_unlock} as follows: | 
 |  | 
 | @smallexample | 
 | pthread_mutex_lock(&mut); | 
 | /* operate on x */ | 
 | pthread_mutex_unlock(&mut); | 
 | @end smallexample | 
 |  | 
 | Mutex attributes can be specified at mutex creation time, by passing a | 
 | mutex attribute object as second argument to @code{pthread_mutex_init}. | 
 | Passing @code{NULL} is equivalent to passing a mutex attribute object | 
 | with all attributes set to their default values. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutexattr_init (pthread_mutexattr_t *@var{attr}) | 
 | @code{pthread_mutexattr_init} initializes the mutex attribute object | 
 | @var{attr} and fills it with default values for the attributes. | 
 |  | 
 | This function always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutexattr_destroy (pthread_mutexattr_t *@var{attr}) | 
 | @code{pthread_mutexattr_destroy} destroys a mutex attribute object, | 
 | which must not be reused until it is | 
 | reinitialized. @code{pthread_mutexattr_destroy} does nothing in the | 
 | LinuxThreads implementation. | 
 |  | 
 | This function always returns 0. | 
 | @end deftypefun | 
 |  | 
 | LinuxThreads supports only one mutex attribute: the mutex type, which is | 
 | either @code{PTHREAD_MUTEX_ADAPTIVE_NP} for ``fast'' mutexes, | 
 | @code{PTHREAD_MUTEX_RECURSIVE_NP} for ``recursive'' mutexes, | 
 | @code{PTHREAD_MUTEX_TIMED_NP} for ``timed'' mutexes, or | 
 | @code{PTHREAD_MUTEX_ERRORCHECK_NP} for ``error checking'' mutexes.  As | 
 | the @code{NP} suffix indicates, this is a non-portable extension to the | 
 | POSIX standard and should not be employed in portable programs. | 
 |  | 
 | The mutex type determines what happens if a thread attempts to lock a | 
 | mutex it already owns with @code{pthread_mutex_lock}. If the mutex is of | 
 | the ``fast'' type, @code{pthread_mutex_lock} simply suspends the calling | 
 | thread forever.  If the mutex is of the ``error checking'' type, | 
 | @code{pthread_mutex_lock} returns immediately with the error code | 
 | @code{EDEADLK}.  If the mutex is of the ``recursive'' type, the call to | 
 | @code{pthread_mutex_lock} returns immediately with a success return | 
 | code. The number of times the thread owning the mutex has locked it is | 
 | recorded in the mutex. The owning thread must call | 
 | @code{pthread_mutex_unlock} the same number of times before the mutex | 
 | returns to the unlocked state. | 
 |  | 
 | The default mutex type is ``timed'', that is, @code{PTHREAD_MUTEX_TIMED_NP}. | 
 | @c This doesn't describe how a ``timed'' mutex behaves. FIXME | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutexattr_settype (pthread_mutexattr_t *@var{attr}, int @var{type}) | 
 | @code{pthread_mutexattr_settype} sets the mutex type attribute in | 
 | @var{attr} to the value specified by @var{type}. | 
 |  | 
 | If @var{type} is not @code{PTHREAD_MUTEX_ADAPTIVE_NP}, | 
 | @code{PTHREAD_MUTEX_RECURSIVE_NP}, @code{PTHREAD_MUTEX_TIMED_NP}, or | 
 | @code{PTHREAD_MUTEX_ERRORCHECK_NP}, this function will return | 
 | @code{EINVAL} and leave @var{attr} unchanged. | 
 |  | 
 | The standard Unix98 identifiers @code{PTHREAD_MUTEX_DEFAULT}, | 
 | @code{PTHREAD_MUTEX_NORMAL}, @code{PTHREAD_MUTEX_RECURSIVE}, | 
 | and @code{PTHREAD_MUTEX_ERRORCHECK} are also permitted. | 
 |  | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_mutexattr_gettype (const pthread_mutexattr_t *@var{attr}, int *@var{type}) | 
 | @code{pthread_mutexattr_gettype} retrieves the current value of the | 
 | mutex type attribute in @var{attr} and stores it in the location pointed | 
 | to by @var{type}. | 
 |  | 
 | This function always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @node Condition Variables | 
 | @section Condition Variables | 
 |  | 
 | A condition (short for ``condition variable'') is a synchronization | 
 | device that allows threads to suspend execution until some predicate on | 
 | shared data is satisfied. The basic operations on conditions are: signal | 
 | the condition (when the predicate becomes true), and wait for the | 
 | condition, suspending the thread execution until another thread signals | 
 | the condition. | 
 |  | 
 | A condition variable must always be associated with a mutex, to avoid | 
 | the race condition where a thread prepares to wait on a condition | 
 | variable and another thread signals the condition just before the first | 
 | thread actually waits on it. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_cond_init (pthread_cond_t *@var{cond}, pthread_condattr_t *cond_@var{attr}) | 
 |  | 
 | @code{pthread_cond_init} initializes the condition variable @var{cond}, | 
 | using the condition attributes specified in @var{cond_attr}, or default | 
 | attributes if @var{cond_attr} is @code{NULL}. The LinuxThreads | 
 | implementation supports no attributes for conditions, hence the | 
 | @var{cond_attr} parameter is actually ignored. | 
 |  | 
 | Variables of type @code{pthread_cond_t} can also be initialized | 
 | statically, using the constant @code{PTHREAD_COND_INITIALIZER}. | 
 |  | 
 | This function always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_cond_signal (pthread_cond_t *@var{cond}) | 
 | @code{pthread_cond_signal} restarts one of the threads that are waiting | 
 | on the condition variable @var{cond}. If no threads are waiting on | 
 | @var{cond}, nothing happens. If several threads are waiting on | 
 | @var{cond}, exactly one is restarted, but it is not specified which. | 
 |  | 
 | This function always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_cond_broadcast (pthread_cond_t *@var{cond}) | 
 | @code{pthread_cond_broadcast} restarts all the threads that are waiting | 
 | on the condition variable @var{cond}. Nothing happens if no threads are | 
 | waiting on @var{cond}. | 
 |  | 
 | This function always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_cond_wait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex}) | 
 | @code{pthread_cond_wait} atomically unlocks the @var{mutex} (as per | 
 | @code{pthread_unlock_mutex}) and waits for the condition variable | 
 | @var{cond} to be signaled. The thread execution is suspended and does | 
 | not consume any CPU time until the condition variable is signaled. The | 
 | @var{mutex} must be locked by the calling thread on entrance to | 
 | @code{pthread_cond_wait}. Before returning to the calling thread, | 
 | @code{pthread_cond_wait} re-acquires @var{mutex} (as per | 
 | @code{pthread_lock_mutex}). | 
 |  | 
 | Unlocking the mutex and suspending on the condition variable is done | 
 | atomically. Thus, if all threads always acquire the mutex before | 
 | signaling the condition, this guarantees that the condition cannot be | 
 | signaled (and thus ignored) between the time a thread locks the mutex | 
 | and the time it waits on the condition variable. | 
 |  | 
 | This function always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_cond_timedwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime}) | 
 | @code{pthread_cond_timedwait} atomically unlocks @var{mutex} and waits | 
 | on @var{cond}, as @code{pthread_cond_wait} does, but it also bounds the | 
 | duration of the wait. If @var{cond} has not been signaled before time | 
 | @var{abstime}, the mutex @var{mutex} is re-acquired and | 
 | @code{pthread_cond_timedwait} returns the error code @code{ETIMEDOUT}. | 
 | The wait can also be interrupted by a signal; in that case | 
 | @code{pthread_cond_timedwait} returns @code{EINTR}. | 
 |  | 
 | The @var{abstime} parameter specifies an absolute time, with the same | 
 | origin as @code{time} and @code{gettimeofday}: an @var{abstime} of 0 | 
 | corresponds to 00:00:00 GMT, January 1, 1970. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_cond_destroy (pthread_cond_t *@var{cond}) | 
 | @code{pthread_cond_destroy} destroys the condition variable @var{cond}, | 
 | freeing the resources it might hold.  If any threads are waiting on the | 
 | condition variable, @code{pthread_cond_destroy} leaves @var{cond} | 
 | untouched and returns @code{EBUSY}.  Otherwise it returns 0, and | 
 | @var{cond} must not be used again until it is reinitialized. | 
 |  | 
 | In the LinuxThreads implementation, no resources are associated with | 
 | condition variables, so @code{pthread_cond_destroy} actually does | 
 | nothing. | 
 | @end deftypefun | 
 |  | 
 | @code{pthread_cond_wait} and @code{pthread_cond_timedwait} are | 
 | cancellation points. If a thread is canceled while suspended in one of | 
 | these functions, the thread immediately resumes execution, relocks the | 
 | mutex specified by  @var{mutex}, and finally executes the cancellation. | 
 | Consequently, cleanup handlers are assured that @var{mutex} is locked | 
 | when they are called. | 
 |  | 
 | It is not safe to call the condition variable functions from a signal | 
 | handler. In particular, calling @code{pthread_cond_signal} or | 
 | @code{pthread_cond_broadcast} from a signal handler may deadlock the | 
 | calling thread. | 
 |  | 
 | Consider two shared variables @var{x} and @var{y}, protected by the | 
 | mutex @var{mut}, and a condition variable @var{cond} that is to be | 
 | signaled whenever @var{x} becomes greater than @var{y}. | 
 |  | 
 | @smallexample | 
 | int x,y; | 
 | pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | 
 | pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | 
 | @end smallexample | 
 |  | 
 | Waiting until @var{x} is greater than @var{y} is performed as follows: | 
 |  | 
 | @smallexample | 
 | pthread_mutex_lock(&mut); | 
 | while (x <= y) @{ | 
 |         pthread_cond_wait(&cond, &mut); | 
 | @} | 
 | /* operate on x and y */ | 
 | pthread_mutex_unlock(&mut); | 
 | @end smallexample | 
 |  | 
 | Modifications on @var{x} and @var{y} that may cause @var{x} to become greater than | 
 | @var{y} should signal the condition if needed: | 
 |  | 
 | @smallexample | 
 | pthread_mutex_lock(&mut); | 
 | /* modify x and y */ | 
 | if (x > y) pthread_cond_broadcast(&cond); | 
 | pthread_mutex_unlock(&mut); | 
 | @end smallexample | 
 |  | 
 | If it can be proved that at most one waiting thread needs to be waken | 
 | up (for instance, if there are only two threads communicating through | 
 | @var{x} and @var{y}), @code{pthread_cond_signal} can be used as a slightly more | 
 | efficient alternative to @code{pthread_cond_broadcast}. In doubt, use | 
 | @code{pthread_cond_broadcast}. | 
 |  | 
 | To wait for @var{x} to becomes greater than @var{y} with a timeout of 5 | 
 | seconds, do: | 
 |  | 
 | @smallexample | 
 | struct timeval now; | 
 | struct timespec timeout; | 
 | int retcode; | 
 |  | 
 | pthread_mutex_lock(&mut); | 
 | gettimeofday(&now); | 
 | timeout.tv_sec = now.tv_sec + 5; | 
 | timeout.tv_nsec = now.tv_usec * 1000; | 
 | retcode = 0; | 
 | while (x <= y && retcode != ETIMEDOUT) @{ | 
 |         retcode = pthread_cond_timedwait(&cond, &mut, &timeout); | 
 | @} | 
 | if (retcode == ETIMEDOUT) @{ | 
 |         /* timeout occurred */ | 
 | @} else @{ | 
 |         /* operate on x and y */ | 
 | @} | 
 | pthread_mutex_unlock(&mut); | 
 | @end smallexample | 
 |  | 
 | Condition attributes can be specified at condition creation time, by | 
 | passing a condition attribute object as second argument to | 
 | @code{pthread_cond_init}.  Passing @code{NULL} is equivalent to passing | 
 | a condition attribute object with all attributes set to their default | 
 | values. | 
 |  | 
 | The LinuxThreads implementation supports no attributes for | 
 | conditions. The functions on condition attributes are included only for | 
 | compliance with the POSIX standard. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_condattr_init (pthread_condattr_t *@var{attr}) | 
 | @deftypefunx int pthread_condattr_destroy (pthread_condattr_t *@var{attr}) | 
 | @code{pthread_condattr_init} initializes the condition attribute object | 
 | @var{attr} and fills it with default values for the attributes. | 
 | @code{pthread_condattr_destroy} destroys the condition attribute object | 
 | @var{attr}. | 
 |  | 
 | Both functions do nothing in the LinuxThreads implementation. | 
 |  | 
 | @code{pthread_condattr_init} and @code{pthread_condattr_destroy} always | 
 | return 0. | 
 | @end deftypefun | 
 |  | 
 | @node POSIX Semaphores | 
 | @section POSIX Semaphores | 
 |  | 
 | @vindex SEM_VALUE_MAX | 
 | Semaphores are counters for resources shared between threads. The | 
 | basic operations on semaphores are: increment the counter atomically, | 
 | and wait until the counter is non-null and decrement it atomically. | 
 |  | 
 | Semaphores have a maximum value past which they cannot be incremented. | 
 | The macro @code{SEM_VALUE_MAX} is defined to be this maximum value.  In | 
 | the GNU C library, @code{SEM_VALUE_MAX} is equal to @code{INT_MAX} | 
 | (@pxref{Range of Type}), but it may be much smaller on other systems. | 
 |  | 
 | The pthreads library implements POSIX 1003.1b semaphores.  These should | 
 | not be confused with System V semaphores (@code{ipc}, @code{semctl} and | 
 | @code{semop}). | 
 | @c !!! SysV IPC is not doc'd at all in our manual | 
 |  | 
 | All the semaphore functions and macros are defined in @file{semaphore.h}. | 
 |  | 
 | @comment semaphore.h | 
 | @comment POSIX | 
 | @deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value}) | 
 | @code{sem_init} initializes the semaphore object pointed to by | 
 | @var{sem}. The count associated with the semaphore is set initially to | 
 | @var{value}. The @var{pshared} argument indicates whether the semaphore | 
 | is local to the current process (@var{pshared} is zero) or is to be | 
 | shared between several processes (@var{pshared} is not zero). | 
 |  | 
 | On success @code{sem_init} returns 0.  On failure it returns -1 and sets | 
 | @var{errno} to one of the following values: | 
 |  | 
 | @table @code | 
 | @item EINVAL | 
 | @var{value} exceeds the maximal counter value @code{SEM_VALUE_MAX} | 
 |  | 
 | @item ENOSYS | 
 | @var{pshared} is not zero.  LinuxThreads currently does not support | 
 | process-shared semaphores.  (This will eventually change.) | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @comment semaphore.h | 
 | @comment POSIX | 
 | @deftypefun int sem_destroy (sem_t * @var{sem}) | 
 | @code{sem_destroy} destroys a semaphore object, freeing the resources it | 
 | might hold.  If any threads are waiting on the semaphore when | 
 | @code{sem_destroy} is called, it fails and sets @var{errno} to | 
 | @code{EBUSY}. | 
 |  | 
 | In the LinuxThreads implementation, no resources are associated with | 
 | semaphore objects, thus @code{sem_destroy} actually does nothing except | 
 | checking that no thread is waiting on the semaphore.  This will change | 
 | when process-shared semaphores are implemented. | 
 | @end deftypefun | 
 |  | 
 | @comment semaphore.h | 
 | @comment POSIX | 
 | @deftypefun int sem_wait (sem_t * @var{sem}) | 
 | @code{sem_wait} suspends the calling thread until the semaphore pointed | 
 | to by @var{sem} has non-zero count. It then atomically decreases the | 
 | semaphore count. | 
 |  | 
 | @code{sem_wait} is a cancellation point.  It always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment semaphore.h | 
 | @comment POSIX | 
 | @deftypefun int sem_trywait (sem_t * @var{sem}) | 
 | @code{sem_trywait} is a non-blocking variant of @code{sem_wait}. If the | 
 | semaphore pointed to by @var{sem} has non-zero count, the count is | 
 | atomically decreased and @code{sem_trywait} immediately returns 0.  If | 
 | the semaphore count is zero, @code{sem_trywait} immediately returns -1 | 
 | and sets errno to @code{EAGAIN}. | 
 | @end deftypefun | 
 |  | 
 | @comment semaphore.h | 
 | @comment POSIX | 
 | @deftypefun int sem_post (sem_t * @var{sem}) | 
 | @code{sem_post} atomically increases the count of the semaphore pointed to | 
 | by @var{sem}. This function never blocks. | 
 |  | 
 | @c !!! This para appears not to agree with the code. | 
 | On processors supporting atomic compare-and-swap (Intel 486, Pentium and | 
 | later, Alpha, PowerPC, MIPS II, Motorola 68k, Ultrasparc), the | 
 | @code{sem_post} function is can safely be called from signal handlers. | 
 | This is the only thread synchronization function provided by POSIX | 
 | threads that is async-signal safe.  On the Intel 386 and earlier Sparc | 
 | chips, the current LinuxThreads implementation of @code{sem_post} is not | 
 | async-signal safe, because the hardware does not support the required | 
 | atomic operations. | 
 |  | 
 | @code{sem_post} always succeeds and returns 0, unless the semaphore | 
 | count would exceed @code{SEM_VALUE_MAX} after being incremented.  In | 
 | that case @code{sem_post} returns -1 and sets @var{errno} to | 
 | @code{EINVAL}.  The semaphore count is left unchanged. | 
 | @end deftypefun | 
 |  | 
 | @comment semaphore.h | 
 | @comment POSIX | 
 | @deftypefun int sem_getvalue (sem_t * @var{sem}, int * @var{sval}) | 
 | @code{sem_getvalue} stores in the location pointed to by @var{sval} the | 
 | current count of the semaphore @var{sem}.  It always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @node Thread-Specific Data | 
 | @section Thread-Specific Data | 
 |  | 
 | Programs often need global or static variables that have different | 
 | values in different threads. Since threads share one memory space, this | 
 | cannot be achieved with regular variables. Thread-specific data is the | 
 | POSIX threads answer to this need. | 
 |  | 
 | Each thread possesses a private memory block, the thread-specific data | 
 | area, or TSD area for short. This area is indexed by TSD keys. The TSD | 
 | area associates values of type @code{void *} to TSD keys. TSD keys are | 
 | common to all threads, but the value associated with a given TSD key can | 
 | be different in each thread. | 
 |  | 
 | For concreteness, the TSD areas can be viewed as arrays of @code{void *} | 
 | pointers, TSD keys as integer indices into these arrays, and the value | 
 | of a TSD key as the value of the corresponding array element in the | 
 | calling thread. | 
 |  | 
 | When a thread is created, its TSD area initially associates @code{NULL} | 
 | with all keys. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_key_create (pthread_key_t *@var{key}, void (*destr_function) (void *)) | 
 | @code{pthread_key_create} allocates a new TSD key. The key is stored in | 
 | the location pointed to by @var{key}. There is a limit of | 
 | @code{PTHREAD_KEYS_MAX} on the number of keys allocated at a given | 
 | time. The value initially associated with the returned key is | 
 | @code{NULL} in all currently executing threads. | 
 |  | 
 | The @var{destr_function} argument, if not @code{NULL}, specifies a | 
 | destructor function associated with the key. When a thread terminates | 
 | via @code{pthread_exit} or by cancellation, @var{destr_function} is | 
 | called on the value associated with the key in that thread. The | 
 | @var{destr_function} is not called if a key is deleted with | 
 | @code{pthread_key_delete} or a value is changed with | 
 | @code{pthread_setspecific}.  The order in which destructor functions are | 
 | called at thread termination time is unspecified. | 
 |  | 
 | Before the destructor function is called, the @code{NULL} value is | 
 | associated with the key in the current thread.  A destructor function | 
 | might, however, re-associate non-@code{NULL} values to that key or some | 
 | other key.  To deal with this, if after all the destructors have been | 
 | called for all non-@code{NULL} values, there are still some | 
 | non-@code{NULL} values with associated destructors, then the process is | 
 | repeated.  The LinuxThreads implementation stops the process after | 
 | @code{PTHREAD_DESTRUCTOR_ITERATIONS} iterations, even if some | 
 | non-@code{NULL} values with associated descriptors remain.  Other | 
 | implementations may loop indefinitely. | 
 |  | 
 | @code{pthread_key_create} returns 0 unless @code{PTHREAD_KEYS_MAX} keys | 
 | have already been allocated, in which case it fails and returns | 
 | @code{EAGAIN}. | 
 | @end deftypefun | 
 |  | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_key_delete (pthread_key_t @var{key}) | 
 | @code{pthread_key_delete} deallocates a TSD key. It does not check | 
 | whether non-@code{NULL} values are associated with that key in the | 
 | currently executing threads, nor call the destructor function associated | 
 | with the key. | 
 |  | 
 | If there is no such key @var{key}, it returns @code{EINVAL}.  Otherwise | 
 | it returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_setspecific (pthread_key_t @var{key}, const void *@var{pointer}) | 
 | @code{pthread_setspecific} changes the value associated with @var{key} | 
 | in the calling thread, storing the given @var{pointer} instead. | 
 |  | 
 | If there is no such key @var{key}, it returns @code{EINVAL}.  Otherwise | 
 | it returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun {void *} pthread_getspecific (pthread_key_t @var{key}) | 
 | @code{pthread_getspecific} returns the value currently associated with | 
 | @var{key} in the calling thread. | 
 |  | 
 | If there is no such key @var{key}, it returns @code{NULL}. | 
 | @end deftypefun | 
 |  | 
 | The following code fragment allocates a thread-specific array of 100 | 
 | characters, with automatic reclaimation at thread exit: | 
 |  | 
 | @smallexample | 
 | /* Key for the thread-specific buffer */ | 
 | static pthread_key_t buffer_key; | 
 |  | 
 | /* Once-only initialisation of the key */ | 
 | static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT; | 
 |  | 
 | /* Allocate the thread-specific buffer */ | 
 | void buffer_alloc(void) | 
 | @{ | 
 |   pthread_once(&buffer_key_once, buffer_key_alloc); | 
 |   pthread_setspecific(buffer_key, malloc(100)); | 
 | @} | 
 |  | 
 | /* Return the thread-specific buffer */ | 
 | char * get_buffer(void) | 
 | @{ | 
 |   return (char *) pthread_getspecific(buffer_key); | 
 | @} | 
 |  | 
 | /* Allocate the key */ | 
 | static void buffer_key_alloc() | 
 | @{ | 
 |   pthread_key_create(&buffer_key, buffer_destroy); | 
 | @} | 
 |  | 
 | /* Free the thread-specific buffer */ | 
 | static void buffer_destroy(void * buf) | 
 | @{ | 
 |   free(buf); | 
 | @} | 
 | @end smallexample | 
 |  | 
 | @node Threads and Signal Handling | 
 | @section Threads and Signal Handling | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_sigmask (int @var{how}, const sigset_t *@var{newmask}, sigset_t *@var{oldmask}) | 
 | @code{pthread_sigmask} changes the signal mask for the calling thread as | 
 | described by the @var{how} and @var{newmask} arguments. If @var{oldmask} | 
 | is not @code{NULL}, the previous signal mask is stored in the location | 
 | pointed to by @var{oldmask}. | 
 |  | 
 | The meaning of the @var{how} and @var{newmask} arguments is the same as | 
 | for @code{sigprocmask}. If @var{how} is @code{SIG_SETMASK}, the signal | 
 | mask is set to @var{newmask}. If @var{how} is @code{SIG_BLOCK}, the | 
 | signals specified to @var{newmask} are added to the current signal mask. | 
 | If @var{how} is @code{SIG_UNBLOCK}, the signals specified to | 
 | @var{newmask} are removed from the current signal mask. | 
 |  | 
 | Recall that signal masks are set on a per-thread basis, but signal | 
 | actions and signal handlers, as set with @code{sigaction}, are shared | 
 | between all threads. | 
 |  | 
 | The @code{pthread_sigmask} function returns 0 on success, and one of the | 
 | following error codes on error: | 
 | @table @code | 
 | @item EINVAL | 
 | @var{how} is not one of @code{SIG_SETMASK}, @code{SIG_BLOCK}, or @code{SIG_UNBLOCK} | 
 |  | 
 | @item EFAULT | 
 | @var{newmask} or @var{oldmask} point to invalid addresses | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_kill (pthread_t @var{thread}, int @var{signo}) | 
 | @code{pthread_kill} sends signal number @var{signo} to the thread | 
 | @var{thread}.  The signal is delivered and handled as described in | 
 | @ref{Signal Handling}. | 
 |  | 
 | @code{pthread_kill} returns 0 on success, one of the following error codes | 
 | on error: | 
 | @table @code | 
 | @item EINVAL | 
 | @var{signo} is not a valid signal number | 
 |  | 
 | @item ESRCH | 
 | The thread @var{thread} does not exist (e.g. it has already terminated) | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int sigwait (const sigset_t *@var{set}, int *@var{sig}) | 
 | @code{sigwait} suspends the calling thread until one of the signals in | 
 | @var{set} is delivered to the calling thread. It then stores the number | 
 | of the signal received in the location pointed to by @var{sig} and | 
 | returns. The signals in @var{set} must be blocked and not ignored on | 
 | entrance to @code{sigwait}. If the delivered signal has a signal handler | 
 | function attached, that function is @emph{not} called. | 
 |  | 
 | @code{sigwait} is a cancellation point.  It always returns 0. | 
 | @end deftypefun | 
 |  | 
 | For @code{sigwait} to work reliably, the signals being waited for must be | 
 | blocked in all threads, not only in the calling thread, since | 
 | otherwise the POSIX semantics for signal delivery do not guarantee | 
 | that it's the thread doing the @code{sigwait} that will receive the signal. | 
 | The best way to achieve this is block those signals before any threads | 
 | are created, and never unblock them in the program other than by | 
 | calling @code{sigwait}. | 
 |  | 
 | Signal handling in LinuxThreads departs significantly from the POSIX | 
 | standard. According to the standard, ``asynchronous'' (external) signals | 
 | are addressed to the whole process (the collection of all threads), | 
 | which then delivers them to one particular thread. The thread that | 
 | actually receives the signal is any thread that does not currently block | 
 | the signal. | 
 |  | 
 | In LinuxThreads, each thread is actually a kernel process with its own | 
 | PID, so external signals are always directed to one particular thread. | 
 | If, for instance, another thread is blocked in @code{sigwait} on that | 
 | signal, it will not be restarted. | 
 |  | 
 | The LinuxThreads implementation of @code{sigwait} installs dummy signal | 
 | handlers for the signals in @var{set} for the duration of the | 
 | wait. Since signal handlers are shared between all threads, other | 
 | threads must not attach their own signal handlers to these signals, or | 
 | alternatively they should all block these signals (which is recommended | 
 | anyway). | 
 |  | 
 | @node Threads and Fork | 
 | @section Threads and Fork | 
 |  | 
 | It's not intuitively obvious what should happen when a multi-threaded POSIX | 
 | process calls @code{fork}. Not only are the semantics tricky, but you may | 
 | need to write code that does the right thing at fork time even if that code | 
 | doesn't use the @code{fork} function. Moreover, you need to be aware of | 
 | interaction between @code{fork} and some library features like | 
 | @code{pthread_once} and stdio streams. | 
 |  | 
 | When @code{fork} is called by one of the threads of a process, it creates a new | 
 | process which is copy of the  calling process. Effectively, in addition to | 
 | copying certain system objects, the function takes a snapshot of the memory | 
 | areas of the parent process, and creates identical areas in the child. | 
 | To make matters more complicated, with threads it's possible for two or more | 
 | threads to concurrently call fork to create two or more child processes. | 
 |  | 
 | The child process has a copy of the address space of the parent, but it does | 
 | not inherit any of its threads. Execution of the child process is carried out | 
 | by a new thread which returns from @code{fork} function with a return value of | 
 | zero; it is the only thread in the child process.  Because threads are not | 
 | inherited across fork, issues arise. At the time of the call to @code{fork}, | 
 | threads in the parent process other than the one calling @code{fork} may have | 
 | been executing critical regions of code.  As a result, the child process may | 
 | get a copy of objects that are not in a well-defined state.  This potential | 
 | problem affects all components of the program. | 
 |  | 
 | Any program component which will continue being used in a child process must | 
 | correctly handle its state during @code{fork}. For this purpose, the POSIX | 
 | interface provides the special function @code{pthread_atfork} for installing | 
 | pointers to handler functions which are called from within @code{fork}. | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_atfork (void (*@var{prepare})(void), void (*@var{parent})(void), void (*@var{child})(void)) | 
 |  | 
 | @code{pthread_atfork} registers handler functions to be called just | 
 | before and just after a new process is created with @code{fork}. The | 
 | @var{prepare} handler will be called from the parent process, just | 
 | before the new process is created. The @var{parent} handler will be | 
 | called from the parent process, just before @code{fork} returns. The | 
 | @var{child} handler will be called from the child process, just before | 
 | @code{fork} returns. | 
 |  | 
 | @code{pthread_atfork} returns 0 on success and a non-zero error code on | 
 | error. | 
 |  | 
 | One or more of the three handlers @var{prepare}, @var{parent} and | 
 | @var{child} can be given as @code{NULL}, meaning that no handler needs | 
 | to be called at the corresponding point. | 
 |  | 
 | @code{pthread_atfork} can be called several times to install several | 
 | sets of handlers. At @code{fork} time, the @var{prepare} handlers are | 
 | called in LIFO order (last added with @code{pthread_atfork}, first | 
 | called before @code{fork}), while the @var{parent} and @var{child} | 
 | handlers are called in FIFO order (first added, first called). | 
 |  | 
 | If there is insufficient memory available to register the handlers, | 
 | @code{pthread_atfork} fails and returns @code{ENOMEM}.  Otherwise it | 
 | returns 0. | 
 |  | 
 | The functions @code{fork} and @code{pthread_atfork} must not be regarded as | 
 | reentrant from the context of the handlers.  That is to say, if a | 
 | @code{pthread_atfork} handler invoked from within @code{fork} calls | 
 | @code{pthread_atfork} or @code{fork}, the behavior is undefined. | 
 |  | 
 | Registering a triplet of handlers is an atomic operation with respect to fork. | 
 | If new handlers are registered at about the same time as a fork occurs, either | 
 | all three handlers will be called, or none of them will be called. | 
 |  | 
 | The handlers are inherited by the child process, and there is no | 
 | way to remove them, short of using @code{exec} to load a new | 
 | pocess image. | 
 |  | 
 | @end deftypefun | 
 |  | 
 | To understand the purpose of @code{pthread_atfork}, recall that | 
 | @code{fork} duplicates the whole memory space, including mutexes in | 
 | their current locking state, but only the calling thread: other threads | 
 | are not running in the child process.  The mutexes are not usable after | 
 | the @code{fork} and must be initialized with @code{pthread_mutex_init} | 
 | in the child process.  This is a limitation of the current | 
 | implementation and might or might not be present in future versions. | 
 |  | 
 | To avoid this, install handlers with @code{pthread_atfork} as follows: have the | 
 | @var{prepare} handler lock the mutexes (in locking order), and the | 
 | @var{parent} handler unlock the mutexes. The @var{child} handler should reset | 
 | the mutexes using @code{pthread_mutex_init}, as well as any other | 
 | synchronization objects such as condition variables. | 
 |  | 
 | Locking the global mutexes before the fork ensures that all other threads are | 
 | locked out of the critical regions of code protected by those mutexes.  Thus | 
 | when @code{fork} takes a snapshot of the parent's address space, that snapshot | 
 | will copy valid, stable data.  Resetting the synchronization objects in the | 
 | child process will ensure they are properly cleansed of any artifacts from the | 
 | threading subsystem of the parent process. For example, a mutex may inherit | 
 | a wait queue of threads waiting for the lock; this wait queue makes no sense | 
 | in the child process. Initializing the mutex takes care of this. | 
 |  | 
 | @node Streams and Fork | 
 | @section Streams and Fork | 
 |  | 
 | The GNU standard I/O library has an internal mutex which guards the internal | 
 | linked list of all standard C FILE objects. This mutex is properly taken care | 
 | of during @code{fork} so that the child receives an intact copy of the list. | 
 | This allows the @code{fopen} function, and related stream-creating functions, | 
 | to work correctly in the child process, since these functions need to insert | 
 | into the list. | 
 |  | 
 | However, the individual stream locks are not completely taken care of.  Thus | 
 | unless the multithreaded application takes special precautions in its use of | 
 | @code{fork}, the child process might not be able to safely use the streams that | 
 | it inherited from the parent.   In general, for any given open stream in the | 
 | parent that is to be used by the child process, the application must ensure | 
 | that that stream is not in use by another thread when @code{fork} is called. | 
 | Otherwise an inconsistent copy of the stream object be produced. An easy way to | 
 | ensure this is to use @code{flockfile} to lock the stream prior to calling | 
 | @code{fork} and then unlock it with @code{funlockfile} inside the parent | 
 | process, provided that the parent's threads properly honor these locks. | 
 | Nothing special needs to be done in the child process, since the library | 
 | internally resets all stream locks. | 
 |  | 
 | Note that the stream locks are not shared between the parent and child. | 
 | For example, even if you ensure that, say, the stream @code{stdout} is properly | 
 | treated and can be safely used in the child, the stream locks do not provide | 
 | an exclusion mechanism between the parent and child. If both processes write | 
 | to @code{stdout}, strangely interleaved output may result regardless of | 
 | the explicit use of @code{flockfile} or implicit locks. | 
 |  | 
 | Also note that these provisions are a GNU extension; other systems might not | 
 | provide any way for streams to be used in the child of a multithreaded process. | 
 | POSIX requires that such a child process confines itself to calling only | 
 | asynchronous safe functions, which excludes much of the library, including | 
 | standard I/O. | 
 |  | 
 | @node Miscellaneous Thread Functions | 
 | @section Miscellaneous Thread Functions | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun {pthread_t} pthread_self (@var{void}) | 
 | @code{pthread_self} returns the thread identifier for the calling thread. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_equal (pthread_t thread1, pthread_t thread2) | 
 | @code{pthread_equal} determines if two thread identifiers refer to the same | 
 | thread. | 
 |  | 
 | A non-zero value is returned if @var{thread1} and @var{thread2} refer to | 
 | the same thread. Otherwise, 0 is returned. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_detach (pthread_t @var{th}) | 
 | @code{pthread_detach} puts the thread @var{th} in the detached | 
 | state. This guarantees that the memory resources consumed by @var{th} | 
 | will be freed immediately when @var{th} terminates. However, this | 
 | prevents other threads from synchronizing on the termination of @var{th} | 
 | using @code{pthread_join}. | 
 |  | 
 | A thread can be created initially in the detached state, using the | 
 | @code{detachstate} attribute to @code{pthread_create}. In contrast, | 
 | @code{pthread_detach} applies to threads created in the joinable state, | 
 | and which need to be put in the detached state later. | 
 |  | 
 | After @code{pthread_detach} completes, subsequent attempts to perform | 
 | @code{pthread_join} on @var{th} will fail. If another thread is already | 
 | joining the thread @var{th} at the time @code{pthread_detach} is called, | 
 | @code{pthread_detach} does nothing and leaves @var{th} in the joinable | 
 | state. | 
 |  | 
 | On success, 0 is returned. On error, one of the following codes is | 
 | returned: | 
 | @table @code | 
 | @item ESRCH | 
 | No thread could be found corresponding to that specified by @var{th} | 
 | @item EINVAL | 
 | The thread @var{th} is already in the detached state | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment GNU | 
 | @deftypefun void pthread_kill_other_threads_np (@var{void}) | 
 | @code{pthread_kill_other_threads_np} is a non-portable LinuxThreads extension. | 
 | It causes all threads in the program to terminate immediately, except | 
 | the calling thread which proceeds normally. It is intended to be | 
 | called just before a thread calls one of the @code{exec} functions, | 
 | e.g. @code{execve}. | 
 |  | 
 | Termination of the other threads is not performed through | 
 | @code{pthread_cancel} and completely bypasses the cancellation | 
 | mechanism. Hence, the current settings for cancellation state and | 
 | cancellation type are ignored, and the cleanup handlers are not | 
 | executed in the terminated threads. | 
 |  | 
 | According to POSIX 1003.1c, a successful @code{exec*} in one of the | 
 | threads should automatically terminate all other threads in the program. | 
 | This behavior is not yet implemented in LinuxThreads.  Calling | 
 | @code{pthread_kill_other_threads_np} before @code{exec*} achieves much | 
 | of the same behavior, except that if @code{exec*} ultimately fails, then | 
 | all other threads are already killed. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_once (pthread_once_t *once_@var{control}, void (*@var{init_routine}) (void)) | 
 |  | 
 | The purpose of @code{pthread_once} is to ensure that a piece of | 
 | initialization code is executed at most once. The @var{once_control} | 
 | argument points to a static or extern variable statically initialized | 
 | to @code{PTHREAD_ONCE_INIT}. | 
 |  | 
 | The first time @code{pthread_once} is called with a given | 
 | @var{once_control} argument, it calls @var{init_routine} with no | 
 | argument and changes the value of the @var{once_control} variable to | 
 | record that initialization has been performed. Subsequent calls to | 
 | @code{pthread_once} with the same @code{once_control} argument do | 
 | nothing. | 
 |  | 
 | If a thread is cancelled while executing @var{init_routine} | 
 | the state of the @var{once_control} variable is reset so that | 
 | a future call to @code{pthread_once} will call the routine again. | 
 |  | 
 | If the process forks while one or more threads are executing | 
 | @code{pthread_once} initialization routines, the states of their respective | 
 | @var{once_control} variables will appear to be reset in the child process so | 
 | that if the child calls @code{pthread_once}, the routines will be executed. | 
 |  | 
 | @code{pthread_once} always returns 0. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_setschedparam (pthread_t target_@var{thread}, int @var{policy}, const struct sched_param *@var{param}) | 
 |  | 
 | @code{pthread_setschedparam} sets the scheduling parameters for the | 
 | thread @var{target_thread} as indicated by @var{policy} and | 
 | @var{param}. @var{policy} can be either @code{SCHED_OTHER} (regular, | 
 | non-realtime scheduling), @code{SCHED_RR} (realtime, round-robin) or | 
 | @code{SCHED_FIFO} (realtime, first-in first-out). @var{param} specifies | 
 | the scheduling priority for the two realtime policies.  See | 
 | @code{sched_setpolicy} for more information on scheduling policies. | 
 |  | 
 | The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO} | 
 | are available only to processes with superuser privileges. | 
 |  | 
 | On success, @code{pthread_setschedparam} returns 0.  On error it returns | 
 | one of the following codes: | 
 | @table @code | 
 | @item EINVAL | 
 | @var{policy} is not one of @code{SCHED_OTHER}, @code{SCHED_RR}, | 
 | @code{SCHED_FIFO}, or the priority value specified by @var{param} is not | 
 | valid for the specified policy | 
 |  | 
 | @item EPERM | 
 | Realtime scheduling was requested but the calling process does not have | 
 | sufficient privileges. | 
 |  | 
 | @item ESRCH | 
 | The @var{target_thread} is invalid or has already terminated | 
 |  | 
 | @item EFAULT | 
 | @var{param} points outside the process memory space | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_getschedparam (pthread_t target_@var{thread}, int *@var{policy}, struct sched_param *@var{param}) | 
 |  | 
 | @code{pthread_getschedparam} retrieves the scheduling policy and | 
 | scheduling parameters for the thread @var{target_thread} and stores them | 
 | in the locations pointed to by @var{policy} and @var{param}, | 
 | respectively. | 
 |  | 
 | @code{pthread_getschedparam} returns 0 on success, or one of the | 
 | following error codes on failure: | 
 | @table @code | 
 | @item ESRCH | 
 | The @var{target_thread} is invalid or has already terminated. | 
 |  | 
 | @item EFAULT | 
 | @var{policy} or @var{param} point outside the process memory space. | 
 |  | 
 | @end table | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_setconcurrency (int @var{level}) | 
 | @code{pthread_setconcurrency} is unused in LinuxThreads due to the lack | 
 | of a mapping of user threads to kernel threads.  It exists for source | 
 | compatibility.  It does store the value @var{level} so that it can be | 
 | returned by a subsequent call to @code{pthread_getconcurrency}.  It takes | 
 | no other action however. | 
 | @end deftypefun | 
 |  | 
 | @comment pthread.h | 
 | @comment POSIX | 
 | @deftypefun int pthread_getconcurrency () | 
 | @code{pthread_getconcurrency} is unused in LinuxThreads due to the lack | 
 | of a mapping of user threads to kernel threads.  It exists for source | 
 | compatibility.  However, it will return the value that was set by the | 
 | last call to @code{pthread_setconcurrency}. | 
 | @end deftypefun |