gcc/libstdc++-v3/include/std
Jonathan Wakely 93fc477468 libstdc++: Optimise std::future::wait_for and fix futex polling
To poll a std::future to see if it's ready you have to call one of the
timed waiting functions. The most obvious way is wait_for(0s) but this
was previously very inefficient because it would turn the relative
timeout to an absolute one by calling system_clock::now(). When the
relative timeout is zero (or less) we're obviously going to get a time
that has already passed, but the overhead of obtaining the current time
can be dozens of microseconds. The alternative is to call wait_until
with an absolute timeout that is in the past. If you know the clock's
epoch is in the past you can use a default constructed time_point.
Alternatively, using some_clock::time_point::min() gives the earliest
time point supported by the clock, which should be safe to assume is in
the past. However, using a futex wait with an absolute timeout before
the UNIX epoch fails and sets errno=EINVAL. The new code using futex
waits with absolute timeouts was not checking for this case, which could
result in hangs (or killing the process if the libray is built with
assertions enabled).

This patch checks for times before the epoch before attempting to wait
on a futex with an absolute timeout, which fixes the hangs or crashes.
It also makes it very fast to poll using an absolute timeout before the
epoch (because we skip the futex syscall).

It also makes future::wait_for avoid waiting at all when the relative
timeout is zero or less, to avoid the unnecessary overhead of getting
the current time. This makes polling with wait_for(0s) take only a few
cycles instead of dozens of milliseconds.

libstdc++-v3/ChangeLog:

	* include/std/future (future::wait_for): Do not wait for
	durations less than or equal to zero.
	* src/c++11/futex.cc (_M_futex_wait_until)
	(_M_futex_wait_until_steady): Do not wait for timeouts before
	the epoch.
	* testsuite/30_threads/future/members/poll.cc: New test.
2020-11-12 23:47:04 +00:00
..
algorithm
any
array libstdc++: Remove <debug/array> 2020-11-09 21:20:01 +01:00
atomic
bit libstdc++: Remove redundant check for zero in std::__popcount 2020-11-09 14:54:29 +00:00
bitset
charconv
chrono
codecvt
complex
concepts
condition_variable
coroutine
deque
execution
filesystem
forward_list
fstream
functional libstdc++: Remove <debug/array> 2020-11-09 21:20:01 +01:00
future libstdc++: Optimise std::future::wait_for and fix futex polling 2020-11-12 23:47:04 +00:00
iomanip
ios
iosfwd
iostream
istream
iterator
limits
list
locale
map
memory
memory_resource
mutex libstdc++: Rewrite std::call_once to use futexes [PR 66146] 2020-11-03 18:44:49 +00:00
numbers
numeric
optional libstdc++: Fix constraints on std::optional comparisons [PR 96269] 2020-11-05 19:09:22 +00:00
ostream libstdc++: Implement std::emit_on_flush etc. 2020-11-11 00:19:40 +00:00
queue
random
ranges libstdc++: Don't initialize from *this inside some views [PR97600] 2020-10-30 20:33:19 -04:00
ratio
regex
scoped_allocator
set
shared_mutex
span libstdc++: Remove <debug/array> 2020-11-09 21:20:01 +01:00
sstream libstdc++: Reorder constructors in <sstream> 2020-11-10 19:22:48 +00:00
stack
stdexcept
stop_token libstdc++: Use helper type for checking thread ID 2020-11-11 11:13:31 +00:00
streambuf
string
string_view
syncstream libstdc++: Implement std::emit_on_flush etc. 2020-11-11 00:19:40 +00:00
system_error
thread libstdc++: Assigning to a joinable std::jthread calls std::terminate 2020-11-11 11:13:31 +00:00
tuple
type_traits libstdc++: Define type traits for wchar_t even when libc support missing 2020-11-01 11:39:07 +00:00
typeindex
unordered_map
unordered_set
utility
valarray
variant libstdc++: Fix some warnings in headers 2020-10-29 22:47:22 +00:00
vector
version libstdc++: Add c++2a <syncstream> 2020-11-02 10:41:32 -08:00