#include "internal.h"
DISPATCH_NOINLINE
static void *
__DISPATCH_WAIT_FOR_ENQUEUER__(void **ptr)
{
int spins = 0;
void *value;
while ((value = os_atomic_load(ptr, relaxed)) == NULL) {
_dispatch_preemption_yield(++spins);
}
return value;
}
void *
_dispatch_wait_for_enqueuer(void **ptr)
{
#if !DISPATCH_HW_CONFIG_UP
#if defined(__arm__) || defined(__arm64__)
int spins = DISPATCH_WAIT_SPINS_WFE;
void *value;
while (unlikely(spins-- > 0)) {
if (likely(value = __builtin_arm_ldrex(ptr))) {
__builtin_arm_clrex();
return value;
}
__builtin_arm_wfe();
}
#else
int spins = DISPATCH_WAIT_SPINS;
void *value;
while (unlikely(spins-- > 0)) {
if (likely(value = os_atomic_load(ptr, relaxed))) {
return value;
}
dispatch_hardware_pause();
}
#endif
#endif // DISPATCH_HW_CONFIG_UP
return __DISPATCH_WAIT_FOR_ENQUEUER__(ptr);
}