Document Number: N2999=09-0189
Date: 2009-10-23
Project: Programming Language C++

Detlef Vollmann <dv@vollmann.ch>

N2999: Background for issue 887: Clocks and Condition Variables (Rev. 1)

Revision history

This is a revision of N2969, with the following change:

Added proposed wording for conditionally supported and implementation-defined.

Discussion

Timeliness of the return of any waiting functions is a big concern in real-time environments. It's clear that anything that's not non-interruptible can have delays, the return of waiting functions will always be late. That doesn't mean that they can be arbitrarily late, even if an API specification doesn't give any specific upper limit on those delays.

Especially for embedded systems, the environment is often controlled very closely and these delays are measured as latency, and often the whole system is built around this latency. This latency can be some microseconds, some milliseconds or even some seconds, and the system is generally tuned such that some external requirements on the maximum latency are met.

So on a system with a maximum latency of e.g. 500ms, if a wait function returns 450ms later than specified in the wait call, that is ok. But if it returns half a week later, then that's a clear bug of the implementation, especially if the rest of the system continues normally. So being 40µs late or 700ms late is a QOI issue, but being arbitrarly late is simply a wrong implementation.

POSIX provides the function pthread_cond_timedwait to wait on a condition variable with a timeout. This timeout is measured by a predefined clock. This predefined clock can be set before a condition variable is initialized with the function pthread_condattr_setclock, but this function is not generally available on POSIX systems, but is part of the ADVANCED REALTIME option of POSIX. On all other POSIX systems, the timeout of pthread_cond_timedwait is always an absolute time and measured on the standard (non-monotonic) system clock.

So the wait_* in [thread.condition.condvar] as currently specified can not correctly be implemented on top of POSIX condition variables. The only function that can be correctly be implemented is wait_until where Clock == chrono::system_clock.

That doesn't mean that these functions as specified can not be correctly implemented on top of POSIX systems, but only by not using POSIX condition variables, but instead providing an own implementation of condition variables. This is what implementations on Windows have to do anyway, because Windows doesn't have condition variables. But given the history of implementing condition variables on Windows (see http://sources.redhat.com/ml/pthreads-win32/2001/msg00012.html) this borders on "heroic effort" that should not be required. And also most users of C++ condition variables on POSIX systems expect them to be identical to the native condition variables, and that their implementers provide them some mechanism to get a native handle.

Proposed resolution

Make wait_for conditionally supported und the possible clocks of wait_until implementation-defined. Request that system_clock is always supported.

In [thread.condition.condvar], near paragraph 15 and paragraph 23, and [thread.condition.condvarany], near paragraph 13 and paragraph 20, near wait_until at an appropriate place, add:

 

It is implementation-defined which Clocks are supported.

system_clock shall always be in the set of supported clocks.

In [thread.condition.condvar], before paragraph 21, and [thread.condition.condvarany], before paragraph 18, before wait_for, add:

  wait_for is conditionally supported.