MCPcopy Create free account
hub / github.com/cameron314/concurrentqueue / enqueue

Method enqueue

concurrentqueue.h:2509–2563  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2507
2508 template<AllocationMode allocMode, typename U>
2509 inline bool enqueue(U&& element)
2510 {
2511 index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed);
2512 index_t newTailIndex = 1 + currentTailIndex;
2513 if ((currentTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) == 0) {
2514 // We reached the end of a block, start a new one
2515 auto head = this->headIndex.load(std::memory_order_relaxed);
2516 assert(!details::circular_less_than<index_t>(currentTailIndex, head));
2517 if (!details::circular_less_than<index_t>(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t>::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) {
2518 return false;
2519 }
2520#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2521 debug::DebugLock lock(mutex);
2522#endif
2523 // Find out where we'll be inserting this block in the block index
2524 BlockIndexEntry* idxEntry;
2525 if (!insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) {
2526 return false;
2527 }
2528
2529 // Get ahold of a new block
2530 auto newBlock = this->parent->ConcurrentQueue::template requisition_block<allocMode>();
2531 if (newBlock == nullptr) {
2532 rewind_block_index_tail();
2533 idxEntry->value.store(nullptr, std::memory_order_relaxed);
2534 return false;
2535 }
2536#ifdef MCDBGQ_TRACKMEM
2537 newBlock->owner = this;
2538#endif
2539 newBlock->ConcurrentQueue::Block::template reset_empty<implicit_context>();
2540
2541 MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element)))) {
2542 // May throw, try to insert now before we publish the fact that we have this new block
2543 MOODYCAMEL_TRY {
2544 new ((*newBlock)[currentTailIndex]) T(std::forward<U>(element));
2545 }
2546 MOODYCAMEL_CATCH (...) {
2547 rewind_block_index_tail();
2548 idxEntry->value.store(nullptr, std::memory_order_relaxed);
2549 this->parent->add_block_to_free_list(newBlock);
2550 MOODYCAMEL_RETHROW;
2551 }
2552 }
2553
2554 // Insert the new block into the index
2555 idxEntry->value.store(newBlock, std::memory_order_relaxed);
2556
2557 this->tailBlock = newBlock;
2558
2559 MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element)))) {
2560 this->tailIndex.store(newTailIndex, std::memory_order_release);
2561 return true;
2562 }
2563 }
2564
2565 // Enqueue
2566 new ((*this->tailBlock)[currentTailIndex]) T(std::forward<U>(element));

Callers

nothing calls this directly

Calls 5

assertClass · 0.85
rewind_block_index_tailFunction · 0.85
MOODYCAMEL_CONSTEXPR_IFFunction · 0.85
loadMethod · 0.45
storeMethod · 0.45

Tested by

no test coverage detected