[committed] libstdc++: Optimise std::future::wait_for and fix futex polling

Jonathan Wakely jwakely@redhat.com
Sat Nov 14 00:17:22 GMT 2020


On 13/11/20 22:45 +0000, Jonathan Wakely wrote:
>On 13/11/20 21:12 +0000, Jonathan Wakely wrote:
>>On 13/11/20 20:29 +0000, Mike Crowe via Libstdc++ wrote:
>>>On Friday 13 November 2020 at 17:25:22 +0000, Jonathan Wakely wrote:
>>>>+  // Return the relative duration from (now_s + now_ns) to (abs_s + abs_ns)
>>>>+  // as a timespec.
>>>>+  struct timespec
>>>>+  relative_timespec(chrono::seconds abs_s, chrono::nanoseconds abs_ns,
>>>>+		    time_t now_s, long now_ns)
>>>>+  {
>>>>+    struct timespec rt;
>>>>+
>>>>+    // Did we already time out?
>>>>+    if (now_s > abs_s.count())
>>>>+      {
>>>>+	rt.tv_sec = -1;
>>>>+	return rt;
>>>>+      }
>>>>+
>>>>+    auto rel_s = abs_s.count() - now_s;
>>>>+
>>>>+    // Avoid overflows
>>>>+    if (rel_s > __gnu_cxx::__int_traits<time_t>::__max)
>>>>+      rel_s = __gnu_cxx::__int_traits<time_t>::__max;
>>>>+    else if (rel_s < __gnu_cxx::__int_traits<time_t>::__min)
>>>>+      rel_s = __gnu_cxx::__int_traits<time_t>::__min;
>>>
>>>I may be missing something, but if the line above executes...
>>>
>>>>+
>>>>+    // Convert the absolute timeout value to a relative timeout
>>>>+    rt.tv_sec = rel_s;
>>>>+    rt.tv_nsec = abs_ns.count() - now_ns;
>>>>+    if (rt.tv_nsec < 0)
>>>>+      {
>>>>+	rt.tv_nsec += 1000000000;
>>>>+	--rt.tv_sec;
>>>
>>>...and so does this line above, then I think that we'll end up
>>>underflowing. (Presumably rt.tv_sec will wrap round to being some time in
>>>2038 on most 32-bit targets.)
>>
>>Ugh.
>>
>>>I'm currently trying to persuade myself that this can actually happen and
>>>if so work out how to come up with a test case for it.
>>
>>Maybe something like:
>>
>>auto d = chrono::floor<chrono::seconds>(system_clock::now().time_since_epoch() - seconds(INT_MAX + 2LL));
>>fut.wait_until(system_clock::time_point(d));
>>
>>This will create a sys_time with a value that is slightly more than
>>INT_MAX seconds before the current time, with a zero nanoseconds
>
>Ah, but such a time will never reach the overflow because the first
>thing that the new relative_timespec function does is:
>
>     if (now_s > abs_s.count())
>       {
>         rt.tv_sec = -1;
>         return rt;
>       }
>
>So in fact we can never have a negative rel_s anyway.

Here's what I've pushed now, after testing on x86_64-linux.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 1918 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20201114/96ec1ce3/attachment.bin>


More information about the Libstdc++ mailing list