Porting InterlockedExchange, using GCC intrinsics only

帅比萌擦擦* 提交于 2019-12-12 08:15:40

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!