HomePhabricator

Implement std::condition_variable via pthread_cond_clockwait() where available

Authored by danalbert on Sep 16 2019, 10:57 AM.

Description

Implement std::condition_variable via pthread_cond_clockwait() where available

std::condition_variable is currently implemented via
pthread_cond_timedwait() on systems that use pthread. This is
problematic, since that function waits by default on CLOCK_REALTIME
and libc++ does not provide any mechanism to change from this
default.

Due to this, regardless of if condition_variable::wait_until() is
called with a chrono::system_clock or chrono::steady_clock parameter,
condition_variable::wait_until() will wait using CLOCK_REALTIME. This
is not accurate to the C++ standard as calling
condition_variable::wait_until() with a chrono::steady_clock parameter
should use CLOCK_MONOTONIC.

This is particularly problematic because CLOCK_REALTIME is a bad
choice as it is subject to discontinuous time adjustments, that may
cause condition_variable::wait_until() to immediately timeout or wait
indefinitely.

This change fixes this issue with a new POSIX function,
pthread_cond_clockwait() proposed on
http://austingroupbugs.net/view.php?id=1216. The new function is
similar to pthread_cond_timedwait() with the addition of a clock
parameter that allows it to wait using either CLOCK_REALTIME or
CLOCK_MONOTONIC, thus allowing condition_variable::wait_until() to
wait using CLOCK_REALTIME for chrono::system_clock and CLOCK_MONOTONIC
for chrono::steady_clock.

pthread_cond_clockwait() is implemented in glibc (2.30 and later) and
Android's bionic (Android API version 30 and later).

This change additionally makes wait_for() and wait_until() with clocks
other than chrono::system_clock use CLOCK_MONOTONIC.<Paste>

llvm-svn: 372016

Event Timeline

leonardchan added inline comments.
/libcxx/include/__config
1091

Should there be a check before here for #if defined(__linux__)?

We're getting a bunch of errors relating to _LIBCPP_GLIBC_PREREQ not being defined when building libcxx for Fuchsia.

[51/717] Building CXX object compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_fuchsia.cpp.obj
FAILED: compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_fuchsia.cpp.obj 
...
In file included from /b/s/w/ir/k/recipe_cleanup/clanglCHXUb/llvm_build_dir/./bin/../include/c++/v1/stdint.h:106:
/b/s/w/ir/k/recipe_cleanup/clanglCHXUb/llvm_build_dir/./bin/../include/c++/v1/__config:1127:58: error: function-like macro '_LIBCPP_GLIBC_PREREQ' is not defined
#if (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)

Full log: https://logs.chromium.org/logs/fuchsia/buildbucket/cr-buildbucket.appspot.com/8902137346512980416/+/steps/clang/0/steps/build/0/stdout?format=raw