[llvm-branch-commits] [libcxx] 216200a - [libc++] Fix hang in counting_semaphore::try_acquire
Arthur O'Dwyer via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Nov 5 13:03:43 PDT 2021
Author: Arthur O'Dwyer
Date: 2021-11-05T15:59:12-04:00
New Revision: 216200aff2681407b5e799738b09a047771d86ec
URL: https://github.com/llvm/llvm-project/commit/216200aff2681407b5e799738b09a047771d86ec
DIFF: https://github.com/llvm/llvm-project/commit/216200aff2681407b5e799738b09a047771d86ec.diff
LOG: [libc++] Fix hang in counting_semaphore::try_acquire
Before this patch, `try_acquire` blocks instead of returning false.
This is because `__libcpp_thread_poll_with_backoff` interprets zero
as meaning infinite, causing `try_acquire` to wait indefinitely.
Thanks to Pablo Busse (pabusse) for the patch!
Differential Revision: https://reviews.llvm.org/D98334
(cherry picked from commit c92a253cf0ddcf905707b4e9265b42570ce409d9)
Added:
Modified:
libcxx/include/semaphore
libcxx/test/std/thread/thread.semaphore/try_acquire.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index 1128b36d9527..db03fb967ed1 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -105,17 +105,22 @@ public:
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
{
- auto const __test_fn = [this]() -> bool {
- auto __old = __a.load(memory_order_acquire);
- while(1) {
- if (__old == 0)
- return false;
- if(__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed))
- return true;
- }
- };
+ if (__rel_time == chrono::duration<Rep, Period>::zero())
+ return try_acquire();
+ auto const __test_fn = [this]() { return try_acquire(); };
return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
}
+ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
+ bool try_acquire()
+ {
+ auto __old = __a.load(memory_order_acquire);
+ while (true) {
+ if (__old == 0)
+ return false;
+ if (__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed))
+ return true;
+ }
+ }
};
#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptr
diff _t>::max())
@@ -156,14 +161,14 @@ public:
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire()
{
- return try_acquire_for(chrono::nanoseconds::zero());
+ return __semaphore.try_acquire();
}
template <class Clock, class Duration>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire_until(chrono::time_point<Clock, Duration> const& __abs_time)
{
auto const current = Clock::now();
- if(current >= __abs_time)
+ if (current >= __abs_time)
return try_acquire();
else
return try_acquire_for(__abs_time - current);
diff --git a/libcxx/test/std/thread/thread.semaphore/try_acquire.pass.cpp b/libcxx/test/std/thread/thread.semaphore/try_acquire.pass.cpp
index 35cb6ce7dc82..5a5ab72d05df 100644
--- a/libcxx/test/std/thread/thread.semaphore/try_acquire.pass.cpp
+++ b/libcxx/test/std/thread/thread.semaphore/try_acquire.pass.cpp
@@ -27,14 +27,17 @@ int main(int, char**)
std::counting_semaphore<> s(1);
assert(s.try_acquire());
+ assert(!s.try_acquire());
s.release();
assert(s.try_acquire());
+ assert(!s.try_acquire());
s.release(2);
std::thread t = support::make_test_thread([&](){
assert(s.try_acquire());
});
t.join();
assert(s.try_acquire());
+ assert(!s.try_acquire());
return 0;
}
More information about the llvm-branch-commits
mailing list