atomic 注释15:特化模板类 _Atomic_storage<T, 2>、_Atomic_storage<T, 4>、_Atomic_storage<T, 8>

(44)特化模板 _Atomic_storage《T, 2》,以更高效的方式处理保存的 short 型变量

template <class _Ty>            // lock-free using 2-byte intrinsics
struct _Atomic_storage<_Ty, 2>  // 无锁,使用2字节内置函数
{ 
    typename _Atomic_storage_types<_Ty>::_TStorage _Storage; // 本类的数据成员

    using _TVal = remove_reference_t<_Ty>;
    
    _Atomic_storage() = default;   // 默认构造函数

    _Atomic_storage(conditional_t<is_reference_v<_Ty>, _Ty, const _TVal> _Value) // 有参构造函数
        : _Storage{_Value} { }
    
    // template <class _Ty, class _Value_type>   本函数会让本线程睡眠等待,直到形参 1 和 2 不等才返回
    // void _Atomic_wait_direct                  更准确的描述是等待原子量(形参1 ) 发生变化后才返回
    // ( _Atomic_storage<_Ty>* this, _Value_type expected_bytes, memory_order order)
    // 所以,本成员函数的语义是等待本类的数据成员与形参 1 不等才返回。 
    void wait(const _TVal _Expected, const memory_order _Order = memory_order_seq_cst) const noexcept
    {
        _Atomic_wait_direct(this, _Atomic_reinterpret_as<short>(_Expected), _Order);
    }

    void notify_one() { __std_atomic_notify_one_direct(_STD addressof(_Storage)); }

    void notify_all() { __std_atomic_notify_all_direct(_STD addressof(_Storage)); }

    //********************

    void store(const _TVal _Value) noexcept  // store with sequential consistency 函数重载
    { 
        const auto _Mem       = _Atomic_address_as<short>(_Storage);
        const short _As_bytes = _Atomic_reinterpret_as<short>(_Value);

        (void) _InterlockedExchange16(_Mem, _As_bytes);
    }

    void store(const _TVal _Value, const memory_order _Order) noexcept  // store with given memory order
    { 
        const auto _Mem       = _Atomic_address_as<short>(_Storage);
        const short _As_bytes = _Atomic_reinterpret_as<short>(_Value);
        switch (_Order) 
        {
        case memory_order_relaxed:  __iso_volatile_store16(_Mem, _As_bytes);     return;
        case memory_order_release:
            _Compiler_or_memory_barrier();
            __iso_volatile_store16(_Mem, _As_bytes);
            return;
        default:
        case memory_order_consume:
        case memory_order_acquire:
        case memory_order_acq_rel:     _INVALID_MEMORY_ORDER;
            // [[fallthrough]];
        case memory_order_seq_cst:      store(_Value);       return;
        }
    }

    //*********************

    _TVal load() const noexcept  // load with sequential consistency  函数重载
    { 
        const auto _Mem = _Atomic_address_as<short>(_Storage);

        short _As_bytes = __iso_volatile_load16(_Mem);

        _Compiler_or_memory_barrier(); //= _Compiler_barrier() 插入内存栅栏

        return reinterpret_cast<_TVal&>(_As_bytes);
    }

    _TVal load(const memory_order _Order) const noexcept // load with given memory order
    { 
        const auto _Mem = _Atomic_address_as<short>(_Storage);
        short _As_bytes = __iso_volatile_load16(_Mem);
        _Load_barrier(_Order);
        return reinterpret_cast<_TVal&>(_As_bytes);
    }

    //********************

