Атомно уменьшить данные члена союза?

У меня есть структура в союзе с uint64_t, предоставляя доступ к двум int32_t. Я хотел бы уменьшить один из членов структуры атомарно. Я придумал это:

class{

public:

void atomicallyDecrement_B(const int32_t decrementByThisValue){
MyUnion newUnion;
MyStruct currentStruct = _union._data;

do{
const int32_t currentB = currentStruct.b;
const int32_t currentA = currentStruct.a;
const int32_t newB = currentB - decrementByThisValue;

newUnion._data.a = currentA;
newUnion._data.b = newB;
}
while(!std::atomic_compare_exchange_weak(&_union._data, &currentStruct, newUnion._data));
}

private:
struct MyStruct{
int a;
int b;
};

union MyUnion{
MyUnion(){
_data.a = 0;
_data.b = 0;
}

MyStruct _data;
uint64_t _atomic;
} _union;
};

но, похоже, первый аргумент atomic_compare_exchange_weak() должен быть сам атомный тип. Есть ли способ выполнить эту операцию без изменение члена данных uint64_t на std::atomic<uint64_t>?

Я использую GCC 5.2

0

Решение

GCC имеет атомарные операции как встроенные модули. Они описаны на эта страница.

Операция, которую вы ищете

type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)

или же

bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)

Эти встроенные функции выполняют атомное сравнение и обмен. То есть, если текущее значение * ptr равно oldval, тогда пишите newval в * ptr.

Для пользователей Windows соответствующая возможность

LONG __cdecl InterlockedCompareExchange(
_Inout_ LONG volatile *Destination,
_In_    LONG          Exchange,
_In_    LONG          Comparand
);

Который описан Вот

Пример использования bool-формы встроенного gcc:

do{
int oldVal = protectedVal;
int newVal = someFunction(oldVal);
} while (__sync_bool_compare_and_swap(&protectedVal, oldVal, newVal);
1

Другие решения

Да, есть способы сделать это. Вы можете использовать атомарные встроенные функции GCC, найденные здесь: https://gcc.gnu.org/onlinedocs/gcc-4.4.5/gcc/Atomic-Builtins.html или вы можете использовать элементарные функции, предоставляемые вашей ОС. Третий вариант — использовать атомарные инструкции по сборке.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector