2011-11-25 42 views
4

Windows API提供了InterlockedExchange,它以原子方式在內存中設置一個值。只使用GCC內在函數,我想創建一個等價的函數。設置該值然後調用內存屏障就足夠了(請參閱下面的代碼)?移植InterlockedExchange,僅使用GCC內部函數

template <typename T> 
T InterlockedExchange(volatile T& _data, T _value) 
{ 
    const T oldValue = _data; 
    _data = _value; 
    __sync_synchronize(); 
    return oldValue; 
} 

謝謝。

編輯:建議片段是不是一個正確的解決問題的方法,因爲它顯然不是原子的(不過,好了,我不得不至少給一試)。

+0

你聲明'_data'參數作爲參考,但稍後使用指針解引用來訪問它。 –

+0

已更改,謝謝:) – qdii

回答

9

使用 __sync_val_compare_and_swap __sync_lock_test_and_set而不是__sync_synchronize

這與InterlockedExchange具有完全相同的功能。

像這樣的東西(未測試的代碼!):

template<typename T> T InterlockedExchange(T& data, T& new_val) 
{ 
    return __sync_lock_test_and_set(&data, new_val); 
} 

編輯:
愛,我讀錯了,你想InterlockedExchange,不InterlockedCompareExchange ......所以這是__sync_lock_test_and_set(該名稱是誤導英特爾人,但這正是你想要的)。
請參閱here,頁面底部。

+2

請注意'__sync_lock_test_and_set()'只具有Acquire語義,所以這隻相當於'InterlockedExchangeAcquire()'。您需要爲完整的內存屏障添加一個__sync_synchronize();',相當於'InterlockedExchange()'。 – caf

0

您提出的示例並不等同,因爲它不是原子的。執行你的函數的兩個賽跑線程都可以檢索相同的舊值,其中一個新值是「丟失」的。

+0

的確,我會盡快找到解決方案:) – qdii