• <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>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            用匯編實現(xiàn)原子操作

             

            原子操作(1) - 用匯編實現(xiàn)原子操作

            最輕量級的鎖”,通常也叫原子操作”,之所以加引號是因為他們在匯編級別并不是原子操作,是用多條指令完成的,這些操作大多都是利用CPU支持的匯編指令.在某些構(gòu)架過時的CPU體系結(jié)構(gòu)上,它們應(yīng)該是用比較重量級的線程內(nèi)鎖實現(xiàn)的吧(我的猜測).

            最常見的原子操作有Compare and Exchange,Self Increase/Decrease等等

            80486 CPU相關(guān)指令:

            LOCK:這是一個指令前綴,在所對應(yīng)的指令操作期間使此指令的目標(biāo)操作數(shù)指定的存儲區(qū)域鎖定,以得到保護(hù)。

            XADD:先交換兩個操作數(shù)的值,再進(jìn)行算術(shù)加法操作。多處理器安全,在80486及以上CPU中支持。

            CMPXCHG:比較交換指令,第一操作數(shù)先和AL/AX/EAX比較,如果相等ZF1,第二操作數(shù)賦給第一操作數(shù),否則ZF0,第一操作數(shù)賦給AL/AX/EAX。多處理器安全,在80486及以上CPU中支持。

            XCHG:交換兩個操作數(shù),其中至少有一個是寄存器尋址.其他寄存器和標(biāo)志位不受影響.

            80486以上都支持這四個操作,因此當(dāng)今幾乎100%CPU都支持這兩個指令,也能由此用標(biāo)準(zhǔn)CC++寫出一系列幾乎可以跨平臺的原子操作函數(shù)和Lock-Free數(shù)據(jù)結(jié)構(gòu)和算法.

            64位平臺也有一系列的相關(guān)指令,當(dāng)然他們也有以上提到的指令,其下的64位原子操作函數(shù)應(yīng)該和32位的分開(要問為什么?我現(xiàn)在告訴你恐怕你印象不深,接著看這一系列吧),而道理完全一樣.因此,不存在跨CPU體系結(jié)構(gòu)的問題)

            原子操作函數(shù):

            由以上提供的幾個匯編指令,我們可以做出以下實現(xiàn),這些都是最常用的原語.

            比較后交換

            long __stdcall CompareExchange(long volatile*Destination,long Exchange,long Comperand)

            {

               __asm

               {

                  mov     ecx, Destination;

                  mov     edx, Exchange;

                  mov     eax, Comperand;

                  lock cmpxchg [ecx], edx;

               }

            }

            交換

            long __stdcall Exchange(long volatile* Target,long Value)

            {

               __asm

               {

                  mov      ecx, Target;

                  mov      edx, Value;

            label:

                  lock cmpxchg [ecx], edx;//

                  jnz      short label;

               }

            }

            自減

            long __stdcall Decrement(long volatile* Addend)

            {

               __asm

               {

                  mov     ecx, Addend;

                  mov     eax, 0FFFFFFFFh;//-1

                  lock xadd [ecx], eax; //-1

                  dec     eax;

               }

            }

            自增

            long __stdcall Increment(long volatile* Addend)

            {

               __asm

               {

                  mov      ecx, Addend;

                  mov      eax, 1;

                  lock xadd [ecx], eax; //

                  inc      eax;

               }

            }

            相加后交換

            long __stdcall ExchangeAdd(long volatile* Addend,long Value)

            {

               __asm

               {

                  mov      ecx, Addend;

                  mov      eax, Value;

                  lock xadd [ecx], eax;

               }

            }

             

            原子操作(2) - 泛型后的原子操作

            32位的數(shù)據(jù)類型有4,但是上面的只支持long,怎么辦?手工hack?太土了,當(dāng)然是C++的大規(guī)模殺傷性武器template.

            同時把幾個不跨平臺的地方抽出來用macro表示.

            目前模板還沒有得到concept的支持,所以只能用boost.type_traits低級的手動判斷,要求只有32位的整數(shù)類型才能實例化這些函數(shù).

            #include

            #include

            #define CALL_METHOD __stdcall

            #define VOLATILE volatile

            template<typename T>

            T CALL_METHOD compare_exchange32(T VOLATILE*Destination,T exchange32,T Comperand)

            {

               BOOST_STATIC_ASSERT(sizeof(T) == 4 && boost::is_integral<T>::value);

               __asm

               {

                  mov     ecx, Destination;

                  mov     edx, exchange32;

                  mov     eax, Comperand;

                  lock cmpxchg [ecx], edx;

               }

            }

            template<typename T>

            T CALL_METHOD exchange32(T VOLATILE* Target,T Value)

            {

               BOOST_STATIC_ASSERT(sizeof(T) == 4 && boost::is_integral<T>::value);

               __asm

               {

                  //     mov    ecx, Target;

                  //     mov    edx, Value;      

                  //label:

                  //     lock   cmpxchg [ecx], edx;//

                  //     jnz    short label;

                  mov      ecx, Target;

                  mov      eax, Value;

                  xchg [ecx],eax;

               }

            }

            template<typename T>

            T CALL_METHOD decrement32(T VOLATILE* Addend)

            {

               BOOST_STATIC_ASSERT(sizeof(T) == 4 && boost::is_integral<T>::value);

               __asm

               {

                  mov     ecx, Addend;

                  mov    eax, 0FFFFFFFFh;//-1

                  lock xadd [ecx], eax; //-1

                  dec     eax;

               }

            }

            template<typename T>

            T CALL_METHOD increment32(T VOLATILE* Addend)

            {

               BOOST_STATIC_ASSERT(sizeof(T) == 4 && boost::is_integral<T>::value);

               __asm

               {

                  mov      ecx, Addend;

                  mov      eax, 1;

                  lock xadd [ecx], eax; //

                  inc      eax;

               }

            }

            template<typename T>

            T CALL_METHOD exchange_add32(T VOLATILE* Addend,T Value)

            {

               BOOST_STATIC_ASSERT(sizeof(T) == 4 && boost::is_integral<T>::value);

               __asm

               {

                  mov      ecx, Addend;

                  mov      eax, Value;

                  lock xadd [ecx], eax;

               }

            }

            原子操作(3) - 原子數(shù)類

            根據(jù)上面的5個函數(shù)就能做出一個原子操作的整數(shù)數(shù)字類,這將是下一節(jié)中,我的最輕量級鎖的基礎(chǔ)和原型,他不依賴于操作系統(tǒng),當(dāng)然,所以你也可以不叫他是鎖,只是一種類似鎖的機(jī)制.

            一切細(xì)節(jié)看源碼中穿插的注釋.

            #ifndef __ATOM_VALUE_H__

            #define __ATOM_VALUE_H__

            #include "atom.hpp"

            #include <boost/static_assert.hpp>

            #include <boost/type_traits.hpp>

            template<typename T>

            class atomic_value32

            {

               //,boost.type_traits來保證是位的整數(shù)類型

               BOOST_STATIC_ASSERT(sizeof(T) == 4 && boost::is_integral<T>::value);

            private:

               volatile T value_;

            public:

               atomic_value32(T v = 0)

                  :value_(v){}

               atomic_value32(atomic_value32& v){//??? 這里留給大家,我不給出源碼了

               }

               //需要這么一個轉(zhuǎn)型符號,因為大部分時候我們將atomic_value32<T>當(dāng)作一個T使用

               operator T(){return exchange_add32(&value_,0);}

               //賦值

               atomic_value32& operator=(T v){exchange32(&value_, v);return *this;}

               atomic_value32& operator=(atomic_value32& v){exchange32(&value_, v);return *this;}

               //比較并交換,好像沒有什么operator與之對應(yīng),就直接拿出來了

               T compare_exchange(T to_exchange, T to_compare)

               {return compare_exchange32<T>(&value_, to_exchange, to_compare);}

               //只提供前置,后置似乎沒什么必要,我也懶得去實現(xiàn)了:)

               T operator++(){return increment32(&value_);}

               T operator--(){return decrement32(&value_);}

               //千萬不能返回引用,因為線程安全考慮,

               T operator+=(T add){return exchange_add32(&value_,add);}

               T operator+=(atomic_value32& add){return exchange_add32(&value_,add);}

               T operator-=(T add){return exchange_add32(&value_,-add);}

               T operator-=(atomic_value32& add){return exchange_add32(&value_,-add);}

               //6個比較符號

               bool operator==(T rhs){return operator T()==rhs;}

               bool operator==(atomic_value32& rhs){return operator T()==rhs.operator T();}

               bool operator<(T rhs){return operator T()<rhs;}

               bool operator<(atomic_value32& rhs){return operator T()<rhs.operator T();}

               bool operator!=(T rhs){return !this->operator ==(rhs);}

               bool operator!=(atomic_value32& rhs){return !this->operator ==(rhs);}

               bool operator>=(T rhs){return !this->operator <(rhs);}

               bool operator>=(atomic_value32& rhs){return !this->operator <(rhs);}

               bool operator>(T rhs){return ((*this)!=(rhs)) && !((*this)<(rhs));}

               bool operator>(atomic_value32& rhs){return ((*this)!=(rhs)) && !((*this)<(rhs));}

               bool operator<=(T rhs){return !((*this)>(rhs));}

               bool operator<=(atomic_value32& rhs){return !((*this)>(rhs));}

            };

            #endif//__ATOM_VALUE_H__

            posted on 2009-10-19 18:45 肥仔 閱讀(8389) 評論(1)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

            評論

            # re: 用匯編實現(xiàn)原子操作  回復(fù)  更多評論   

            推薦文章:[url=http://cjjjs.cn/windows/12342320121020.aspx]原子操作與互斥訪問關(guān)系分析 [/url]
            推薦理由:主要講解原子操作的原理和實現(xiàn)過程,借鑒了數(shù)據(jù)庫系統(tǒng)的事務(wù)來分析。
            2014-12-23 15:00 | wd
            国产亚洲综合久久系列| 久久久久国产精品嫩草影院| 国产精品免费久久| 久久精品国产第一区二区| 国产精品久久久久乳精品爆| 久久久受www免费人成| 最新久久免费视频| 欧美精品久久久久久久自慰| 一本久久久久久久| 国产精品乱码久久久久久软件| 亚洲国产精品久久久天堂| 999久久久免费国产精品播放| 亚洲精品视频久久久| 久久发布国产伦子伦精品 | 久久WWW免费人成—看片| 一本久久a久久精品亚洲| 2021国产成人精品久久| 色综合久久久久综合体桃花网 | 久久精品国产亚洲欧美| 午夜精品久久影院蜜桃| 久久精品无码一区二区无码| 日韩va亚洲va欧美va久久| 久久精品成人免费网站| 久久人人爽人人人人爽AV| 国产精品午夜久久| 成人国内精品久久久久一区| 无码八A片人妻少妇久久| 久久无码精品一区二区三区| 久久久91精品国产一区二区三区| 久久精品国产亚洲av麻豆蜜芽| 久久久久久亚洲精品无码| 精品久久久久久久久久中文字幕| 国内精品九九久久久精品| av无码久久久久久不卡网站| 人人狠狠综合久久88成人| 久久人人爽人人爽人人av东京热| 久久综合九色欧美综合狠狠| 国产福利电影一区二区三区久久老子无码午夜伦不 | 亚洲国产成人久久精品动漫| 99久久er这里只有精品18| 久久天天躁夜夜躁狠狠|