#ifndef ptrcompression_h #define ptrcompression_h #include #include #include template class stack { public: ~stack() { while (pop()); } void push(T t) { node *p = new node{pointer(nullptr, 0), t}; pointer old_head = head.load(std::memory_order_relaxed); do { p->next = old_head; } while (!head.compare_exchange_weak( old_head, pointer(p, old_head.get_tag() + 1), std::memory_order_release, std::memory_order_relaxed)); } std::optional pop() { while (true) { pointer old_head = head.load(std::memory_order_acquire); if (old_head) { pointer new_head = pointer(old_head->next.get_ptr(), old_head.get_tag() + 1); if (head.compare_exchange_weak(old_head, new_head, std::memory_order_acquire, std::memory_order_relaxed)) { T data = old_head->data; delete old_head.get_ptr(); return std::optional(data); } } else { return std::nullopt; } } } private: struct node; using pointer = typename boost::lockfree::detail::tagged_ptr; struct node { pointer next; T data; }; std::atomic head{pointer(nullptr, 0)}; }; #endif // ptrcompression_h // #include // void push(T t) // { // node *p = new node{pointer(nullptr, 0), t}; // pointer old_head = head.load(std::memory_order_relaxed); // do // { // p->next = old_head; // } while (!head.compare_exchange_weak( // old_head, pointer(p, old_head.get_tag() + 1), // std::memory_order_release, std::memory_order_relaxed)); // ANNOTATE_HAPPENS_BEFORE(&head); // ← publicamos el nodo // } // std::optional pop() // { // while (true) // { // pointer old_head = head.load(std::memory_order_acquire); // if (old_head) // { // pointer new_head = pointer(old_head->next.get_ptr(), // old_head.get_tag() + 1); // if (head.compare_exchange_weak(old_head, new_head, // std::memory_order_acquire, std::memory_order_relaxed)) // { // ANNOTATE_HAPPENS_AFTER(&head); // ← consumimos el nodo // T data = old_head->data; // delete old_head.get_ptr(); // return std::optional(data); // } // } // else // { // return std::nullopt; // } // } // }