This defines __platform_wait, __platform_notify, and
__platform_wait_until for DragonFly, making use of the umtx_sleep and
umtx_wakeup functions.
libstdc++-v3/ChangeLog:
PR libstdc++/120527
* include/bits/atomic_wait.h [__DragonFly__]: Reuse Linux
definitions of __platform_wait_t and __platform_wait_uses_type.
* src/c++20/atomic.cc [__DragonFly__] (_GLIBCXX_HAVE_PLATFORM_WAIT)
(__platform_wait, __platform_notify, __platform_wait_until):
Define.
---
Untested, not to be committed.
libstdc++-v3/include/bits/atomic_wait.h | 2 +-
libstdc++-v3/src/c++20/atomic.cc | 40 +++++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/libstdc++-v3/include/bits/atomic_wait.h
b/libstdc++-v3/include/bits/atomic_wait.h
index 22727e2101d9..6d72b328da31 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -56,7 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& (sizeof(_Tp) <= sizeof(__UINT64_TYPE__));
}
-#if defined _GLIBCXX_HAVE_LINUX_FUTEX
+#if defined _GLIBCXX_HAVE_LINUX_FUTEX || defined __DragonFly__
namespace __detail
{
// Use futex syscall on int objects.
diff --git a/libstdc++-v3/src/c++20/atomic.cc b/libstdc++-v3/src/c++20/atomic.cc
index 918b045adcd5..749071095332 100644
--- a/libstdc++-v3/src/c++20/atomic.cc
+++ b/libstdc++-v3/src/c++20/atomic.cc
@@ -54,6 +54,9 @@ __ulock_wake(uint32_t operation, void* addr, uint64_t
wake_value);
# include <sys/umtx.h>
# include <sys/time.h>
# define _GLIBCXX_HAVE_PLATFORM_WAIT 1
+#elif defined __DragonFly__
+# include <unistd.h>
+# define _GLIBCXX_HAVE_PLATFORM_WAIT 1
#endif
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
@@ -216,6 +219,43 @@ namespace
}
return true;
}
+#elif defined __DragonFly__
+ void
+ __platform_wait(const void* addr, uint64_t val, int /* obj_sz */) noexcept
+ {
+ if (umtx_sleep(static_cast<const int*>(addr), (int)val, 0))
+ if (errno == EINVAL)
+ __throw_system_error(errno);
+ }
+
+ void
+ __platform_notify(const void* addr, bool all, int /* obj_sz */) noexcept
+ {
+ umtx_wakeup(static_cast<const int*>(addr), !all);
+ }
+
+ // returns true if wait ended before timeout
+ bool
+ __platform_wait_until(const void* addr, uint64_t val,
+ const __wait_clock_t::time_point& atime,
+ int /* obj_sz */) noexcept
+ {
+ auto reltime
+ = chrono::ceil<chrono::microseconds>(__wait_clock_t::now() - atime);
+ if (reltime <= reltime.zero())
+ return false;
+ int timeout = numeric_limits<int>::max();
+ if (std::cmp_less(reltime.count(), timeout)
+ timeout = reltime.count();
+ if (umtx_sleep(static_cast<const int*>(addr), (int)val, reltime.count()))
+ {
+ if (errno == EWOULDBLOCK)
+ return timeout == numeric_limits<int>::max();
+ if (errno == EINVAL)
+ __throw_system_error(errno);
+ }
+ return true;
+ }
#endif // HAVE_LINUX_FUTEX
// The state used by atomic waiting and notifying functions.
--
2.51.1