60int __ulock_wait(uint32_t op,
void* address, uint64_t val, uint32_t max_us);
61int __ulock_wake(uint32_t op,
void* address, uint64_t zero);
81 const uint32_t prev,
const std::atomic<uint32_t>& current) {
82 const auto acq = std::memory_order_acquire;
86 volatile void* address =
87 const_cast<volatile void*
>(
static_cast<const volatile void*
>(¤t));
88 const double max_ms = INFINITY;
90 const uint32_t next = current.load(acq);
91 if (next != prev)
return next;
92 const int ret = emscripten_futex_wait(address, prev, max_ms);
99 const uint32_t* address =
reinterpret_cast<const uint32_t*
>(¤t);
102 const int op = FUTEX_WAIT_PRIVATE;
104 const uint32_t next = current.load(acq);
105 if (next != prev)
return next;
108 const auto ret = syscall(SYS_futex, address, op, prev,
nullptr,
nullptr, 0);
114#elif HWY_OS_WIN && !defined(HWY_DISABLE_FUTEX)
116 volatile void* address =
117 const_cast<volatile void*
>(
static_cast<const volatile void*
>(¤t));
119 PVOID pprev =
const_cast<void*
>(
static_cast<const void*
>(&prev));
120 const DWORD max_ms = INFINITE;
122 const uint32_t next = current.load(acq);
123 if (next != prev)
return next;
124 const BOOL ok = WaitOnAddress(address, pprev,
sizeof(prev), max_ms);
129#elif HWY_OS_APPLE && !defined(HWY_DISABLE_FUTEX)
131 void* address =
const_cast<void*
>(
static_cast<const void*
>(¤t));
133 const uint32_t next = current.load(acq);
134 if (next != prev)
return next;
135 __ulock_wait(UL_COMPARE_AND_WAIT, address, prev, 0);
138#elif defined(HWY_FUTEX_SLEEP)
140 const uint32_t next = current.load(acq);
141 if (next != prev)
return next;
142 std::this_thread::sleep_for(std::chrono::microseconds(2));
145#elif HWY_CXX_LANG >= 202002L
146 current.wait(prev, acq);
147 const uint32_t next = current.load(acq);
152#error "Logic error, should have reached HWY_FUTEX_SLEEP"
158static inline void WakeAll(std::atomic<uint32_t>& current) {
161 volatile void* address =
static_cast<volatile void*
>(¤t);
162 const int max_to_wake = INT_MAX;
163 const int ret = emscripten_futex_wake(address, max_to_wake);
169 uint32_t* address =
reinterpret_cast<uint32_t*
>(¤t);
170 const int max_to_wake = INT_MAX;
171 const auto ret = syscall(SYS_futex, address, FUTEX_WAKE_PRIVATE, max_to_wake,
172 nullptr,
nullptr, 0);
176#elif HWY_OS_WIN && !defined(HWY_DISABLE_FUTEX)
178 void* address =
static_cast<void*
>(¤t);
179 WakeByAddressAll(address);
181#elif HWY_OS_APPLE && !defined(HWY_DISABLE_FUTEX)
183 void* address =
static_cast<void*
>(¤t);
184 __ulock_wake(UL_COMPARE_AND_WAIT | ULF_WAKE_ALL, address, 0);
186#elif defined(HWY_FUTEX_SLEEP)
189#elif HWY_CXX_LANG >= 202002L
190 current.notify_all();
193#error "Logic error, should have reached HWY_FUTEX_SLEEP"