gcc/libstdc++-v3/config/abi
Mike Crowe 01d412ef36 libstdc++: Support futex waiting on chrono::steady_clock directly
The user-visible effect of this change is for std::future::wait_until to
use CLOCK_MONOTONIC when passed a timeout of std::chrono::steady_clock
type.  This makes it immune to any changes made to the system clock
CLOCK_REALTIME.

Add an overload of __atomic_futex_unsigned::_M_load_and_text_until_impl
that accepts a std::chrono::steady_clock, and correctly passes this
through to __atomic_futex_unsigned_base::_M_futex_wait_until_steady
which uses CLOCK_MONOTONIC for the timeout within the futex system call.
These functions are mostly just copies of the std::chrono::system_clock
versions with small tweaks.

Prior to this commit, a std::chrono::steady timeout would be converted
via std::chrono::system_clock which risks reducing or increasing the
timeout if someone changes CLOCK_REALTIME whilst the wait is happening.
(The commit immediately prior to this one increases the window of
opportunity for that from a short period during the calculation of a
relative timeout, to the entire duration of the wait.)

FUTEX_WAIT_BITSET was added in kernel v2.6.25.  If futex reports ENOSYS
to indicate that this operation is not supported then the code falls
back to using clock_gettime(2) to calculate a relative time to wait for.

I believe that I've added this functionality in a way that it doesn't
break ABI compatibility, but that has made it more verbose and less type
safe.  I believe that it would be better to maintain the timeout as an
instance of the correct clock type all the way down to a single
_M_futex_wait_until function with an overload for each clock.  The
current scheme of separating out the seconds and nanoseconds early risks
accidentally calling the wait function for the wrong clock.
Unfortunately, doing this would break code that compiled against the old
header.

libstdc++-v3/ChangeLog:

	* config/abi/pre/gnu.ver: Update for addition of
	__atomic_futex_unsigned_base::_M_futex_wait_until_steady.
	* include/bits/atomic_futex.h (__atomic_futex_unsigned_base):
	Add comments to clarify that _M_futex_wait_until and
	_M_load_and_test_until use CLOCK_REALTIME.
	(__atomic_futex_unsigned_base::_M_futex_wait_until_steady)
	(__atomic_futex_unsigned_base::_M_load_and_text_until_steady):
	New member functions that use CLOCK_MONOTONIC.
	(__atomic_futex_unsigned_base::_M_load_and_test_until_impl)
	(__atomic_futex_unsigned_base::_M_load_when_equal_until): Add
	overloads that accept a steady_clock time_point and use the
	new member functions.
	* src/c++11/futex.cc: Include headers required for
	clock_gettime.
	(futex_clock_monotonic_flag): New constant to tell futex to
	use CLOCK_MONOTONIC to match existing futex_clock_realtime_flag.
	(futex_clock_monotonic_unavailable): New global to store the
	result of trying to use CLOCK_MONOTONIC.
	(__atomic_futex_unsigned_base::_M_futex_wait_until_steady): Add
	new variant of _M_futex_wait_until that uses CLOCK_MONOTONIC to
	support waiting using steady_clock.
2020-09-11 14:25:00 +01:00
..
post
pre libstdc++: Support futex waiting on chrono::steady_clock directly 2020-09-11 14:25:00 +01:00
compatibility.h