PALOpenBSD implement WaitOnAddress feature attempt. (#716)
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
#if defined(__OpenBSD__) && !defined(_KERNEL)
|
#if defined(__OpenBSD__) && !defined(_KERNEL)
|
||||||
# include "pal_bsd.h"
|
# include "pal_bsd.h"
|
||||||
|
|
||||||
|
# include <sys/futex.h>
|
||||||
|
|
||||||
namespace snmalloc
|
namespace snmalloc
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -21,7 +23,50 @@ namespace snmalloc
|
|||||||
* declared explicitly to remind anyone who modifies this class that they
|
* declared explicitly to remind anyone who modifies this class that they
|
||||||
* should add any required features.
|
* 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
|
} // namespace snmalloc
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user