Я хочу атомарно поменять две большие области памяти, определенные как структура VValue
. Поскольку размер структуры больше, чем long
, отсутствует архитектурная поддержка для прямого сравнения и обмена двух структур. Однако один из способов - поменять местами указатели двух структур и косвенно поменять местами памяти.
Ниже мой код, который должен поменять местами oldValue
с b
. Встроенная функция сравнения и обмена используется внутри do-while
l oop, чтобы убедиться, что значение oldValue
не изменилось, возможно, другими потоками во время обмена (этот фрагмент кода является упрощенной версией более сложный своп с другими условиями. Условия для краткости удалены.
template<typename A, typename B, typename C, typename D>
struct VStructType{
A a;
B b;
C c;
D d;
VStructType () {
;
}
VStructType (A a, B b, C c, D d) {
this->a = a;
this->b = b;
this->c = c;
this->d = d;
}
};
typedef VStructType<uint32_t,uint32_t,uint32_t,uint32_t> VValue;
bool swap(VValue* oldValue, VValue b)
{
bool r = 0;
VValue* c;
VValue *w = new VValue();
do{
c = oldValue;
w->a = b.a;
w->b = b.b;
w->c = b.c;
w->d = b.d;
} while (!(r = __sync_bool_compare_and_swap(&oldValue, c, w)));
return r;
}
int main()
{
VValue oldValue = VValue(1,2,3,4);
VValue b = VValue(10,12,2,8);
swap(&oldValue, b);
}
Проблема в том, что после свопинга внутри функции свопинга значение oldValue
изменяется на новое, но после При возврате из функции подкачки oldValue
не изменяется. Похоже, что ссылка на oldValue
является временной ссылкой, и когда происходит свопинг, она меняет только новую ссылку, а не фактический указатель на oldValue
. Причина, по которой ссылка передается функции __sync_bool_compare_and_swap
, заключается в том, что первый аргумент является указателем на переменную, значение которой нужно сравнить с .
Мои вопросы:
1) Есть ли способ передать указатель указателя oldValue
непосредственно в функцию __sync_bool_compare_and_swap
?
2) Это Подход возможен, когда oldValue
является элементом в массиве?
Примечание: используйте g++ -latomic -std=gnu++11
для компиляции.