pthread_cond_wait(3T) DG/UX 5.4R3.00 pthread_cond_wait(3T)
NAME
pthreadcondwait, pthreadcondtimedwait - wait for a condition
SYNOPSIS
#include <pthread.h>
int pthreadcondwait(pthreadcondt *cond, pthreadmutext *mutex);
int pthreadcondtimedwait(pthreadcondt *cond,
pthreadmutext *mutex,
const struct timespec *abstime);
where:
cond A pointer to a condition variable
mutex A pointer to a mutex
abstime A pointer to an absolute time point in the future
DESCRIPTION
The pthreadcondwait() and pthreadcondtimedwait() functions block
on the condition variable pointed to by cond. These functions
atomically release the mutex and cause the calling thread to block on
the specified condition variable. Upon return, the mutex is
implicitly reacquired by the calling thread.
The pthreadcondtimedwait() function is the same as
pthreadcondwait(), except that it returns with an EAGAIN error (and
reacquires the mutex) if the absolute time point specified by abstime
passes before the calling thread is unblocked normally by
pthreadcondsignal() or pthreadcondbroadcast(). The absolute time
is typically calculated by first calling clockgettime() to get the
current time, then adding a specific amount of wait time to produce
the desired time point into the future. Absolute times in the past
cause a timeout to occur as soon as possible, which depends on
aspects of the underlying timer hardware. In any case, a thread that
returns with EAGAIN does not consume an unblock from another thread's
simultaneous call to pthreadcondsignal() or
pthreadcondbroadcast().
When using condition variables, there is always a boolean predicate
involving shared variables associated with each condition wait that
is true if the thread should proceed. This predicate is typically
protected by the mutex associated with the condition variable.
Because the return from pthreadcondwait() or
pthreadcondtimedwait() does not imply anything about the value of
this predicate or can occur spuriously, the predicate must exist for
all callers of these functions and must be re-evaluated in a loop
upon such return.
A side effect of being canceled or acting upon a signal request while
in a condition variable wait is that the mutex is implicitly re-
acquired before invoking cancellation handlers or the signal handler.
In addition, no condition signals directed at the condition variable
shall be consumed by the canceled or signaled thread if there are
other threads blocked on the condition variable. In DG/UX (and most
Licensed material--property of copyright holder(s) 1
pthread_cond_wait(3T) DG/UX 5.4R3.00 pthread_cond_wait(3T)
implementations), if the thread executes a signal handler and returns
normally from the handler, it will be awakened spuriously from its
call to one of the above functions. These functions, unlike other
interrupted system calls, never fail with EINTR. They just return
normally, even if the associated predicate has not been satisifed.
These functions must be called with mutex pointing to a mutex that is
locked by the calling thread, or undefined behavior will result.
Furthermore, the effect of using more than one mutex for concurrent
pthreadcondwait() or pthreadcondtimedwait() operations on the
same condition variable is undefined, that is, a condition variable
becomes bound to a unique mutex when a thread waits on the condition
variable, and this (dynamic) binding ends when the wait returns. Of
course, the same mutex can be used to guard multiple condition
variables.
DIAGNOSTICS
Returns
If successful, these functions return 0. Otherwise they return -1
and set errno to indicate the error.
Errors
For each of the following conditions, pthreadcondwait() and
pthreadcondtimedwait() return -1 and set errno to the corresponding
value:
[EINVAL] The value specified by cond or mutex is invalid. This
occurs when DG/UX has detected that these arguments do not
point to a properly initialized condition variable or
mutex, respectively.
[EINVAL] The mutex was not owned by the current thread at the time
of the call.
For each of the following conditions, pthreadcondtimedwait()
returns -1 and sets errno to the corresponding value:
[EINVAL] The value specified abstime is invalid. Under DG/UX, there
are currently no invalid values for this absolute time.
[EAGAIN] The absolute time point specified by abstime has passed.
SEE ALSO
pthreadcondsignal(3T), pthreadcondbroadcast(3T),
pthreadmutexlock(3T), dgpthreadsleep(3T), dgpthreadsleep(3T),
clockgettime(2).
NOTES
Condition Wait Semantics
It is important to note that when pthreadcondwait() and
pthreadcondtimedwait() return successfully, the associated
predicate may still be false. Similarly, when
pthreadcondtimedwait() returns with the timeout error, the
associated predicate may be true due to an unavoidable race between
Licensed material--property of copyright holder(s) 2
pthread_cond_wait(3T) DG/UX 5.4R3.00 pthread_cond_wait(3T)
the expiration of the timeout and the predicate state change.
In general, whenever a condition wait returns, the thread must re-
evaluate the predicate associated with the condition wait to
determine whether it can safely proceed, should wait again, or should
declare a timeout. A return from the wait does not imply that the
associated predicate is either true or false. It is thus recommended
that a condition wait be enclosed in a "while loop" that checks the
predicate.
Timed Condition Wait
An absolute time measure was chosen by the standards committee for
two reasons. First, a relative time measure can be easily
implemented on top of an interface which specifies absolute time, but
there is a race condition associated with specifying an absolute
timeout on top of an interface that specifies relative timeouts. For
example, assume that clockgettime() returns the current time and
pthreadcondrelativetimedwait() uses relative timeouts:
clockgettime(CLOCKREALTIME, &now)
reltime = sleeptilthisabsolutetime - now;
condrelativetimedwait(c, m, &reltime);
If the thread is preempted between the first statement and the last
statement, the thread will block for too long. Blocking, however, is
irrelevant if an absolute timeout is used. An absolute timeout also
need not be recomputed if it is used multiple times in a loop.
Moreover, an absolute time allows a thread, if it so wishes, to
timeout at specific intervals; a relative time would skew such
intervals.
An example of typical use follows:
struct timespec ts;
(void) pthreadmutexlock(&mutex);
clockgettime(CLOCKREALTIME, &ts)
ts.tvsec += 5;
rc = 0;
while (! [predicate satisifed] && rc == 0 )
rc = pthreadcondtimedwait(&cond, &mutex, &ts);
if (rc == 0) [...]
pthreadmutexunlock(&mutex);
By making the timeout parameter absolute it does not need to be
recomputed each time the program checks its blocking predicate. If
the timeout were relative it would have to be recomputed before each
call.
Signals and Condition Wait
A side effect of acting on an signal request while a thread is
blocked on a condition variable is to reacquire the mutex before
Licensed material--property of copyright holder(s) 3
pthread_cond_wait(3T) DG/UX 5.4R3.00 pthread_cond_wait(3T)
calling any of the signal handlers. This is done to let signal
handlers change the state protected by the mutex and to ensure that
the signal handler is executed in the same state as the critical code
before and after the call to the condition wait function.
When acting on an signal request while a thread is blocked on a
condition variable, the system is required to ensure that the thread
does not consume any condition signals directed at that condition
variable if there are any other threads waiting on that condition
variable. This is done in order to avoid deadlock conditions that
could otherwise occur if a thread were to consume the signal but not
respond to the event that the signal is indicating, while there are
other threads waiting to respond to that event.
Scheduling Behavior of Mutexes and Condition Variables
Synchronization primitives that attempt to interfere with scheduling
policy by specifying an ordering rule are considered undesirable.
Threads waiting on mutexes and condition variables are selected to
proceed in an order dependent upon the scheduling policy rather than
in some fixed order, for example, FIFO. Thus the scheduling policy
determines which thread(s) will be awakened and allowed to proceed.
Licensed material--property of copyright holder(s) 4