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; }
std::shared_ptr<T> pop() { ++threads_in_pop; // increase counter before doing anything else 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); // extract data from node rather than // coping pointer } try_reclaim(old_head); // reclaim deleted nodes if you can return res; }
std::shared_ptr<T> lock_free_stack<T>::pop() { ++threads_in_pop; //получаем указатель на текущий head Node* old_head = head.load(std::memory_order_seq_cst); //пока old_head не нулевой (стек пустой) && head перенаправлен на следующий Node (compare_exchange_weak) при условии, что на момент обмена head не изменился while (old_head && !head.compare_exchange_weak(old_head, old_head->next)) {} //формируем возвращаемое значение: std::shared_ptr<T> res; //данное по умолчанию if (old_head) { res.swap(old_head->item); //не копируем указатель, а обмениваем данные } try_reclaim(old_head); //вызываем вспомогательный метод return res; }