MCPcopy Create free account
hub / github.com/danoon2/Boxedwine / enqueue

Method enqueue

source/util/concurrentqueue.h:2487–2541  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2485
2486 template<AllocationMode allocMode, typename U>
2487 inline bool enqueue(U&& element)
2488 {
2489 index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed);
2490 index_t newTailIndex = 1 + currentTailIndex;
2491 if ((currentTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) == 0) {
2492 // We reached the end of a block, start a new one
2493 auto head = this->headIndex.load(std::memory_order_relaxed);
2494 assert(!details::circular_less_than<index_t>(currentTailIndex, head));
2495 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))) {
2496 return false;
2497 }
2498#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2499 debug::DebugLock lock(mutex);
2500#endif
2501 // Find out where we'll be inserting this block in the block index
2502 BlockIndexEntry* idxEntry;
2503 if (!insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) {
2504 return false;
2505 }
2506
2507 // Get ahold of a new block
2508 auto newBlock = this->parent->ConcurrentQueue::template requisition_block<allocMode>();
2509 if (newBlock == nullptr) {
2510 rewind_block_index_tail();
2511 idxEntry->value.store(nullptr, std::memory_order_relaxed);
2512 return false;
2513 }
2514#ifdef MCDBGQ_TRACKMEM
2515 newBlock->owner = this;
2516#endif
2517 newBlock->ConcurrentQueue::Block::template reset_empty<implicit_context>();
2518
2519 MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element)))) {
2520 // May throw, try to insert now before we publish the fact that we have this new block
2521 MOODYCAMEL_TRY {
2522 new ((*newBlock)[currentTailIndex]) T(std::forward<U>(element));
2523 }
2524 MOODYCAMEL_CATCH (...) {
2525 rewind_block_index_tail();
2526 idxEntry->value.store(nullptr, std::memory_order_relaxed);
2527 this->parent->add_block_to_free_list(newBlock);
2528 MOODYCAMEL_RETHROW;
2529 }
2530 }
2531
2532 // Insert the new block into the index
2533 idxEntry->value.store(newBlock, std::memory_order_relaxed);
2534
2535 this->tailBlock = newBlock;
2536
2537 MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element)))) {
2538 this->tailIndex.store(newTailIndex, std::memory_order_release);
2539 return true;
2540 }
2541 }
2542
2543 // Enqueue
2544 new ((*this->tailBlock)[currentTailIndex]) T(std::forward<U>(element));

Callers

nothing calls this directly

Calls 4

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

Tested by

no test coverage detected