condition(3T)
NAME
condition, cond_init, cond_destroy, cond_wait, cond_timedwait, cond_signal, cond_broadcast − condition variables
SYNOPSIS
#include <synch.h>
int cond_init(cond_t ∗cvp, int type, int arg);
int cond_destroy(cond_t ∗cvp);
int cond_wait(cond_t ∗cvp, mutex_t ∗mp);
int cond_timedwait(cond_t ∗cvp, mutex_t ∗mp, timestruc_t ∗abstime);
int cond_signal(cond_t ∗cvp);
int cond_broadcast(cond_t ∗cvp);
MT-LEVEL
MT-Safe
DESCRIPTION
A condition variable enables threads to atomically block until a condition is satisfied. The condition is tested under the protection of a mutual exclusion lock (mutex). When the condition is false, a thread typically blocks on a condition variable and atomically releases the mutex waiting for the condition to change. When another thread changes the condition, it may signal the associated condition variable to cause one or more waiting threads to wake up, reacquire the mutex, and re-evaluate the condition.
Condition variables can be used to synchronize threads among processes if they are allocated in memory that is writable and shared by the cooperating processes (see mmap(2)) and have been initialized for this behavior.
Condition variables must be initialized before use. cond_init() initializes the condition variable pointed to by cvp. A condition variable can potentially have several different types of behavior, specified by type. No current type uses arg although a future type may specify additional behavior parameters via arg. type may be one of the following:
USYNC_PROCESS The condition variable can be used to synchronize threads in this process and other processes. Only one process should initialize the condition variable. arg is ignored.
USYNC_THREAD The condition variable can be used to synchronize threads in this process, only. arg is ignored.
Condition variables may also be initialized by allocation in zeroed memory. In this case a type of USYNC_THREAD is assumed. Multiple threads must not initialize the same condition variable simultaneously. A condition variable must not be re-initialized while other threads may be using it.
cond_destroy() destroys any state associated with the condition variable pointed to by cvp. The space for storing the condition variable is not freed.
cond_wait() atomically releases the mutex pointed to by mp and causes the calling thread to block on the condition variable pointed to by cvp. The blocked thread may be awakened by cond_signal(), cond_broadcast(), or when interrupted by delivery of a signal or a fork(). Any change in value of a condition associated with the condition variable cannot be inferred by the return of cond_wait() and any such condition must be re-evaluated.
cond_timedwait() is similar to cond_wait(), except that the calling thread will not block past the time of day specified by abstime. If the time of day becomes greater than abstime then cond_timedwait() returns with the error code ETIME .
cond_wait() and cond_timedwait() always return with the mutex locked and owned by the calling thread even when returning an error.
cond_signal() unblocks one thread that is blocked on the condition variable pointed to by cvp.
cond_broadcast() unblocks all threads that are blocked on the condition variable pointed to by cvp.
If no threads are blocked on the condition variable then cond_signal() and cond_broadcast() have no effect.
Both functions should be called under the protection of the same mutex that is used with the condition variable being signaled. Otherwise the condition variable may be signaled between the test of the associated condition and blocking in cond_wait(). This can cause an infinite wait.
RETURN VALUES
Zero is returned when successful. A non-zero value indicates an error.
ERRORS
If any of the following conditions are detected, these functions fail and return the corresponding value:
EINVAL Invalid argument. For cond_init(), type is not a recognized type. For cond_timedwait(), the specified number of seconds, abstime, is greater than pgm_start_time + 50,000,000, where pgm_start_time is the start time of the application, or the number of nanoseconds is greater than or equal to 1,000,000,000.
EFAULT cvp, arg, or abstime point to an illegal address.
If any of the following conditions are detected, cond_wait() or cond_timedwait() fails and returns the corresponding value:
EINTR The wait was interrupted by a signal or fork().
If any of the following conditions are detected, cond_timedwait() fails and returns the corresponding value:
ETIME The time specified by abstime has passed.
EXAMPLES
cond_wait() is normally used in a loop testing some condition, as follows:
(void) mutex_lock(mp);
while (cond == FALSE) {
(void) cond_wait(cvp, mp);
}
(void) mutex_unlock(mp);
cond_timedwait() is also normally used in a loop testing some condition. It uses an absolute timeout value as follows:
timestruc_t to;
...
(void) mutex_lock(mp);
to.tv_sec = time(NULL) + TIMEOUT;
to.tv_nsec = 0;
while (cond == FALSE) {
err = cond_timedwait(cvp, mp, &to);
if (err == ETIME) {
/∗ timeout, do something ∗/
break;
}
}
(void) mutex_unlock(mp);
This sets a bound on the total wait time even though cond_timedwait() may return several times due to the condition being signaled or the wait being interrupted.
SEE ALSO
mmap(2), fork(2), signal(3C), mutex(3T)
NOTES
These interfaces also available via:
#include <thread.h>
By default, there is no defined order of unblocking if multiple threads are waiting for a condition variable.
SunOS 5.4 — Last change: 30 Mar 1994