#ifndef SPIN_LOCK_H #define SPIN_LOCK_H #include #ifdef __x86_64__ #include #elif defined(__i386__) #include #elif defined(__arm__) #include #elif defined(__aarch64__) #include #elif defined(__aarch32__) #include #endif namespace smo { /** * @brief Simple spinlock using std::atomic */ class SpinLock { public: SpinLock() : locked(false) {} bool tryAcquire() { bool expected = false; return locked.compare_exchange_strong(expected, true); } inline void spinPause() { #ifdef __x86_64__ _mm_pause(); #elif defined(__i386__) _mm_pause(); #elif defined(__arm__) __asm__ volatile("yield"); #elif defined(__aarch64__) __asm__ volatile("yield"); #elif defined(__aarch32__) __asm__ volatile("yield"); #else # error "Unsupported architecture" #endif } void acquire() { while (!tryAcquire()) { /** EXPLANATION: * Busy-wait: keep trying to acquire the lock * The CPU will spin here until the lock becomes available * * The spinPause() function is architecture-specific and is * essential because I once fried an older Intel M-class laptop CPU * when I forgot to include a PAUSE instruction in a for (;;){} * loop. I'm not interested in frying my RPi or my other testbed * robot boards. */ spinPause(); } } void release() { locked.store(false); } private: std::atomic locked; }; } // namespace smo #endif // SPIN_LOCK_H