#ifndef TILE_BASE_THREAD_SPINLOCK_H
#define TILE_BASE_THREAD_SPINLOCK_H

#pragma once

#include "tile/base/likely.h"

#include <atomic>

namespace tile {

class Spinlock {
public:
    void Lock() noexcept
    {
        if (TILE_LIKELY(TryLock())) { return; }

        LockSlow();
    }

    bool TryLock() noexcept { return !locked_.exchange(true, std::memory_order_acquire); }

    void Unlock() noexcept { locked_.store(false, std::memory_order_release); }

private:
    void LockSlow() noexcept;

private:
    std::atomic<bool> locked_{false};
};

void RelaxCpu() noexcept;
}// namespace tile

#endif// TILE_BASE_THREAD_SPINLOCK_H
