2013-01-08 45 views
0

我正在編寫一個應用程序,這個應用程序是一個無鎖隊列的實現,將在linux上運行並由編譯器GCC 3.4.2編譯。如何在Linux上定義/寫這些原子操作GCC

的實現是基於以下的原子操作:

__sync_fetch_and_add

__sync_fetch_and_sub

__sync_bool_compare_and_swap

__sync_val_compare_and_swap **

的問題是GCC不具備上述建宏直到GCC 4.1,所以目前我有定義他們自己的彙編語言。但是我對彙編一無所知,任何人都可以給我定義上面的函數嗎?任何幫助將不勝感激。

的更多信息:

/// @brief原子添加A_COUNT通過指出可變a_ptr /// @返回先前已在存儲器 __sync_fetch_and_add

/// @brief值原子substracts A_COUNT由所指的變量a_ptr /// @返回先前已在內存中的值 __sync_fetch_and_sub

/// @brief比較和交換 ///我F * a_ptr的當前值是a_oldVal,然後寫a_newVal成* a_ptr /// @返回true,如果比較成功和a_newVal寫 __sync_bool_compare_and_swap

/// @brief比較和交換 ///如果* a_ptr的當前值是a_oldVal,然後寫入到a_newVal * a_ptr /// @返回的內容* a_ptr操作 __sync_val_compare_and_swap之前(a_ptr,a_oldVal,a_newVal)

+1

如果您升級到現代版本的編譯器,而不是依賴非常非常舊的東西,那麼您將[原子功能](http://en.cppreference.com/w/cpp/atomic)內置到標準C++庫。 –

+0

是的,你是對的!感謝Joachim,但是我爲公司工作,而且它的機器已經很舊了,所以他們不能安裝gcc 4.1,所以我必須自己編寫它們。你有更多的建議嗎? – Steve

+0

您可以用舊的GCC建立一個現代化的GCC,不需要走其他路線。 –

回答

0

(未經測試,可以含有錯別字) :

inline long 
val_compare_and_swap(volatile long *ptr, long old, long _new) { 
    long prev; 
    asm volatile("lock;" 
#if defined(__amd64__) 
       "cmpxchgq %1, %2;" 
#else 
       "cmpxchgl %1, %2;" 
#endif 
       : "=a"(prev) 
       : "q"(_new), "m"(*ptr), "a"(old) 
       : "memory"); 
    return prev; 
} 

inline int 
bool_compare_and_swap(volatile long *ptr, long old, long _new) { 
    return val_compare_and_swap(ptr, old, new) == old; 
} 

inline long 
fetch_and_add(volatile long *ptr, long value) { 
    long prev; 
    do { 
     prev = *ptr; 
    } until (bool_compare_and_swap(ptr, prev, prev + value)); 
    return prev; 
} 

如果您需要使用雙字值而不是單字值的compare_and_swap,請參閱http://src.chromium.org/svn/trunk/src/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.h