MCPcopy Create free account
hub / github.com/dmlc/dmlc-core / dequeue_bulk

Function dequeue_bulk

include/dmlc/concurrentqueue.h:2765–2876  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2763
2764 template<typename It>
2765 size_t dequeue_bulk(It &itemFirst, size_t max) {
2766 auto tail = this->tailIndex.load(std::memory_order_relaxed);
2767 auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed);
2768 auto desiredCount = static_cast<size_t>(tail - (this->dequeueOptimisticCount.load(
2769 std::memory_order_relaxed) - overcommit));
2770 if (details::circular_less_than<size_t>(0, desiredCount)) {
2771 desiredCount = desiredCount < max ? desiredCount : max;
2772 std::atomic_thread_fence(std::memory_order_acquire);
2773
2774 auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount,
2775 std::memory_order_relaxed);
2776 assert(overcommit <= myDequeueCount);
2777
2778 tail = this->tailIndex.load(std::memory_order_acquire);
2779 auto actualCount = static_cast<size_t>(tail - (myDequeueCount - overcommit));
2780 if (details::circular_less_than<size_t>(0, actualCount)) {
2781 actualCount = desiredCount < actualCount ? desiredCount : actualCount;
2782 if (actualCount < desiredCount) {
2783 this->dequeueOvercommit.fetch_add(desiredCount - actualCount,
2784 std::memory_order_release);
2785 }
2786
2787 // Get the first index. Note that since there's guaranteed to be at least actualCount elements, this
2788 // will never exceed tail.
2789 auto firstIndex = this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel);
2790
2791 // Iterate the blocks and dequeue
2792 auto index = firstIndex;
2793 BlockIndexHeader *localBlockIndex;
2794 auto indexIndex = get_block_index_index_for_index(index, localBlockIndex);
2795 do {
2796 auto blockStartIndex = index;
2797 auto endIndex =
2798 (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
2799 endIndex = details::circular_less_than<index_t>(
2800 firstIndex + static_cast<index_t>(actualCount), endIndex) ? firstIndex +
2801 static_cast<index_t>(actualCount)
2802 : endIndex;
2803
2804 auto entry = localBlockIndex->index[indexIndex];
2805 auto block = entry->value.load(std::memory_order_relaxed);
2806 if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T &&, details::deref_noexcept(itemFirst) = std::move(
2807 (*(*block)[index])))) {
2808 while (index != endIndex) {
2809 auto &el = *((*block)[index]);
2810 *itemFirst++ = std::move(el);
2811 el.~T();
2812 ++index;
2813 }
2814 } else {
2815 MOODYCAMEL_TRY {
2816 while (index != endIndex) {
2817 auto &el = *((*block)[index]);
2818 *itemFirst = std::move(el);
2819 ++itemFirst;
2820 el.~T();
2821 ++index;
2822 }

Callers

nothing calls this directly

Calls 2

deref_noexceptFunction · 0.85

Tested by

no test coverage detected