PTHREAD_COND_WAIT(3C) Standard C Library Functions PTHREAD_COND_WAIT(3C)

pthread_cond_wait, pthread_cond_clockwait, pthread_cond_timedwait, pthread_cond_relclockwait_np, pthread_cond_reltimedwait_npwait on a condition

Standard C Library (libc, -lc)

int
pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

int
pthread_cond_clockwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, clockid_t clock, const struct timespec *restrict abstime);

int
pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);

int
pthread_cond_relclockwait_np(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, clockid_t clock, const struct timespec *restrict reltime);

int
pthread_cond_reltimedwait_np(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict reltime);

The (), pthread_cond_clockwait(), pthread_cond_timedwait(), pthread_cond_relclockwait_np(), and pthread_cond_reltimedwait_np() functions are used to block on a condition variable. They must be called with mutex locked by the calling thread or undefined behavior will result.

These functions atomically release mutex and cause the calling thread to block on the condition variable cond. Atomically here means atomically with respect to access by another thread to the mutex and then the condition variable. That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call to pthread_cond_signal(3C) or pthread_cond_broadcast(3C) in that thread behaves as if it were issued after the about-to-block thread has blocked.

Upon successful return, the mutex has been locked and is owned by the calling thread. If mutex is a robust mutex where an owner terminated while holding the lock and the state is recoverable, the mutex is acquired even though the function returns an error value.

When using condition variables there is always a boolean predicate, an invariant, associated with each condition wait that must be true before the thread should proceed. Spurious wakeups from the (), pthread_cond_clockwait(), pthread_cond_timedwait(), pthread_cond_relclockwait_np(), or pthread_cond_reltimedwait_np() functions could occur. The return from these functions does not imply anything about the value of this predicate and the predicate must always be reevaluated.

The order in which blocked threads are awakened by pthread_cond_signal(3C) or pthread_cond_broadcast(3C) is determined by the scheduling policy. See pthreads(7).

The effect of using more than one mutex for concurrent (), pthread_cond_clockwait(), pthread_cond_timedwait(), pthread_cond_relclockwait_np(), or pthread_cond_reltimedwait_np() operations on the same condition variable will result in undefined behavior.

A condition wait (whether timed or not) is a cancellation point. When the cancelability enable state of a thread is set to PTHREAD_CANCEL_DEFERRED, a side effect of acting upon a cancellation request while in a condition wait is that the mutex is reacquired before calling the first cancellation cleanup handler.

A thread that has been unblocked because it has been canceled while blocked in a call to any of these functions does not consume any condition signal that may be directed concurrently at the condition variable if there are other threads blocked on the condition variable.

The () function will block forever until it is signaled. With the other functions, it is possible to bound the amount of time that the calling thread will block waiting to be signaled. When a timeout occurs, the calling threads will return with the mutex held, but will instead indicate an error occurred.

In general, the system provides the ability to program timeouts against either the realtime clock, CLOCK_REALTIME, which measures the wall clock and is subject to changes due to time synchronization daemons such as NTP and PTP, or the high-resolution clock, CLOCK_HIGHRES, which is a non-adjustable high-resolution clock that is provided by system hardware. The specified timeout may either be specified as an absolute time in the future or as a relative amount of time that should elapse. Each clock has its own resolution, which can be determined by clock_getres(3C). Timeouts may be rounded up to a given clock's resolution.

The () and () functions determine which clock they use to wait based upon the clock that the condition variable was created with. By default, all timed condition variables utilize the realtime clock, CLOCK_REALTIME. The default clock may be changed on a per-condition variable basis by setting the condition variable's attributes with the pthread_condattr_setclock(3C) function when creating the condition variable.

The () and () functions ignore the condition variable's defined clock and instead utilize the clock specified by the clock argument. While there are additional clocks in the system, only CLOCK_REALTIME or CLOCK_HIGHRES may be specified. The thread and process-specific CPU time clocks cannot be used.

The () and pthread_cond_timedwait() functions treat the timeout value, abstime, as the absolute time in the future when the timeout should expire. Conversely, the pthread_cond_relclockwait_np() and () functions operate in terms of a relative time. The timer will expire when a specified amount of time passes on the clock as indicated by reltime.

The (), pthread_cond_clockwait(), pthread_cond_timedwait(), pthread_cond_relclockwait_np(), or pthread_cond_reltimedwait_np() functions split the errors that they return into those that occur before and those that occur after dropping the lock in any form. In particular, error checking is guaranteed to occur before releasing the mutex and waiting on the condition variable. The errors ETIMEDOUT, EOWNERDEAD, and ENOTRECOVERABLE are the only errors that may occur after a wait has begun. The latter two errors only apply to a robust mutex. No matter why the calling functions return, they will always return with the mutex mutex held, excepting certain unrecoverable robust mutexes. In addition, if the calling thread that is waiting on a condition variable takes a signal, the thread will never return EINTR. It may resume blocking or potentially deliver a spurious wakeup.

Upon successful completion, the pthread_cond_wait(), pthread_cond_clockwait(), pthread_cond_timedwait(), pthread_cond_relclockwait_np(), and pthread_cond_reltimedwait_np() functions return 0. Otherwise, an error value is returned to indicate the error.

The pthread_cond_wait(), pthread_cond_clockwait(), pthread_cond_timedwait(), pthread_cond_relclockwait_np(), and pthread_cond_reltimedwait_np() functions will fail if:

The mutex type is PTHREAD_MUTEX_ERRORCHECK or the mutex is a robust mutex, and the current thread does not own the mutex.
The absolute or relative time specified by abstime and reltime respectively, has passed. This does not apply to pthread_cond_wait().
One or more of the values specified by cond, mutex, abstime, or reltime is invalid.

Different mutexes were supplied for concurrent operation on the same condition variable.

The value of clock is either unsupported for timing operations or the value is unknown to the system.

The mutex is a robust mutex initialized with the attribute PTHREAD_MUTEX_ROBUST and the last owner of this mutex died while holding the mutex, leaving the state it was protecting possibly inconsistent. The mutex is now owned by the caller.
The mutex is a robust mutex initialized with the attribute PTHREAD_MUTEX_ROBUST and the mutex was protecting state that has now been left irrecoverable. The mutex has not been acquired.

clock_getres(3C), pthread_cond_broadcast(3C), pthread_cond_signal(3C), pthread_condattr_setclock(3C), pthread_mutex_lock(3C), pthread_mutexattr_getrobust(3C), time.h(3HEAD), attributes(7), condition(7), pthreads(7), standards(7)

June 23, 2024 OmniOS