(79)成员函数 比较及弱交换 compare_exchange_weak (),功能与 compare_exchange_strong () 是等价的。多此一举的目的,可能是为了满足形式以及语义的完整性。源代码支持如下:
++ 测试一下:
(80) 接着给出 atomic《T》 的完整源代码,这是最重要的基础架构:
/*
(1)整数原子性的支持:加减法、*(-1)取反、a++、++a、a--、--a 以及按位的 与and、或or、异或xor 运算;
以及复合运算符 : +=、-=、&=、|=、^= 。
(2)指针类原子量支持的运算有:加减法、a++、++a、a--、--a、+=、-= 。
(3)浮点类型的原子类型的运算:加减法、+=、-= 。
(4)bool 类型只支持 赋值读值的 store ()、load () 这俩原子操作。
*/
template <class _Ty>
struct atomic : _Choose_atomic_base_t<_Ty>
{
private:
using _Base = _Choose_atomic_base_t<_Ty>;
public: // 要求 类型 _Ty 支持复制构造与移动构造的操作
static_assert( is_trivially_copyable_v<_Ty> && is_copy_constructible_v<_Ty> &&
is_copy_assignable_v<_Ty> && is_move_constructible_v<_Ty> && is_move_assignable_v<_Ty>,
"atomic<T> requires T to be trivially copyable, copy constructible, "
"move constructible, copy assignable, and move assignable." );
using value_type = _Ty; using _Base::_Base;
// template <size_t _TypeSize> // 当 T 的大小为 1 2 4 8 字节时将不需要自旋锁来保护数据
// bool _Is_always_lock_free = _TypeSize <= 8 && (_TypeSize & (_TypeSize - 1)) == 0;
static constexpr bool is_always_lock_free = _Is_always_lock_free<sizeof(_Ty)>; // 类的静态数据成员
atomic() noexcept(is_nothrow_default_constructible_v<_Ty>) : _Base() {} // 默认构造函数
atomic(const atomic&) = delete; // 禁止了 copy 构造函数
atomic& operator=(const atomic&) = delete; // 禁止了 copy 赋值运算符函数
//****测试本模板参数的类型是否是免自旋锁的****
bool is_lock_free() const volatile noexcept // 对于 1 2 4 8 16 将返回 true
{
constexpr bool _Result = sizeof(_Ty) <= 8 && (sizeof(_Ty) & sizeof(_Ty) - 1) == 0;
return _Result;
}
bool is_lock_free() const noexcept // 调用了上面的重载函数,对 this 的修饰不一样
{
return static_cast<const volatile atomic*>(this)->is_lock_free();
}
//****往 atomic<T> 里原子地写入数据****
using _Base::store;
/*
template <size_t _TypeSize> // 能同时满足这些条件的只有上面的 1 2 4 8 这四个数。此时不用内部自旋锁了。
bool _Is_always_lock_free = _TypeSize <= 8 && (_TypeSize & (_TypeSize - 1)) == 0;
template <class _Ty, bool _Is_lock_free = _Is_always_lock_free<sizeof(_Ty)>>
bool _Deprecate_non_lock_free_volatile = true; // 此模板变量恒为 true
template <class _Ty>
bool _Deprecate_non_lock_free_volatile<_Ty, false> = true;
*/
void store(const _Ty _Value) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails"); // 断言恒为真
const_cast<atomic*>(this)->_Base::store(_Value);
}
void store(const _Ty _Value, const memory_order _Order) volatile noexcept // 函数重载
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
const_cast<atomic*>(this)->_Base::store(_Value, _Order);
}
_Ty operator = (const _Ty _Value) volatile noexcept // 赋值运算符函数
{ // 加 volitile 是不要编译器过度优化,从内存读值
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails"); // 断言恒为真
this->store(_Value); // 调用了上面的函数
return _Value; // 返回 atomic<T> 原子量的新值
}
_Ty operator=(const _Ty _Value) noexcept
{
this->store(_Value);
return _Value;
}
//****从 atomic<T> 里原子地读值****
using _Base::load;
_Ty load() const volatile noexcept // 返回值是值传递或左值引用,取决于 atomic<_Ty> 中模板参数的类型
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return const_cast<const atomic*>(this)->_Base::load();
}
/*
template <class _Ty, size_t = sizeof(remove_reference_t<_Ty>)> // 泛化模板类
struct _Atomic_storage
{
_Ty _Storage{}; // 原子量要保护的数据成员,是个引用,也可以是一个值,都包括了
using _TVal = remove_reference_t<_Ty> ; // 该类的特化模板,也都采用了 _TVal 来作为 load() 的返回值
_TVal load(const memory_order _Order = memory_order_seq_cst) const noexcept // 读取值
{
_Check_load_memory_order(_Order); // 允许的读取内存序:relaxed、acquire、seq_cst
_Guard _Lock{ _Spinlock }; // 先获取自旋锁,再读取数据
_TVal _Local(_Storage);
return _Local; // 返回值是值传递
}
};
*/
_Ty load(const memory_order _Order) const volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return const_cast<const atomic*>(this)->_Base::load(_Order);
}
//**** atomic<T> 支持的类型转换运算符函数 ****
operator _Ty () const volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return this->load();
}
operator _Ty () const noexcept { return this->load(); }
//**** atomic<T> 支持等待与唤醒操作 ****
using _Base::wait; // wait()被 nofify()唤醒后,如果原子量的值等于形参 1,还是不会返回的。
void wait(const _Ty _Expected, const memory_order _Order = memory_order_seq_cst) const volatile noexcept
{
const_cast<const atomic*>(this)->_Base::wait(_Expected, _Order);
}
/*
template <class _Ty, size_t > // 泛化版本
struct _Atomic_storage
{ // 简单情况下 _Spinlock = long 类型。引用情况下 _Spinlock 是 void * 类型。
mutable typename _Atomic_storage_types<_Ty>::_Spinlock _Spinlock{}; // 定义了一个自旋锁
using _TVal = remove_reference_t<_Ty>;
_Ty _Storage{}; // 原子量要保护的数据成员,是个引用,也可以是一个值,都包括了
void wait(_TVal _Expected, memory_order = memory_order_seq_cst) const noexcept // 值不等于形参 1 才返回
{
const auto _Storage_ptr = _STD addressof(_Storage);
const auto _Expected_ptr = _STD addressof(_Expected);
for (;;) // 可见,wait()被 nofify()唤醒后,如果原子量的值等于形参 1,还是不会返回的。
{
{ _Guard _Lock{ _Spinlock }; // 取得自旋锁
if (_CSTD memcmp(_Storage_ptr, _Expected_ptr, sizeof(_TVal)) != 0) return;
}
__std_atomic_wait_indirect(_Storage_ptr, _Expected_ptr, sizeof(_TVal), &_Spinlock,
&_Atomic_wait_compare_non_lock_free<decltype(_Spinlock)>, _Atomic_wait_no_timeout);
}
}
};
*/
using _Base::notify_one;
void notify_one() volatile noexcept
{
const_cast<atomic*>(this)->_Base::notify_one();
}
using _Base::notify_all;
void notify_all() volatile noexcept
{
const_cast<atomic*>(this)->_Base::notify_all();
}
//**** 与形参交换数值 ****
using _Base::exchange;
_Ty exchange(const _Ty _Value) volatile noexcept // 存储形参里的新值,返回原子量里的旧值
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return const_cast<atomic*>(this)->_Base::exchange(_Value);
}
/*
template <class _Ty, size_t > // 泛化版本似乎简单
struct _Atomic_storage
{
mutable typename _Atomic_storage_types<_Ty>::_Spinlock _Spinlock{};
using _TVal = remove_reference_t<_Ty>;
_Ty _Storage{};
// exchange _Value with _Storage with sequential consistency // 意思是 atomic 存入新值,把旧值返回去
_TVal exchange(const _TVal _Value, const memory_order _Order = memory_order_seq_cst) noexcept
{
_Check_memory_order(_Order);
_Guard _Lock{ _Spinlock };
_TVal _Result(_Storage);
_Storage = _Value;
return _Result;
}
};
*/
_Ty exchange(const _Ty _Value, const memory_order _Order) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return const_cast<atomic*>(this)->_Base::exchange(_Value, _Order);
}
//**** 比较并强交换 ****
using _Base::compare_exchange_strong;
bool compare_exchange_strong(_Ty& _Expected, const _Ty _Desired) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return const_cast<atomic*>(this)->_Base::compare_exchange_strong(_Expected, _Desired);
}
/*
template <class _Ty, size_t = sizeof(remove_reference_t<_Ty>)>
struct _Atomic_storage
{
// 当本类中存储的值 等于形参1 时,把形参 2 的值存入本类;
// 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
// 返回值表示形参1 与本类中的值是否相等,是则返回 true。
bool compare_exchange_strong // 注意:形参1 是左值引用,对左值引用取地址返回的是原始值的地址
(_TVal& _Expected, const _TVal _Desired, const memory_order _Order = memory_order_seq_cst)
{
_Check_memory_order(_Order);
const auto _Storage_ptr = _STD addressof(_Storage); // 取本类中数据成员的地址
const auto _Expected_ptr = _STD addressof(_Expected);
bool _Result;
_Guard _Lock{ _Spinlock }; // 取得自旋锁
_Result = _CSTD memcmp(_Storage_ptr, _Expected_ptr, sizeof(_TVal)) == 0;
if (_Result)
_CSTD memcpy(_Storage_ptr, _STD addressof(_Desired), sizeof(_TVal));
else
_CSTD memcpy(_Expected_ptr, _Storage_ptr, sizeof(_TVal));
return _Result;
}
};
*/
bool compare_exchange_strong(_Ty& _Expected, const _Ty _Desired,
const memory_order _Order) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return const_cast<atomic*>(this)->_Base::compare_exchange_strong(_Expected, _Desired, _Order);
}
bool compare_exchange_strong(_Ty& _Expected, const _Ty _Desired,
const memory_order _Success, const memory_order _Failure) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return this->compare_exchange_strong( _Expected, _Desired,
_Combine_cas_memory_orders(_Success, _Failure));
}
bool compare_exchange_strong( _Ty& _Expected, const _Ty _Desired,
const memory_order _Success, const memory_order _Failure) noexcept
{
return this->compare_exchange_strong(_Expected, _Desired,
_Combine_cas_memory_orders(_Success, _Failure));
}
//**** 比较并弱交换 ****
// we have no weak CAS intrinsics, even on ARM32/ARM64, so fall back to strong
// 我们没有弱的 CAS 内置函数,即使在 ARM32/ARM64 上也是如此,所以等价于调用 compare_exchange_strong()
bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired) noexcept
{
return this->compare_exchange_strong(_Expected, _Desired);
}
bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return this->compare_exchange_strong(_Expected, _Desired);
}
bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired, const memory_order _Order) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return this->compare_exchange_strong(_Expected, _Desired, _Order);
}
bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired, const memory_order _Order) noexcept
{
return this->compare_exchange_strong(_Expected, _Desired, _Order);
}
bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired,
const memory_order _Success, const memory_order _Failure) volatile noexcept
{
static_assert(_Deprecate_non_lock_free_volatile<_Ty>, "Never fails");
return this->compare_exchange_strong(_Expected, _Desired,
_Combine_cas_memory_orders(_Success, _Failure));
}
bool compare_exchange_weak( _Ty& _Expected, const _Ty _Desired,
const memory_order _Success, const memory_order _Failure) noexcept
{
return this->compare_exchange_strong(_Expected, _Desired,
_Combine_cas_memory_orders(_Success, _Failure));
}
};
(81)经测试: atomic《T》 中 T 不可为引用类型:
++ 右值引用也是不可以的:
++ 代码来源是这个静态断言:
++ 再测试:
++ 以及:
++ 以及:
(82)
谢谢