Какой порядок памяти использовать в реализации pop() стека связанных списков без блокировки?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Какой порядок памяти использовать в реализации pop() стека связанных списков без блокировки?

Сообщение Anonymous »

Я столкнулся с интересной проблемой: когда дело доходит до навязчивых стеков без блокировки (односвязных списков), похоже, существует консенсус относительно того, как должен выглядеть метод push(). Все поисковые запросы в Интернете/ИИ (и cppreference.com) всегда создают код, написанный следующим образом:

Код: Выделить всё

struct stack
{
struct node { node* next; };

std::atomic head;

void push(node* new_node)
{
new_node->next = head.load(std::memory_order_relaxed);

while (!head.compare_exchange_weak(new_node->next, new_node,
std::memory_order_release,
std::memory_order_relaxed)) {}
}
};
но когда дело доходит до pop(), результаты поиска несовместимы с порядком памяти, например:

Код: Выделить всё

    node* pop()
{
node* p = head_.load(std::memory_order_**acquire**);

while (p && !head_.compare_exchange_weak(p, p->next,
std::memory_order_**acq_rel**,
std::memory_order_**relaxed**));
return p;
}
Я видел различные варианты выделенных параметров (например, расслабление + acq_rel + приобретение или расслабление + приобретение + расслабление). Я понимаю, что на x86 это не имеет значения, но приятно все делать правильно...
Каковы правильные значения трех выделенных параметров? (примечание: я знаю о проблеме ABA и в своем коде решаю(*) ее с помощью помеченных указателей)
*solve = значительно уменьшаю вероятность возникновения :)

Подробнее здесь: https://stackoverflow.com/questions/797 ... ementation
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»