[libcxx-commits] [libcxx] [libc++] atomic timed wait (PR #172214)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jan 18 01:59:48 PST 2026
================
@@ -117,11 +128,20 @@ static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
*/
template <std::size_t _Size>
-static void __platform_wait_on_address(void const* __ptr, void const* __val) {
+static void __platform_wait_on_address(void const* __ptr, void const* __val, uint64_t __timeout_ns) {
static_assert(_Size == 8, "Can only wait on 8 bytes value");
- char buffer[_Size];
- std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
- _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
+ if (__timeout_ns == 0) {
+ char buffer[_Size];
+ std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
+ _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr);
+ } else {
+ // TODO the doc says it supports timeout but does not say how to use it
+ // https://man.freebsd.org/cgi/man.cgi?query=_umtx_op
----------------
huixie90 wrote:
Claude wrote the following code for me
```
_umtx_time ut;
ut._timeout.tv_sec = __timeout_ns / 1'000'000'000;
ut._timeout.tv_nsec = __timeout_ns % 1'000'000'000;
ut._flags = 0; // Relative time (not absolute)
ut._clockid = CLOCK_MONOTONIC; // Use monotonic clock
_umtx_op(const_cast<void*>(__ptr),
UMTX_OP_WAIT,
*reinterpret_cast<__cxx_contention_t*>(&buffer),
reinterpret_cast<void*>(sizeof(ut)), // Pass size as uaddr
&ut); // Pass _umtx_time structure as uaddr2
```
And I wrote a test
```
int main(int, char**) {
std::counting_semaphore<> s(0);
(void)s.try_acquire_for(std::chrono::seconds(300));
return 0;
}
```
and the FreeBSD CI seems to do the right thing
```
302.25s: llvm-libc++-shared.cfg.in :: std/thread/thread.semaphore/lost_wakeup.timed2.pass.cpp
```
https://github.com/llvm/llvm-project/pull/172214
More information about the libcxx-commits
mailing list