PALOpenBSD implement WaitOnAddress feature attempt. (#716)

This commit is contained in:
David CARLIER
2025-01-02 09:07:46 +00:00
committed by GitHub
parent 141cdd9361
commit 515b97d996

View File

@@ -3,6 +3,8 @@
#if defined(__OpenBSD__) && !defined(_KERNEL)
# include "pal_bsd.h"
# include <sys/futex.h>
namespace snmalloc
{
/**
@@ -21,7 +23,50 @@ namespace snmalloc
* declared explicitly to remind anyone who modifies this class that they
* should add any required features.
*/
static constexpr uint64_t pal_features = PALBSD::pal_features;
static constexpr uint64_t pal_features =
PALBSD::pal_features | WaitOnAddress;
using WaitingWord = int;
template<class T>
static void wait_on_address(std::atomic<T>& addr, T expected)
{
int backup = errno;
static_assert(
sizeof(T) == sizeof(WaitingWord) && alignof(T) == alignof(WaitingWord),
"T must be the same size and alignment as WaitingWord");
while (addr.load(std::memory_order_relaxed) == expected)
{
long ret = futex(
(uint32_t*)&addr,
FUTEX_WAIT_PRIVATE,
static_cast<int>(expected),
nullptr,
nullptr);
if (ret == 0)
break;
}
errno = backup;
}
template<class T>
static void notify_one_on_address(std::atomic<T>& addr)
{
static_assert(
sizeof(T) == sizeof(WaitingWord) && alignof(T) == alignof(WaitingWord),
"T must be the same size and alignment as WaitingWord");
futex((uint32_t*)&addr, FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr);
}
template<class T>
static void notify_all_on_address(std::atomic<T>& addr)
{
static_assert(
sizeof(T) == sizeof(WaitingWord) && alignof(T) == alignof(WaitingWord),
"T must be the same size and alignment as WaitingWord");
futex((uint32_t*)&addr, FUTEX_WAKE_PRIVATE, INT_MAX, nullptr, nullptr);
}
};
} // namespace snmalloc
#endif