Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Porting InterlockedExchange, using GCC intrinsics only

Tags:

c

port

gcc

atomic

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).

like image 643
qdii Avatar asked Jan 18 '23 04:01

qdii


1 Answers

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.

like image 129
Damon Avatar answered Jan 30 '23 12:01

Damon