• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-167  評論-8  文章-0  trackbacks-0
            gcc從4.1.2提供了__sync_*系列的built-in函數,用于提供加減和邏輯運算的原子操作。

            其聲明如下:

            type __sync_fetch_and_add (type *ptr, type value, ...)
            type __sync_fetch_and_sub (type 
            *ptr, type value, ...)
            type __sync_fetch_and_or (type 
            *ptr, type value, ...)
            type __sync_fetch_and_and (type 
            *ptr, type value, ...)
            type __sync_fetch_and_xor (type 
            *ptr, type value, ...)
            type __sync_fetch_and_nand (type 
            *ptr, type value, ...)


            type __sync_add_and_fetch (type 
            *ptr, type value, ...)
            type __sync_sub_and_fetch (type 
            *ptr, type value, ...)
            type __sync_or_and_fetch (type 
            *ptr, type value, ...)
            type __sync_and_and_fetch (type 
            *ptr, type value, ...)
            type __sync_xor_and_fetch (type 
            *ptr, type value, ...)
            type __sync_nand_and_fetch (type 
            *ptr, type value, ...)




            這兩組函數的區別在于第一組返回更新前的值,第二組返回更新后的值。

            type可以是1,2,4或8字節長度的int類型,即:

            int8_t 
            / uint8_t
            int16_t 
            / uint16_t
            int32_t 
            / uint32_t
            int64_t 
            / uint64_t



            后面的可擴展參數(...)用來指出哪些變量需要memory barrier,因為目前gcc實現的是full barrier(類似于linux kernel 中的mb(),表示這個操作之前的所有內存操作不會被重排序到這個操作之后),所以可以略掉這個參數。


            bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
            type __sync_val_compare_and_swap (type 
            *ptr, type oldval type newval, ...)


            這兩個函數提供原子的比較和交換,如果*ptr == oldval,就將newval寫入*ptr,
            第一個函數在相等并寫入的情況下返回true.
            第二個函數在返回操作之前的值。

            __sync_synchronize (...)

            發出一個full barrier.

            關于memory barrier,cpu會對我們的指令進行排序,一般說來會提高程序的效率,但有時候可能造成我們不希望得到的結果,舉一個例子,比如我們有一個硬件設備,它有4個寄存器,當你發出一個操作指令的時候,一個寄存器存的是你的操作指令(比如READ),兩個寄存器存的是參數(比如是地址和size),最后一個寄存器是控制寄存器,在所有的參數都設置好之后向其發出指令,設備開始讀取參數,執行命令,程序可能如下:
                write1(dev.register_size,size);
                write1(dev.register_addr,addr);
                write1(dev.register_cmd,READ);
                write1(dev.register_control,GO);

            如果最后一條write1被換到了前幾條語句之前,那么肯定不是我們所期望的,這時候我們可以在最后一條語句之前加入一個memory barrier,強制cpu執行完前面的寫入以后再執行最后一條:

                write1(dev.register_size,size);
                write1(dev.register_addr,addr);
                write1(dev.register_cmd,READ);
                __sync_synchronize();
                write1(dev.register_control,GO);

            memory barrier有幾種類型:
                acquire barrier : 不允許將barrier之后的內存讀取指令移到barrier之前(linux kernel中的wmb())。
                release barrier : 不允許將barrier之前的內存讀取指令移到barrier之后 (linux kernel中的rmb())。
                full barrier    : 以上兩種barrier的合集(linux kernel中的mb())。


            還有兩個函數:

            type __sync_lock_test_and_set (type *ptr, type value, ...)
               將*ptr設為value并返回*ptr操作之前的值。

            void __sync_lock_release (type *ptr, ...)
                 將*ptr置0


            示例程序:

            #include 
            <stdio.h>
            #include 
            <pthread.h>
            #include 
            <stdlib.h>

            static int count = 0;


            void *test_func(void *arg)
            {
                    
            int i=0;
                    
            for(i=0;i<20000;++i){
                            __sync_fetch_and_add(
            &count,1);
                    }
                    
            return NULL;
            }

            int main(int argc, const char *argv[])
            {
                    pthread_t id[
            20];
                    
            int i = 0;

                    
            for(i=0;i<20;++i){
                            pthread_create(
            &id[i],NULL,test_func,NULL);
                    }

                    
            for(i=0;i<20;++i){
                            pthread_join(id[i],NULL);
                    }

                    printf(
            "%d\n",count);
                    
            return 0;
            }

            參考:


            1. http://refspecs.freestandards.org/elf/IA64-SysV-psABI.pdf   section 7.4

            2. http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html#Atomic-Builtins

            posted on 2011-08-11 11:27 老馬驛站 閱讀(707) 評論(0)  編輯 收藏 引用 所屬分類: linux
            亚洲欧洲久久久精品| 欧美麻豆久久久久久中文| 无遮挡粉嫩小泬久久久久久久| 久久人人爽人人人人爽AV| 日本人妻丰满熟妇久久久久久| 日韩精品国产自在久久现线拍 | 国产亚洲美女精品久久久| 亚洲国产精品综合久久网络| 无码精品久久久天天影视| 国内精品久久久久久久亚洲 | 精品免费久久久久久久| 久久这里只有精品视频99| 人妻久久久一区二区三区| 青春久久| 久久久久久极精品久久久 | 精品久久久久久中文字幕| 久久午夜夜伦鲁鲁片免费无码影视| 97久久精品国产精品青草| 欧美亚洲国产精品久久久久| 国产成人综合久久精品尤物| 久久久精品人妻一区二区三区四 | 日韩人妻无码精品久久免费一| 久久精品无码一区二区日韩AV| 久久久无码精品亚洲日韩蜜臀浪潮| 性高朝久久久久久久久久| 99久久伊人精品综合观看| 久久丫精品国产亚洲av不卡| 婷婷久久五月天| 久久综合色老色| 97视频久久久| 99久久国产亚洲综合精品| 四虎国产精品成人免费久久| 精品久久久久久无码国产| 久久精品国产久精国产| 久久久精品免费国产四虎| 国产精品免费福利久久| 99久久免费国产精精品| 丁香狠狠色婷婷久久综合| 国产精品9999久久久久| 久久久精品一区二区三区| 久久精品国产99久久香蕉|