Anonymous | Login | 2025-02-11 19:09 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0001164 | [1003.1(2016/18)/Issue7+TC2] System Interfaces | Comment | Enhancement Request | 2017-09-30 15:48 | 2019-01-28 16:48 | ||
Reporter | mikecrowe | View Status | public | ||||
Assigned To | |||||||
Priority | normal | Resolution | Withdrawn | ||||
Status | Closed | ||||||
Name | Mike Crowe | ||||||
Organization | |||||||
User Reference | |||||||
Section | pthread_cond_timedwait | ||||||
Page Number | 0 | ||||||
Line Number | 0 | ||||||
Interp Status | --- | ||||||
Final Accepted Text | |||||||
Summary | 0001164: Correct C++11 std::condition_variable requires a version of pthread_cond_timedwait that supports specifying the clock | ||||||
Description |
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 construction. 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 longer wait. I believe that this issue was raised during the standardisation of C++11 as "DR887"[1]. 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[2] 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 _np.) 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 immediately though.) 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. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861 [^] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4486.html [^] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2999.html [^] [2] https://sourceware.org/ml/libc-alpha/2015-07/msg00193.html [^] https://sourceware.org/ml/libc-alpha/2015-08/msg00186.html [^] https://sourceware.org/ml/libc-alpha/2015-08/msg00230.html [^] https://gcc.gnu.org/ml/libstdc++/2015-07/msg00015.html [^] |
||||||
Desired Action | The addition of pthread_cond_timedwait and pthread_mutex_timedlock variants that accepts clock parameters. | ||||||
Tags | No tags attached. | ||||||
Attached Files | |||||||
|
![]() |
||||||
|
![]() |
|
(0004170) mikecrowe (reporter) 2018-11-26 18:55 |
This issue has been discussed on the mailing list in the thread beginning at https://www.mail-archive.com/austin-group-l@opengroup.org/msg02813.html [^] . This resulted in the scope being widened, so I entered issue 1216 to cover that. http://austingroupbugs.net/view.php?id=1216 [^] . |
(0004232) geoffclare (manager) 2019-01-28 16:48 |
This is being closed as withdrawn, as it is effectively superseded by bug 0001216. |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |