Сбор мусора в книге "С++ Concurrency in Action"

Книга Вильямса оказалась сложнейшей из всех,что я читал. Вопрос у меня по реализации сбора мусора в lock-free stack.

Была проблема удаления нод в структуре, при доступе нескольких потоков к методу pop(). Автор реализует подсчёт количества потоков,которые находятся в методе,и добавляет метод try_reclaim(node* old_head), из-за реализации которого я и решил впервые в жизни задать здесь вопрос.

template<typename T>
class lock_free_stack
{
private:
  std::atomic<unsigned> threads_in_pop;
  void try_reclaim(node* old_head);

 struct node
 {
  std::shared_ptr<T> data;
  node* next;
  node(T const& data_):
  data(std::make_shared<T>(data_))
   {}
 };
 std::atomic<node*> head;
 std::atomic<node*> to_be_deleted;

public:
 void push(T const& data)
 {
  node* const new_node=new node(data);
  new_node->next=head.load();
  while(!head.compare_exchange_weak(new_node->next,new_node));
 }

 std::shared_ptr<T> pop()
 {
  ++threads_in_pop;
  node* old_head=head.load();
  while(old_head &&
  !head.compare_exchange_weak(old_head,old_head->next));
  std::shared_ptr<T> res;
  if(old_head)
  {
    res.swap(old_head->data);
  }
  try_reclaim(old_head);
  return res;
 }
};

void try_reclaim(node* old_head)
{
 if(threads_in_pop==1)
 {
   node* nodes_to_delete=to_be_deleted.exchange(nullptr);
   if(!--threads_in_pop)
   {
    delete_nodes(nodes_to_delete);
   }
   else if(nodes_to_delete)
   {
    chain_pending_nodes(nodes_to_delete);
   }
 }
}

Основной вопрос по проверке на if(threads_in_pop==1) и if(!--threads_in_pop), ведь даже не смотря на то,что эта переменная атомарная, никто не гарантирует,что во время следующего блока кода - она не измениться другим потоком,и вызов метода delete_nodes() станет не безопасным.


Ответы (0 шт):