SpinLock: Add acquire/release() and spinPause()
We're very careful to ensure that we add a cpu_relax hint.
This commit is contained in:
@@ -2,6 +2,17 @@
|
||||
#define SPIN_LOCK_H
|
||||
|
||||
#include <atomic>
|
||||
#ifdef __x86_64__
|
||||
#include <immintrin.h>
|
||||
#elif defined(__i386__)
|
||||
#include <xmmintrin.h>
|
||||
#elif defined(__arm__)
|
||||
#include <arm_neon.h>
|
||||
#elif defined(__aarch64__)
|
||||
#include <arm_neon.h>
|
||||
#elif defined(__aarch32__)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
namespace smo {
|
||||
|
||||
@@ -21,6 +32,41 @@ public:
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user