|Anonymous | Login||2020-03-30 00:57 UTC|
|Main | My View | View Issues | Change Log | Docs|
|Viewing Issue Simple Details|
|ID||Category||Severity||Type||Date Submitted||Last Update|
|0001164||[1003.1(2016)/Issue7+TC2] System Interfaces||Comment||Enhancement Request||2017-09-30 15:48||2019-01-28 16:48|
|Final Accepted Text|
|Summary||0001164: Correct C++11 std::condition_variable requires a version of pthread_cond_timedwait that supports specifying the clock|
C++11's std::condition_variable specifies the clock to be waited upon at
the time of the wait explicitly via the wait_until or implicitly via the
wait_for method. There is no standard way to specify the clock during
pthread_cond_timedwait uses the clock (optionally) specified via
the pthread_cond_attr_t parameter to pthread_cond_init.
This means that current implementations in libstdc++ and libc++ of
std::condition_variable::wait_for and std::condition_variable::wait_until
create their underlying pthread_cond_t to use CLOCK_REALTIME, and then
convert other clocks to CLOCK_REALTIME before calling
pthread_cond_timedwait. Such waits are prone to racing against the system
clock being set asynchronously, potentially resulting in a much shorter or
I believe that this issue was raised during the standardisation of C++11 as
"DR887". It appears that at that time those involved believed that it
was possible to implement the feature on top of POSIX threads. In
particular, it is possible to avoid a much-shorter wait by rechecking the
timeout after pthread_cond_timedwait returns. But, it is my understanding,
that there was no solution provided for the wait potentially being much
longer if the system clock is reset back to the past.
A great many C libraries have moved from using CLOCK_REALTIME (usually via
time(2) or gettimeofday(2)) to CLOCK_MONOTONIC (via clock_gettime(2)) in
order to ensure that timeouts do not unexpectedly change when the system
clock changes. They can do so, even when using condition variables, by
specifying CLOCK_MONOTONIC when creating them.
Unfortunately, C++ libraries that try to do the right thing by using
std::chrono::steady_clock absolute timeouts or relative timeouts, are
inadvertently using timeouts based on CLOCK_REALTIME. They cannot portably
do the right thing without resorting to using pthread calls directly.
As a developer of embedded-Linux-based systems that may have their systems
clocks changed, using CLOCK_MONOTONIC rather than CLOCK_REALTIME for
condition variable timeouts is important to me. We have our own condition
variable implementation that uses pthread_condattr_setclock to always use
CLOCK_MONOTONIC and then converts other clocks to that clock. This solution
works, but we'd much rather be using the standard std::condition_variable
implementation. It also means that any third-party C++ libraries we use
must be modified to use our implementation.
I have submitted patches to libstdc++ and glibc to support a new
pthread_cond_timedwaitonclock_np function which accepts a clockid_t to
indicate which clock should be used for the wait. It supports either
CLOCK_REALTIME or CLOCK_MONOTONIC. These patches were received somewhat
warmly, but it was suggested that I raise the issue here.
I see three alternative ways to correctly support std::condition_variable
waits on std::chrono::steady_clock:
1. The addition of a function like pthread_cond_timedwaitonclock_np as
described above. (Though of course, if approved here it would not be
2. Making std::condition_variable create the underlying pthread_cond_t to
use CLOCK_MONOTONIC. As described above, this means that code genuinely
wanting to wait on CLOCK_REALTIME cannot do so. (I could believe that
there is more code that cares about their waits being immune to system
clock changes than cares about waits honouring system clock changes
3. Implement std::condition_variable on top of non-standard underlying
operating system factilities such as futex(2). This is the route that
std::future has taken in libstdc++, but it still falls back to using
std::condition_variable if futex is not available.
I believe that a similar issue affects std::timed_mutex, but there is
currently no standard way to tell pthread_mutex_timedlock to use a
different clock so method 2 above does not apply. The addition of a
pthread_mutex_timedlockonclock-like function would help there too.
 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861 [^]
 https://sourceware.org/ml/libc-alpha/2015-07/msg00193.html [^]
|Desired Action||The addition of pthread_cond_timedwait and pthread_mutex_timedlock variants that accepts clock parameters.|
|Tags||No tags attached.|
This issue has been discussed on the mailing list in the thread beginning at email@example.com/msg02813.html">https://firstname.lastname@example.org/msg02813.html [email@example.com/msg02813.html" target="_blank">^] .
This resulted in the scope being widened, so I entered issue 1216 to cover that.
http://austingroupbugs.net/view.php?id=1216 [^] .
|This is being closed as withdrawn, as it is effectively superseded by bug 0001216.|
|2017-09-30 15:48||mikecrowe||New Issue|
|2017-09-30 15:48||mikecrowe||Name||=> Mike Crowe|
|2017-09-30 15:48||mikecrowe||Section||=> pthread_cond_timedwait|
|2017-09-30 15:48||mikecrowe||Page Number||=> 0|
|2017-09-30 15:48||mikecrowe||Line Number||=> 0|
|2018-07-22 18:24||mikecrowe||Issue Monitored: mikecrowe|
|2018-11-26 18:55||mikecrowe||Note Added: 0004170|
|2018-11-27 09:23||geoffclare||Relationship added||related to 0001216|
|2019-01-28 16:48||geoffclare||Interp Status||=> ---|
|2019-01-28 16:48||geoffclare||Note Added: 0004232|
|2019-01-28 16:48||geoffclare||Status||New => Closed|
|2019-01-28 16:48||geoffclare||Resolution||Open => Withdrawn|
|Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group|