HomePhabricator

Implement std::condition_variable via pthread_cond_clockwait() where available

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>

Details

Committed
danalbertSep 16 2019, 10:57 AM
Parents
rL372015: [Clang][Codegen] Disable arm_acle.c test.
Branches
Unknown
Tags
Unknown

Event Timeline

This is failing to build on Darwin:

`
/Volumes/Jonas/llvm/llvm-project/libcxx/include/__config:1091:58: error: function-like macro '_LIBCPP_GLIBC_PREREQ' is not defined
#  if (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)

Our CMake bot was offline for a while, but I'm pretty sure it'll start showing up here: http://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/

This is failing to build on Darwin:

`
 /Volumes/Jonas/llvm/llvm-project/libcxx/include/__config:1091:58: error: function-like macro '_LIBCPP_GLIBC_PREREQ' is not defined
 #  if (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)

Our CMake bot was offline for a while, but I'm pretty sure it'll start showing up here: http://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/

The llvm bots are already failing, e.g.:

http://green.lab.llvm.org/green/job/libc++%20and%20libc++abi%20trunk/CI_ARCH=64,CI_EXCEPTIONS=ON,CI_STD=c++17/292/consoleFull#-75790501049ba4694-19c4-4d7e-bec5-911270d8a58c

/libcxx/trunk/include/__config
1091

_LIBCPP_GLIBC_PREREQ is only defined on linux, so this is missing a linux guard.

+tomcherry

Thanks for the heads up. I've reverted the patch.

In the past I would get emails for failing builds, but strangely I don't see any.