atomic 注释28:测试 atomic<T>的成员函数 compare_exchange_weak()比较及弱交换, 及 atomic<T>的完整源代码,atomic<T> 中 T 不可为引用类型

(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)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值