问题
Windows API offers InterlockedExchange
, which sets a value in memory atomically. Using only GCC intrinsics, I’d like to create an equivalent of that function. Would setting the value and then calling a memory barrier be sufficient (see the code below) ?
template <typename T>
T InterlockedExchange(volatile T& _data, T _value)
{
const T oldValue = _data;
_data = _value;
__sync_synchronize();
return oldValue;
}
Thank you.
EDIT: The proposed snippet is NOT a correct solution to the problem, as it is clearly not atomic (but, well, I had to give a try at least).
回答1:
Use __sync_val_compare_and_swap
__sync_lock_test_and_set
, not __sync_synchronize
.
This has exactly the same function as InterlockedExchange.
Something like this (untested code!):
template<typename T> T InterlockedExchange(T& data, T& new_val)
{
return __sync_lock_test_and_set(&data, new_val);
}
EDIT:
Oi, I read wrong, you wanted InterlockedExchange, not InterlockedCompareExchange ... so that is __sync_lock_test_and_set
(the name is a misleading Intel-nomer, but it's exactly what you want).
See here, bottom of the page.
回答2:
Your proposed example is not equivalent, because it is not atomic. Two racing threads executing your function can both retrieve the same old value, with one of the new values being "lost".
来源:https://stackoverflow.com/questions/8268243/porting-interlockedexchange-using-gcc-intrinsics-only