gcc内建的原子操作

You don’t want to mess around with assembly language, especially since you want your code to run on both x86 and ARM. Therefore, compilers let you access these instructions with built-in functions. On gcc, example functions are __sync_fetch_and_add() and __sync_bool_compare_and_swap(). They work just as well on x86 as ARM. Microsoft has similar intrinsics for their compilers.


__sync_fetch_and_add和__sync_bool_compare_and_swap在OceanBase中的应用见:

[xiaochu@OceanBase src]$ grep  __sync_fetch_and_add *  -nr
common/ob_memory_pool.cpp:212:    __sync_fetch_and_add(&mem_size_default_mod_, delta);
common/ob_memory_pool.cpp:220:    __sync_fetch_and_add(&mem_size_each_mod_[real_mod_id], delta);
common/ob_lighty_queue.cpp:81:              val = __sync_fetch_and_add(&val_, 1);
common/ob_lighty_queue.cpp:112:              val = __sync_fetch_and_add(&val_, -1);
common/ob_lighty_queue.cpp:217:    uint64_t seq = __sync_fetch_and_add(&push_, 1);
common/ob_lighty_queue.cpp:225:    uint64_t seq = __sync_fetch_and_add(&pop_, 1);
common/cmbtree/qlock.h:56:          return __sync_fetch_and_add(ref, 1);
common/cmbtree/qlock.h:61:          return __sync_fetch_and_add(ref, -1);
common/qlock.h:41:        return __sync_fetch_and_add(ref, 1);
common/qlock.h:46:        return __sync_fetch_and_add(ref, -1);
common/ob_simple_tpl.h:150:            __sync_fetch_and_add(&allocated_, size);
common/futex_sem.cpp:80:      if (__sync_fetch_and_add(&p->val_, 1) >= INT_MAX)
common/futex_sem.cpp:102:        __sync_fetch_and_add(&p->nwaiters_, 1);
common/futex_sem.cpp:119:        __sync_fetch_and_add(&p->nwaiters_, -1);
common/futex_sem.cpp:132:        __sync_fetch_and_add(&p->nwaiters_, 1);
common/futex_sem.cpp:155:        __sync_fetch_and_add(&p->nwaiters_, -1);
updateserver/ob_inc_seq.h:83:          pthread_setspecific(key_, (void*)(ref = read_ref_[__sync_fetch_and_add(&thread_num_, 1) % N_THREAD]));
[xiaochu@OceanBase src]$ grep __sync_bool_compare_and_swap * -nr
common/ob_atomic_type.h:56:            || !__sync_bool_compare_and_swap(&modify_version_, old_version, -1))
common/ob_atomic_type.h:66:            && !__sync_bool_compare_and_swap(&modify_version_, -1, old_version+1))
common/ob_lighty_queue.cpp:49:      while((x = *p) > 0 && !__sync_bool_compare_and_swap(p, x, x - 1))
common/ob_lighty_queue.cpp:57:      while((x = *p) <= 0 && !__sync_bool_compare_and_swap(p, x, x + 1))
common/ob_lighty_queue.cpp:143:          while(!__sync_bool_compare_and_swap(&data_, NULL, data))
common/ob_lighty_queue.cpp:158:          while(NULL == (data = data_) || !__sync_bool_compare_and_swap(&data_, data, NULL))
common/utility.h:380:        } while((tmp_seq & 1) || !__sync_bool_compare_and_swap(&seq_, tmp_seq, tmp_seq + 1));
common/utility.h:406:        locked_ = (0 == ((cur_seq = seq_) & 1)) && __sync_bool_compare_and_swap(&seq_, cur_seq, cur_seq + 1);
common/ob_tc_malloc.cpp:28:        if (__sync_bool_compare_and_swap(&init_lock, 0, 1))
common/ob_tc_malloc.cpp:33:            __sync_bool_compare_and_swap(&init_lock, 1, 0);
common/ob_tc_malloc.cpp:38:            __sync_bool_compare_and_swap(&init_lock, 1, 2);
common/ob_switch.h:93:          return __sync_bool_compare_and_swap(&seq_, seq, (seq&~STATE_MASK) + STATE_MASK + 1);
common/ob_switch.h:98:          return __sync_bool_compare_and_swap(&seq_, seq, seq | SWITCH_OFF);
common/ob_switch.h:103:          return __sync_bool_compare_and_swap(&seq_, seq, seq | SWITCH_REQ_OFF);
common/cmbtree/qlock.h:36:#define CAS(x, old_v, new_v) __sync_bool_compare_and_swap(x, old_v, new_v)
common/qlock.h:84:        else if (!__sync_bool_compare_and_swap(&uid_, 0, uid))
common/qlock.h:113:        else if (!__sync_bool_compare_and_swap(&uid_, 0, uid|EXCLUSIVE_BIT))
common/qlock.h:203:            if (__sync_bool_compare_and_swap(&uid_, 0, uid|EXCLUSIVE_BIT))
common/qlock.h:235:            if (__sync_bool_compare_and_swap(&uid_, 0, uid|EXCLUSIVE_BIT))
common/qlock.h:284:            else if (__sync_bool_compare_and_swap(&uid_, cur_uid, uid|EXCLUSIVE_BIT))
common/ob_seq_queue.cpp:115:      else if (!__sync_bool_compare_and_swap(&pitem->seq_, -1, -2))
common/ob_seq_queue.cpp:170:          else if (__sync_bool_compare_and_swap(&seq_, seq, seq + 1))
common/futex_sem.cpp:34:      while((x = *p) > 0 && !__sync_bool_compare_and_swap(p, x, x - 1))
updateserver/ob_inc_seq.h:108:        while(!__sync_bool_compare_and_swap(&write_uid_, 0, 1))

__sync_bool_compare_and_swap

Purpose

This function compares the value of __compVal with the value of the variable that __p points to. If they are equal, the value of __exchVal is stored in the address that is specified by __p; otherwise, no operation is performed.

A full memory barrier is created when this function is invoked.

Prototype

bool __sync_bool_compare_and_swap (T__pT __compValT __exchVal, ...);

where T is one of the data types listed in Supported data types.

Parameters

__p
The pointer to a variable whose value is to be compared with.
__compVal
The value to be compared with the value of the variable that  __p points to.
__exchVal
The value to be stored in the address that  __p points to.

Return value

If the value of __compVal and the value of the variable that __p points to are equal, the function returns true; otherwise, it returns false.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值