mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-30 10:45:40 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			1429 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1429 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| @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
 | |
|                                   cancelled.
 | |
| * 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.
 | |
| * 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 cancelled.
 | |
| 
 | |
| 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 cancelled.
 | |
| 
 | |
| 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_setinheritsched
 | |
| @findex pthread_attr_setschedparam
 | |
| @findex pthread_attr_setschedpolicy
 | |
| @findex pthread_attr_setscope
 | |
| @comment pthread.h
 | |
| @comment POSIX
 | |
| @deftypefun int pthread_attr_set@var{attr} (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_getinheritsched
 | |
| @findex pthread_attr_getschedparam
 | |
| @findex pthread_attr_getschedpolicy
 | |
| @findex pthread_attr_getscope
 | |
| @comment pthread.h
 | |
| @comment POSIX
 | |
| @deftypefun int pthread_attr_get@var{attr} (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}.
 | |
| @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 cancelled 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 cancelled 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_defer_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 kind}, which is either ``fast'', ``recursive'', or
 | |
| ``error checking''. The kind of a mutex determines whether
 | |
| it can be locked again by a thread that already owns it.
 | |
| The default kind is ``fast''.
 | |
| 
 | |
| Variables of type @code{pthread_mutex_t} can also be initialized
 | |
| statically, using the constants @code{PTHREAD_MUTEX_INITIALIZER} (for
 | |
| fast mutexes), @code{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} (for
 | |
| recursive 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 kind of the mutex. If the mutex
 | |
| is of the ``fast'' kind, 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'' kind, @code{pthread_mutex_lock}
 | |
| returns immediately with the error code @code{EDEADLK}.  If the mutex is
 | |
| of the ``recursive'' kind, @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.
 | |
| @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_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'' kind,
 | |
| @code{pthread_mutex_unlock} always returns it to the unlocked state. If
 | |
| it is of the ``recursive'' kind, 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 kind, which is
 | |
| either @code{PTHREAD_MUTEX_FAST_NP} for ``fast'' mutexes,
 | |
| @code{PTHREAD_MUTEX_RECURSIVE_NP} for ``recursive'' 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 kind 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'' kind, @code{pthread_mutex_lock} simply suspends the calling
 | |
| thread forever.  If the mutex is of the ``error checking'' kind,
 | |
| @code{pthread_mutex_lock} returns immediately with the error code
 | |
| @code{EDEADLK}.  If the mutex is of the ``recursive'' kind, 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 kind is ``fast'', that is, @code{PTHREAD_MUTEX_FAST_NP}.
 | |
| 
 | |
| @comment pthread.h
 | |
| @comment GNU
 | |
| @deftypefun int pthread_mutexattr_setkind_np (pthread_mutexattr_t *@var{attr}, int @var{kind})
 | |
| @code{pthread_mutexattr_setkind_np} sets the mutex kind attribute in
 | |
| @var{attr} to the value specified by @var{kind}.
 | |
| 
 | |
| If @var{kind} is not @code{PTHREAD_MUTEX_FAST_NP},
 | |
| @code{PTHREAD_MUTEX_RECURSIVE_NP}, or
 | |
| @code{PTHREAD_MUTEX_ERRORCHECK_NP}, this function will return
 | |
| @code{EINVAL} and leave @var{attr} unchanged.
 | |
| @end deftypefun
 | |
| 
 | |
| @comment pthread.h
 | |
| @comment GNU
 | |
| @deftypefun int pthread_mutexattr_getkind_np (const pthread_mutexattr_t *@var{attr}, int *@var{kind})
 | |
| @code{pthread_mutexattr_getkind_np} retrieves the current value of the
 | |
| mutex kind attribute in @var{attr} and stores it in the location pointed
 | |
| to by @var{kind}.
 | |
| 
 | |
| 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 cancelled 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 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 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.
 | |
| @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. Thus, if a mutex is locked by a
 | |
| thread other than the thread calling @code{fork}, that mutex will remain
 | |
| locked forever in the child process, possibly blocking the execution of
 | |
| the child process. To avoid this, install handlers with
 | |
| @code{pthread_atfork} as follows: the @var{prepare} handler locks the
 | |
| global mutexes (in locking order), and the @var{parent} and @var{child}
 | |
| handlers unlock them (in reverse order). Alternatively, @var{prepare}
 | |
| and @var{parent} can be set to @code{NULL} and @var{child} to a function
 | |
| that calls @code{pthread_mutex_init} on the global mutexes.
 | |
| 
 | |
| @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.
 | |
| 
 | |
| @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
 |