    // exchange with given memory order  按指定内存序,把形参 1 的值存入本类中
    _TVal exchange(const _TVal _Value, const memory_order _Order = memory_order_seq_cst) noexcept 
    {        
        short _As_bytes;

        _ATOMIC_CHOOSE_INTRINSIC(_Order, _As_bytes, _InterlockedExchange16,
            _Atomic_address_as<short>(_Storage), _Atomic_reinterpret_as<short>(_Value));

        return reinterpret_cast<_TVal&>(_As_bytes);  // 经测试,是把本类保存的旧值返回
    }

/*此宏函数的定义在本头文件的最上面
#define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
    _Check_memory_order(_Order);                                   \
    _Result = _Intrinsic(__VA_ARGS__)
*/
    // 当本类中存储的值   等于形参1 时,把形参 2 的值存入本类;
    // 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
    // 返回值表示形参1 与本类中的值是否相等,是则返回 true。
    bool compare_exchange_strong   // CAS with given memory order
    (_TVal& _Expected, const _TVal _Desired, const memory_order _Order = memory_order_seq_cst) 
    { 
        short _Expected_bytes = _Atomic_reinterpret_as<short>(_Expected); // read before atomic operation

        short _Prev_bytes;  // 下面宏函数里 函 _InterlockedCompareExchange8() 的返回值

        // 经测试,函 _InterlockedCompareExchange16() 总返回其形参1 的原值。这里则是本类中的数据成员原始值
        _ATOMIC_CHOOSE_INTRINSIC(_Order, _Prev_bytes, _InterlockedCompareExchange16,
            _Atomic_address_as<short>(_Storage), _Atomic_reinterpret_as<short>(_Desired), _Expected_bytes);

        if (_Prev_bytes == _Expected_bytes)      return true;

        _CSTD memcpy(_STD addressof(_Expected), &_Prev_bytes, sizeof(_Ty));

        return false;
    }

};

(45) 接着介绍该类的另一个特化模板 _Atomic_storage《T, 4》,以更高效的方式处理保存的 int 型变量

template <class _Ty>           // lock-free using 4-byte intrinsics
struct _Atomic_storage<_Ty, 4> // 无锁,使用4字节内置函数
{
    typename _Atomic_storage_types<_Ty>::_TStorage _Storage;

    using _TVal = remove_reference_t<_Ty>;

    _Atomic_storage() = default; // 默认构造函数

    // non-atomically initialize this atomic
    _Atomic_storage(conditional_t<is_reference_v<_Ty>, _Ty, const _TVal> _Value) // 有参构造函数
        : _Storage{_Value} {  }
    
    // template <class _Ty, class _Value_type>   本函数会让本线程睡眠等待,直到形参 1 和 2 不等才返回
    // void _Atomic_wait_direct                  更准确的描述是等待原子量(形参1 ) 发生变化后才返回
    // ( _Atomic_storage<_Ty>* this, _Value_type expected_bytes, memory_order order)
    // 所以,本成员函数的语义是等待本类的数据成员与形参 1 不等才返回
    void wait(const _TVal _Expected, const memory_order _Order = memory_order_seq_cst) const noexcept
    {
        _Atomic_wait_direct(this, _Atomic_reinterpret_as<long>(_Expected), _Order);
    }

    void notify_one() { __std_atomic_notify_one_direct(_STD addressof(_Storage)); }

    void notify_all() { __std_atomic_notify_all_direct(_STD addressof(_Storage)); }

    //***************

    void store(const _TVal _Value) noexcept  // store with sequential consistency 函数重载
    { 
        (void) _InterlockedExchange(_Atomic_address_as<long>(_Storage), _Atomic_reinterpret_as<long>(_Value));
    }

    void store(const _TVal _Value, const memory_order _Order) noexcept  // store with given memory order
    { 
        const auto _Mem     = _Atomic_address_as<int>(_Storage)  ;
        const int _As_bytes = _Atomic_reinterpret_as<int>(_Value);
        switch (_Order) 
        {
        case memory_order_relaxed:   __iso_volatile_store32(_Mem, _As_bytes);       return;
        case memory_order_release:
            _Compiler_or_memory_barrier();   //= _Compiler_barrier() 插入内存栅栏
            __iso_volatile_store32(_Mem, _As_bytes);
            return;
        default:
        case memory_order_consume:
        case memory_order_acquire:
        case memory_order_acq_rel:   _INVALID_MEMORY_ORDER;
            // [[fallthrough]];
        case memory_order_seq_cst:     store(_Value);       return;
        }
    }

