diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -582,6 +582,11 @@ target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_RT_LIB) endif() endif() + + if (LIBCXX_HAS_FUTEX_H) + # This tells compiler about the availability of linux/futex.h + target_compile_definitions(${target} PRIVATE -D_LIBCPP_HAS_FUTEX_H) + endif() endfunction() # Warning flags =============================================================== diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake --- a/libcxx/cmake/config-ix.cmake +++ b/libcxx/cmake/config-ix.cmake @@ -3,6 +3,7 @@ include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(CheckCSourceCompiles) +include(CheckIncludeFiles) if(WIN32 AND NOT MINGW) # NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets @@ -24,6 +25,10 @@ endif() endif() +# libc++ is using linux/futex.h for linux platform. So, check it and pass +# it to compiler later. +check_include_files(linux/futex.h LIBCXX_HAS_FUTEX_H) + # libc++ is using -nostdlib++ at the link step when available, # otherwise -nodefaultlibs is used. We want all our checks to also # use one of these options, otherwise we may end up with an inconsistency between diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp --- a/libcxx/src/atomic.cpp +++ b/libcxx/src/atomic.cpp @@ -16,7 +16,9 @@ #ifdef __linux__ #include +#ifdef _LIBCPP_HAS_FUTEX_H #include +#endif #include // libc++ uses SYS_futex as a universal syscall name. However, on 32 bit architectures @@ -39,13 +41,29 @@ __cxx_contention_t __val) { static constexpr timespec __timeout = { 2, 0 }; +#ifdef _LIBCPP_HAS_FUTEX_H syscall(SYS_futex, __ptr, FUTEX_WAIT_PRIVATE, __val, &__timeout, 0, 0); +#elif defined(__ve__) + // VE doesn't distribute linux/futex.h but SYS_futex with + // FUTEX_WAIT_PRIVATE is implemented at 128. + syscall(SYS_futex, __ptr, 128, __val, &__timeout, 0, 0); +#else +#error libc++ requries linux/futex.h or special handling for __libcpp_platform_wait_on_address +#endif } static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) { +#ifdef _LIBCPP_HAS_FUTEX_H syscall(SYS_futex, __ptr, FUTEX_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, 0, 0, 0); +#elif defined(__ve__) + // VE doesn't distribute linux/futex.h but SYS_futex with + // FUTEX_WAKE_PRIVATE is implemented at 129. + syscall(SYS_futex, __ptr, 129, __notify_one ? 1 : INT_MAX, 0, 0, 0); +#else +#error libc++ requries linux/futex.h or special handling for __libcpp_platform_wake_on_address +#endif } #elif defined(__APPLE__) && defined(_LIBCPP_USE_ULOCK)