From 6c7f998ae58874c350880f1fb033d73ba7f04da0 Mon Sep 17 00:00:00 2001 From: gaohongtao Date: Mon, 7 Apr 2025 17:00:27 +0800 Subject: [PATCH] [libcxx]Enable _LIBCPP_HAS_COND_CLOCKWAIT for condition_variable https://gitee.com/openharmony/third_party_llvm-project/issues/IB0ONT Signed-off-by: lightaooii --- libcxx/include/__config | 4 +++ libcxx/include/__mutex_base | 59 +++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/libcxx/include/__config b/libcxx/include/__config index 8bc9e49e9b35..887ca8573a69 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -933,6 +933,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # if _LIBCPP_GLIBC_PREREQ(2, 30) # define _LIBCPP_HAS_COND_CLOCKWAIT # endif +# elif defined(__OHOS_FAMILY__) // OHOS_LOCAL +# if defined(_LIBCPP_HAS_MUSL_LIBC) +# define _LIBCPP_HAS_COND_CLOCKWAIT +# endif # endif # endif diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base index ac0d090b7d19..11fdedcd300a 100644 --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -475,30 +475,45 @@ condition_variable::wait_for(unique_lock& __lk, #if defined(_LIBCPP_HAS_COND_CLOCKWAIT) inline void -condition_variable::__do_timed_wait(unique_lock& __lk, - chrono::time_point __tp) _NOEXCEPT -{ - using namespace chrono; +condition_variable::__do_timed_wait(unique_lock& __lk, + chrono::time_point __tp) _NOEXCEPT { if (!__lk.owns_lock()) - __throw_system_error(EPERM, - "condition_variable::timed wait: mutex not locked"); - nanoseconds __d = __tp.time_since_epoch(); - timespec __ts; - seconds __s = duration_cast(__d); - using __ts_sec = decltype(__ts.tv_sec); - const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); - if (__s.count() < __ts_sec_max) - { - __ts.tv_sec = static_cast<__ts_sec>(__s.count()); - __ts.tv_nsec = (__d - __s).count(); - } - else - { - __ts.tv_sec = __ts_sec_max; - __ts.tv_nsec = giga::num - 1; - } + __throw_system_error(EPERM, "condition_variable::timed wait: mutex not locked"); + + auto __d = __tp.time_since_epoch(); + + // Note: we have to do some optimizations here to reduce the inline cost + // as there're lots of 'failed to inline' compilation errors. + /* + Simplified Time Conversion + Original: Manually decomposed the duration into seconds and nanoseconds using multiple variables and conditional checks. + Optimized: Utilized direct duration casting and modulo operation to compute seconds and nanoseconds in a single + initializer list, reducing intermediate variables and improving readability. + Efficient Edge Case Handling + Original: Checked if the seconds count was less than the maximum value of timespec.tv_sec, then assigned values conditionally. + Optimized: Directly initialized timespec and adjusted only when the seconds value hit the maximum, simplifying the logic flow. + Reduced Namespace Pollution + Original: Used using namespace chrono;, which could introduce naming conflicts. + Optimized: Avoided the using directive, instead using explicit namespace qualifications where necessary. + Precision Handling + Original: Set nanoseconds to giga::num - 1 (999,999,999) for maximum time. + Optimized: Used nano::den - 1, which is equivalent but more semantically clear as it directly refers to the denominator + of the nanoseconds ratio (1,000,000,000 - 1). + */ + + // Convert the duration to a timespec structure + timespec __ts{ + duration_cast(__d).count(), // Convert the duration to seconds + (__d % chrono::seconds(1)).count() // Get the remaining nanoseconds + }; + + // Check for overflow and adjust if necessary + if (__ts.tv_sec == numeric_limits::max()) + // Set the nanoseconds part to the maximum possible value + __ts.tv_nsec = nano::den - 1; + int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts); - if (__ec != 0 && __ec != ETIMEDOUT) + if (__ec && __ec != ETIMEDOUT) __throw_system_error(__ec, "condition_variable timed_wait failed"); } #endif // _LIBCPP_HAS_COND_CLOCKWAIT -- Gitee