MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / enqueue

Method enqueue

extern/libcds/cds/intrusive/segmented_queue.h:462–515  ·  view source on GitHub ↗

Inserts a new element at last segment of the queue

Source from the content-addressed store, hash-verified

460
461 /// Inserts a new element at last segment of the queue
462 bool enqueue( value_type& val )
463 {
464 // LSB is used as a flag in marked pointer
465 assert( (reinterpret_cast<uintptr_t>( &val ) & 1) == 0 );
466
467 typename gc::Guard segmentGuard;
468 segment * pTailSegment = m_SegmentList.tail( segmentGuard );
469 if ( !pTailSegment ) {
470 // no segments, create the new one
471 pTailSegment = m_SegmentList.create_tail( pTailSegment, segmentGuard );
472 assert( pTailSegment );
473 }
474
475 permutation_generator gen( quasi_factor());
476
477 // First, increment item counter.
478 // We sure that the item will be enqueued
479 // but if we increment the counter after inserting we can get a negative counter value
480 // if dequeuing occurs before incrementing (enqueue/dequeue race)
481 ++m_ItemCounter;
482
483 while ( true ) {
484 CDS_DEBUG_ONLY( size_t nLoopCount = 0);
485 do {
486 typename permutation_generator::integer_type i = gen;
487 CDS_DEBUG_ONLY( ++nLoopCount );
488 if ( pTailSegment->cells[i].data.load(memory_model::memory_order_relaxed).all()) {
489 // Cell is not empty, go next
490 m_Stat.onPushPopulated();
491 }
492 else {
493 // Empty cell found, try to enqueue here
494 regular_cell nullCell;
495 if ( pTailSegment->cells[i].data.compare_exchange_strong( nullCell, regular_cell( &val ),
496 memory_model::memory_order_release, atomics::memory_order_relaxed ))
497 {
498 // Ok to push item
499 m_Stat.onPush();
500 return true;
501 }
502 assert( nullCell.ptr());
503 m_Stat.onPushContended();
504 }
505 } while ( gen.next());
506
507 assert( nLoopCount == quasi_factor());
508
509 // No available position, create a new segment
510 pTailSegment = m_SegmentList.create_tail( pTailSegment, segmentGuard );
511
512 // Get new permutation
513 gen.reset();
514 }
515 }
516
517 /// Removes an element from first segment of the queue and returns it
518 /**

Callers

nothing calls this directly

Calls 12

assertClass · 0.85
tailMethod · 0.80
create_tailMethod · 0.80
allMethod · 0.80
loadMethod · 0.45
onPushPopulatedMethod · 0.45
onPushMethod · 0.45
ptrMethod · 0.45
onPushContendedMethod · 0.45
nextMethod · 0.45
resetMethod · 0.45

Tested by

no test coverage detected