应用程序中GCC原子操作类模板

gcc从4.1.2版本开始提供了__sync_*系列的内置API,用于加减和逻辑运算,可以对1,2,4,8字节长度的数值或指针类型进行原子操作。为方便使用,个人对这些API作了简单的封装,主类模板如下:   
 1 template < typename T >
 2 class  atomic_base 
 3 {
 4public:
 5    typedef T int_type;
 6    typedef atomic_base<T> self_type;
 7
 8public:
 9    atomic_base(int_type val = int_type())
10    : val_(val)
11    {
12    }

13
14    ~atomic_base()
15    {
16        BOOST_STATIC_ASSERT(sizeof(int_type)==1||sizeof(int_type)==2||sizeof(int_type)==4||sizeof(int_type)==8);
17    }

18
19    atomic_base(const self_type& other)
20    {
21        int_type val = other;
22        __sync_lock_test_and_set(&val_, val);
23    }

24
25    self_type& operator = (const self_type& other)
26    {
27        if (this!=&other)
28        {
29            int_type val = other;
30            __sync_lock_test_and_set(&val_, val);
31        }

32        return *this;
33    }

34    
35    operator int_type() const
36    {
37        return __sync_val_compare_and_swap(const_cast<volatile int_type*>(&val_),0,0);
38    }

39    
40    self_type operator++(int)
41    {
42        return __sync_fetch_and_add(&val_,1);
43    }

44
45    self_type& operator++()
46    {
47        __sync_add_and_fetch(&val_,1);
48        return *this;
49    }

50
51    self_type operator--(int)
52    {
53        return __sync_fetch_and_sub(&val_,1);
54    }

55
56    self_type& operator--()
57    {
58        __sync_sub_and_fetch(&val_,1);
59        return *this;
60    }

61
62    self_type& operator+=(int_type val)
63    {
64        __sync_add_and_fetch(&val_,val);
65        return *this;
66    }

67
68    self_type& operator-=(int_type val)
69    {
70        __sync_sub_and_fetch(&val_,val);
71        return *this;
72    }

73
74    self_type& operator&=(int_type val)
75    
76        __sync_and_and_fetch(&val_, val); 
77        return *this;
78    }

79
80    self_type& operator|=(int_type val)
81    {
82        __sync_or_and_fetch(&val_,val); 
83        return *this;
84    }

85    
86    self_type& operator^=(int_type val)
87    {
88        __sync_xor_and_fetch(&val_,val); 
89        return *this;
90    }

91
92private:
93    T val_;
94}
;
   上面析构函数中,使用了BOOST_STATIC_ASSERT宏来作编译期约束,确保类型T大小为1,2,4,8字节长度。由于提供了T到atomic_base的隐式转换和转型操作,因此没有必要再定义operato +,operator - ,opeator ^,operator |,operator &运算符成员或友元重载操作。由于主模板定义了operator+=,operator-=,operator&=,operator|=,operator^=运算符重载操作,但当T为指针类型时,指针的加减和逻辑运算没有意义,但对于指针加减一个数值是有意义的,因此前两者操作保留但需要重定义,但没有后三者操作,需要特化实现,其模板类如下:
 1 template < typename T >
 2 class  atomic_base < T *>  
 3 {
 4public:
 5    typedef T* pointer_type;
 6    typedef atomic_base<T*> self_type;
 7
 8public:
 9    atomic_base(pointer_type val = NULL)
10        : val_(val)
11    {
12    }

13
14    atomic_base(const self_type& other)
15    {
16        pointer_type val = other;
17        __sync_lock_test_and_set(&val_, val);
18    }

19
20    ~atomic_base()
21    {
22        BOOST_STATIC_ASSERT(sizeof(pointer_type)==1||sizeof(pointer_type)==2||sizeof(pointer_type)==4||sizeof(pointer_type)==8);
23    }

24
25    self_type& operator=(const self_type& other)
26    {
27        if (this!=&other)
28        {
29            pointer_type val = other;
30            __sync_lock_test_and_set(&val_, val);
31        }

32        return *this;
33    }

34
35    operator pointer_type() const
36    {
37        return __sync_val_compare_and_swap(const_cast<volatile pointer_type*>(&val_),0,0);
38    }

39
40    self_type operator++(int)
41    {
42        return __sync_fetch_and_add(&val_,1);
43    }

44
45    self_type& operator++()
46    {
47        __sync_add_and_fetch(&val_,1);
48        return *this;
49    }

50
51    self_type operator--(int)
52    {
53        return __sync_fetch_and_sub(&val_,1);
54    }

55
56    self_type& operator--()
57    {
58        __sync_sub_and_fetch(&val_,1);
59        return *this;
60    }

61
62    self_type& operator+=(std::ptrdiff_t d)
63    {
64        __sync_add_and_fetch(&val_,d);
65        return *this;
66    }

67
68    self_type& operator-=(std::ptrdiff_t d)
69    {
70        __sync_sub_and_fetch(&val_,d);
71        return *this;
72    }

73
74private:
75    T* val_;
76}
;
  同理,上面析构函数中,使用了BOOST_STATIC_ASSERT宏来作编译期约束,确保类型T的指针大小为1,2,4,8字节长度。在这里,要注意一个特例,大小为1字节的类型包括bool布尔类型,它的取值只有true或false两种可能,不存在加减运算操作,也没有意义,但逻辑运算是有意义的,因此需要特化实现,其模板类如下:
 1 template <>
 2 class  atomic_base < bool >
 3 {
 4public:
 5    typedef atomic_base<bool> self_type;
 6public:
 7    atomic_base(bool val = false)
 8        : val_(val)
 9    {
10    }

11    
12    atomic_base(const self_type& other)
13    {
14        __sync_lock_test_and_set(&val_, other.val_);
15    }

16    
17    self_type& operator=(const self_type& other)
18    {
19        if (this!=&other)
20            __sync_lock_test_and_set(&val_, other.val_);
21        return *this;
22    }

23    
24    operator bool() const
25    {
26        return __sync_val_compare_and_swap(const_cast<volatile bool*>(&val_),0,0);
27    }

28
29    self_type& operator&=(bool val)
30    
31        __sync_and_and_fetch(&val_, val); 
32        return *this;
33    }

34
35    self_type& operator|=(bool val)
36    {
37        __sync_or_and_fetch(&val_,val); 
38        return *this;
39    }

40
41    self_type& operator^=(bool val)
42    {
43        __sync_xor_and_fetch(&val_,val); 
44        return *this;
45    }

46
47private:
48    bool val_;
49}
;
   针对常见的基本数值类型,定义了其类型别名,如下:
 1 typedef atomic_base < bool >                      atomic_bool;
 2 typedef atomic_base < signed  char >            atomic_char;
 3 typedef atomic_base < unsigned  char >         atomic_uchar;
 4 typedef atomic_base < short >                     atomic_short;
 5 typedef atomic_base < unsigned  short >        atomic_ushort;
 6 typedef atomic_base < int >                        atomic_int;
 7 typedef atomic_base < unsigned  int >           atomic_uint;
 8 typedef atomic_base < long >                      atomic_long;
 9 typedef atomic_base < unsigned  long >         atomic_ulong;
10 typedef atomic_base < long   long >               atomic_llong;
11 typedef atomic_base < unsigned  long   long >   atomic_ullong;
   幸运的是,从gcc 4.4起,标准库就提供了atomic C++类,尤其是4.6(支持C++0x标准),作了很好的封装,相关头文件是atomic_base.h, atomic_0.h, atomic_2.h, atomic.h。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值