#include "tile/base/thread/spinlock.h"
#include "tile/base/chrono.h"

// https://doc.rust-lang.org/src/core/hint.rs.html#110
// _x86__       _mm_pause
// __x86_64__   _mm_pause
// riscv32      pause
// riscv64      pause
// aarch64      isb
// arm v6       yield

#if defined(__x86_64__) || defined(__i386__)
#define TILE_CPU_RELAX() asm volatile("pause" ::: "memory")
#elif defined(__aarch64__)
#define TILE_CPU_RELAX() asm volatile("isb" ::)
#elif defined(__arm__)
#define TILE_CPU_RELAX() asm volatile("yield" ::)
#else
#define TILE_CPU_RELAX()
#endif

namespace tile {

void
Spinlock::LockSlow() noexcept
{
    auto start_tp = ReadCoarseSteadyClock();
    do {
        while (locked_.load(std::memory_order_relaxed)) { TILE_CPU_RELAX(); }
    } while (locked_.exchange(true, std::memory_order_acquire));
}

void
RelaxCpu() noexcept
{
    TILE_CPU_RELAX();
}
}// namespace tile
