ywkaras commented on a change in pull request #7362:
URL: https://github.com/apache/trafficserver/pull/7362#discussion_r534617265
##########
File path: src/tscore/ink_queue.cc
##########
@@ -66,6 +67,139 @@
#define DEADBEEF
#endif
+namespace
+{
+// Atomic stack, implemented as a linked list. The link is stored at the
offset (given by the base class
+// member function link_offset() ) within each stack element. The stack is
empty when the head pointer is null.
+//
+template <class Base> class AtomicStack_ : private Base
+{
+public:
+ template <typename... Args>
+ AtomicStack_(std::atomic<void *> &head, Args &&... args) :
Base(std::forward<Args>(args)...), _head(head)
+ {
+ }
+
+ // Return reference to "next" pointer within a stack element.
+ //
+ void *&
+ link(void *elem)
+ {
+ return *reinterpret_cast<void **>(static_cast<char *>(elem) +
Base::link_offset());
+ }
+
+ // Splice this stack to the tail of another stack (whose head and tail is
given by the parameters).
+ // Returns previous head.
+ //
+ void *
+ splice_to_top(void *other_head, void *other_tail)
+ {
+ void *curr_head = _head;
+
+ do {
+ link(other_tail) = curr_head;
+
+ } while (!_head.compare_exchange_weak(curr_head, other_head));
+
+ return curr_head;
+ }
+
+ // Returns previous head.
+ //
+ void *
+ push(void *elem)
+ {
+ return splice_to_top(elem, elem);
+ }
+
+ template <bool All_elements = false>
+ void *
+ pop()
+ {
+ void *curr_head = _head, *new_head;
+
+ do {
+ if (!curr_head) {
+ // Stack is empty.
+ //
+ return nullptr;
+ }
+
+ new_head = All_elements ? nullptr : link(curr_head);
+
+ } while (!_head.compare_exchange_weak(curr_head, new_head));
+
+ return curr_head;
+ }
+
+ // WARNING: This is not safe, unless no other thread is popping or removing.
+ //
+ bool
+ remove(void *item)
+ {
+ void *p = item;
+ void *p2 = link(item);
+
+ if (_head.compare_exchange_strong(p, p2)) {
+ // Item was at the top of the stack.
+ //
+ return true;
+ }
+ if (p) {
+ p2 = link(p);
+
+ while (p2 != item) {
+ if (nullptr == p2) {
+ // Item not in stack.
+ //
+ return false;
+ }
+ p = p2;
+ p2 = link(p2);
+ }
+ link(p) = link(p2);
+ return true;
+ }
+ // Stack is empty.
+ //
+ return false;
+ }
+
+private:
+ std::atomic<void *> &_head;
+};
+
+class AtomicStackBaseNoOffset
+{
+protected:
+ static constexpr size_t
+ link_offset()
+ {
+ return 0;
+ }
+};
+
+using AtomicStackNoOffset = AtomicStack_<AtomicStackBaseNoOffset>;
+
+class AtomicStackBaseWithOffset
+{
+protected:
+ AtomicStackBaseWithOffset(size_t offset) : _link_offset(offset) {}
+
+ size_t
+ link_offset() const
+ {
+ return (_link_offset);
Review comment:
remove paretheses
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]