gcc内建的原子操作

来源:互联网 发布:淘宝企业店铺税点多少 编辑:程序博客网 时间:2024/06/07 07:21

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 *  -nrcommon/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 * -nrcommon/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.


原创粉丝点击