    //****************************

    _TVal load() const noexcept  // load with sequential consistency  函数重载
    { 
        const auto _Mem = _Atomic_address_as<int>(_Storage);

        auto _As_bytes  = __iso_volatile_load32(_Mem);

        _Compiler_or_memory_barrier();    //= _Compiler_barrier() 插入内存栅栏

        return reinterpret_cast<_TVal&>(_As_bytes);
    }

    _TVal load(const memory_order _Order) const noexcept  // load with given memory order
    { 
        const auto _Mem = _Atomic_address_as<int>(_Storage);

        auto _As_bytes  = __iso_volatile_load32(_Mem);

        _Load_barrier(_Order);           //  检查并根据形参内存序的级别,设置内存栅栏

        return reinterpret_cast<_TVal&>(_As_bytes);
    }

    //********************

    // exchange with given memory order 按指定内存序,把形参 1 的值存入本类中
    _TVal exchange(const _TVal _Value, const memory_order _Order = memory_order_seq_cst) 
    {        
        long _As_bytes;

        _ATOMIC_CHOOSE_INTRINSIC(_Order, _As_bytes, _InterlockedExchange,
            _Atomic_address_as<long>(_Storage), _Atomic_reinterpret_as<long>(_Value));

        return reinterpret_cast<_TVal&>(_As_bytes);
    }

/*此宏函数的定义在本头文件的最上面
#define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
    _Check_memory_order(_Order);                                   \
    _Result = _Intrinsic(__VA_ARGS__)
*/
    // 当本类中存储的值   等于形参1 时,把形参 2 的值存入本类;
    // 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
    // 返回值表示形参1 与本类中的值是否相等,是则返回 true。
    bool compare_exchange_strong  // CAS with given memory order
    (_TVal& _Expected, const _TVal _Desired, const memory_order _Order = memory_order_seq_cst) 
    { 
        long _Expected_bytes = _Atomic_reinterpret_as<long>(_Expected); // read before atomic operation
        long _Prev_bytes;

        // 经测试,函 _InterlockedCompareExchange8() 总返回其形参1 的原值。这里则是本类中的数据成员原始值
        _ATOMIC_CHOOSE_INTRINSIC(_Order, _Prev_bytes, _InterlockedCompareExchange, 
            _Atomic_address_as<long>(_Storage), _Atomic_reinterpret_as<long>(_Desired), _Expected_bytes);

        if (_Prev_bytes == _Expected_bytes)   return true;
        
        _CSTD memcpy(_STD addressof(_Expected), &_Prev_bytes, sizeof(_TVal));
        return false;
    }
    
};

(46) 接着介绍该类的另一个特化模板 _Atomic_storage《T, 8》,以更高效的方式处理保存的 long long 型变量

template <class _Ty>           // lock-free using 8-byte intrinsics
struct _Atomic_storage<_Ty, 8> // 无锁,使用 8 字节内置函数
{ 
    typename _Atomic_storage_types<_Ty>::_TStorage _Storage; // 本模板类的数据成员

    using _TVal = remove_reference_t<_Ty>;

    _Atomic_storage() = default;  // 默认构造函数

    // non-atomically initialize this atomic
    _Atomic_storage(conditional_t<is_reference_v<_Ty>, _Ty, const _TVal> _Value) // 有参构造函数
        : _Storage{_Value} { }
     
    // template <class _Ty, class _Value_type>   本函数会让本线程睡眠等待,直到形参 1 和 2 不等才返回
    // void _Atomic_wait_direct                  更准确的描述是等待原子量(形参1 ) 发生变化后才返回
    // ( _Atomic_storage<_Ty>* this, _Value_type expected_bytes, memory_order order)
    // 所以,本成员函数的语义是等待本类的数据成员与形参 1 不等才返回
    void wait(const _TVal _Expected, const memory_order _Order = memory_order_seq_cst) const noexcept 
    {
        _Atomic_wait_direct(this, _Atomic_reinterpret_as<long long>(_Expected), _Order);
    }

