24 #include <glog/logging.h> 41 template <
typename Tag>
45 std::atomic<Node*> tail_{
nullptr};
46 std::atomic<Node*> head_{
nullptr};
55 template <
typename Func>
58 while (node !=
nullptr) {
59 auto next = node->next_;
74 void push(
Node* node);
94 parent_->
ghead_->splice(*
this);
107 template <
typename Tag>
109 DCHECK(node->
next_ ==
nullptr);
110 static thread_local
TLHead* cache_{
nullptr};
113 auto l = lhead_.get();
115 lhead_.reset(
new TLHead(
this));
123 auto head = cache_->head_.load(std::memory_order_relaxed);
125 node->
next_ =
nullptr;
126 if (cache_->head_.compare_exchange_weak(head, node)) {
127 cache_->tail_.store(node);
131 auto tail = cache_->tail_.load(std::memory_order_relaxed);
134 if (cache_->tail_.compare_exchange_weak(node->
next_, node)) {
142 template <
typename Tag>
144 auto acc = lhead_.accessAllThreads();
146 for (
auto& thr : acc) {
150 list.
splice(*ghead_.wlock());
153 template <
typename Tag>
155 if (other.
head_ !=
nullptr) {
156 DCHECK(other.
tail_ !=
nullptr);
158 DCHECK(other.
tail_ ==
nullptr);
163 DCHECK(tail_ !=
nullptr);
164 DCHECK(head_->next_ ==
nullptr);
165 head_->next_ = other.
tail_;
168 DCHECK(head_ ==
nullptr);
173 other.
head_ =
nullptr;
174 other.
tail_ =
nullptr;
177 template <
typename Tag>
181 auto tail = list.
tail_.load();
std::atomic< Node * > head_
—— Concurrent Priority Queue Implementation ——
void splice(ListHead &other)
folly::ThreadLocalPtr< TLHead, Tag > lhead_
folly::Synchronized< ListHead > ghead_
Encoder::MutableCompressedList list
void collect(ListHead &list)
Future< std::vector< typename std::iterator_traits< InputIterator >::value_type::value_type > > collect(InputIterator first, InputIterator last)
TLHead(ThreadCachedLists *parent)
ThreadCachedLists * parent_
std::atomic< Node * > tail_
folly::Function< void()> parent
folly::Function< void()> cb_