нам нужно доказать, что
_array[current_tail] = item; // push(3)
исключено после того, как соответствует (current_head == current_tail
)
item = _array[current_head]; // pop(3)
завершено.мы можем перезаписать ячейку, только после того, как данные из нее уже скопированы в элемент
_head.load(std::memory_order_acquire) // push(2)
, синхронизированный с
_head.store(increment(current_head), std::memory_order_release); //pop(4)
через упорядочение Release-Acquire:
все записи в память ( pop (3) ), которые произошли до того, как выпуск атомарного хранилища ( pop (4) ) в _head
становятся видимыми побочными эффектами, как толькополучение атомной нагрузки ( push (2) ) завершено на _head
.
, поэтому код производителя после push (2) завершен, гарантированно виден результат pop (3) .это означает, что данные из _array[current_head]
копируются в элемент, и результат этой операции отображается для кода источника после push (2) , поэтому _array[current_head]
уже свободен.
с другой стороны от memory_order_acquire
описание загрузки - до этой загрузки нельзя изменить порядок чтения или записи ( push (3) ) в текущем потоке.так что push (3) будет выполнено уже после push (2) загрузка завершена, но на этом этапе pop (3) уже завершена
item = _array[current_head]; //pop(3)
_head.store(increment(current_head), std::memory_order_release); //pop(4)
-----
_head.load(std::memory_order_acquire); //push(2)
_array[current_tail] = item; //push(3)