    void notify_one() { __std_atomic_notify_one_direct(_STD addressof(_Storage)); }

    void notify_all() { __std_atomic_notify_all_direct(_STD addressof(_Storage)); }

    //***************

    void store(const _TVal _Value) noexcept  // store with sequential consistency 函数重载
    { 
        const auto _Mem           = _Atomic_address_as<long long>(_Storage)  ;
        const long long _As_bytes = _Atomic_reinterpret_as<long long>(_Value);

        (void) _InterlockedExchange64(_Mem, _As_bytes);
    }

    void store(const _TVal _Value, const memory_order _Order) noexcept // store with given memory order
    { 
        const auto _Mem           = _Atomic_address_as<long long>(_Storage);
        const long long _As_bytes = _Atomic_reinterpret_as<long long>(_Value);
        switch (_Order) 
        {
        case memory_order_relaxed:     __iso_volatile_store64(_Mem, _As_bytes);      return;
        case memory_order_release:
            _Compiler_or_memory_barrier();  //= _Compiler_barrier() 插入内存栅栏
            __iso_volatile_store64(_Mem, _As_bytes);
            return;
        default:
        case memory_order_consume:
        case memory_order_acquire:
        case memory_order_acq_rel:        _INVALID_MEMORY_ORDER;      
            // [[fallthrough]];
        case memory_order_seq_cst:      store(_Value);        return;
        }
    }

    //***********************

    _TVal load() const noexcept  // load with sequential consistency 函数重载
    { 
        const auto _Mem = _Atomic_address_as<long long>(_Storage);

        long long _As_bytes;

        _As_bytes = __iso_volatile_load64(_Mem);

        _Compiler_or_memory_barrier();  //= _Compiler_barrier() 插入内存栅栏

        return reinterpret_cast<_TVal&>(_As_bytes);
    }

    _TVal load(const memory_order _Order) const noexcept // load with given memory order
    { 
        const auto _Mem = _Atomic_address_as<long long>(_Storage);

        long long _As_bytes = __iso_volatile_load64(_Mem);

        _Load_barrier(_Order);         //  检查并根据形参内存序的级别,设置内存栅栏

        return reinterpret_cast<_TVal&>(_As_bytes);
    }

    //***********************

    // exchange with given memory order 按指定内存序,把形参 1 的值存入本类中
    _TVal exchange(const _TVal _Value, const memory_order _Order = memory_order_seq_cst) 
    {        
        long long _As_bytes;

        _ATOMIC_CHOOSE_INTRINSIC(_Order, _As_bytes, _InterlockedExchange64,
            _Atomic_address_as<long long>(_Storage), _Atomic_reinterpret_as<long long>(_Value));

        return reinterpret_cast<_TVal&>(_As_bytes);
    }

    /*此宏函数的定义在本头文件的最上面
    #define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
        _Check_memory_order(_Order);                                   \
        _Result = _Intrinsic(__VA_ARGS__)
    */
    // 当本类中存储的值   等于形参1 时,把形参 2 的值存入本类;
    // 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
    // 返回值表示形参1 与本类中的值是否相等,是则返回 true。    
    bool compare_exchange_strong      // CAS with given memory order
    (_TVal& _Expected, const _TVal _Desired, const memory_order _Order = memory_order_seq_cst) 
    {
        long long _Expected_bytes = _Atomic_reinterpret_as<long long>(_Expected); // read before atomic operation
        long long _Prev_bytes;

        // 经测试,函 _InterlockedCompareExchange8() 总返回其形参1 的原值。这里则是本类中的数据成员原始值
        _ATOMIC_CHOOSE_INTRINSIC(_Order, _Prev_bytes, _InterlockedCompareExchange64,
            _Atomic_address_as<long long>(_Storage), _Atomic_reinterpret_as<long long>(_Desired), _Expected_bytes);

        if (_Prev_bytes == _Expected_bytes)   return true;

        _CSTD memcpy(_STD addressof(_Expected), &_Prev_bytes, sizeof(_TVal));
        return false;
    }

};

(47)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值