概述
SpinLock是对自旋锁的简单实现,因为SpinLock类仅仅是对MicroSpinLock的简单包装,所以本文主要讲述MicroSpinLock的实现。
后者的实现文件是folly/synchronization/MicroSpinLock.h。
设计-MicroSpinLock
唯一的数据成员就是一个uint8_t,它被作为一个值或为FREE或为LOCKED的原子变量使用:
struct MicroSpinLock {
enum {
FREE = 0, LOCKED = 1 };
// lock_ can't be std::atomic<> to preserve POD-ness.
uint8_t lock_;
// Initialize this MSL. It is unnecessary to call this if you
// zero-initialize the MicroSpinLock.
void init() noexcept {
payload()->store(FREE); }
private:
std::atomic<uint8_t>* payload() noexcept {
return reinterpret_cast<std::atomic<uint8_t>*>(&this->lock_);
}
bool cas(uint8_t compare, uint8_t newVal) noexcept {
return std::atomic_compare_exchange_strong_explicit(
payload(),
&compare,
newVal,
std::memory_order_acquire,
std::memory_order_relaxed);
}
};
lock和unlock的实现:
struct MicroSpinLock {
// ...
bool try_lock() noexcept {
bool ret = cas(FREE, LOCKED);
annotate_rwlock_try_acquired(
this, annotate_rwlock_level::wrlock, ret, __FILE__, __LINE__);
return ret;
}
void