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

Method scan

extern/libcds/src/dhp.cpp:375–434  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

373 } // namespace
374
375 CDS_EXPORT_API void smr::scan( thread_data* pThreadRec )
376 {
377 thread_record* pRec = static_cast<thread_record*>( pThreadRec );
378 pRec->sync();
379
380 CDS_HPSTAT( ++pRec->scan_call_count_ );
381
382 hp_vector plist;
383 size_t plist_size = last_plist_size_.load( std::memory_order_relaxed );
384 plist.reserve( plist_size );
385
386 // Stage 1: Scan HP list and insert non-null values in plist
387 thread_record* pNode = thread_list_.load( atomics::memory_order_acquire );
388 while ( pNode ) {
389 if ( pNode->thread_id_.load( std::memory_order_relaxed ) != cds::OS::c_NullThreadId ) {
390 copy_hazards( plist, pNode->hazards_.array_, pNode->hazards_.initial_capacity_ );
391
392 for ( guard_block* block = pNode->hazards_.extended_list_.load( atomics::memory_order_acquire );
393 block;
394 block = block->next_block_ )
395 {
396 copy_hazards( plist, block->first(), defaults::c_extended_guard_block_size );
397 }
398 }
399
400 pNode = pNode->next_;
401 }
402
403 // Store plist size for next scan() call (vector reallocation optimization)
404 if ( plist.size() > plist_size )
405 last_plist_size_.compare_exchange_weak( plist_size, plist.size(), std::memory_order_relaxed, std::memory_order_relaxed );
406
407 // Sort plist to simplify search in
408 std::sort( plist.begin(), plist.end());
409
410 // Stage 2: Search plist
411 size_t free_count = 0;
412 size_t retired_count = 0;
413 retired_block* last_block = pRec->retired_.current_block_;
414 retired_ptr* last_block_cell = pRec->retired_.current_cell_;
415
416 pRec->retired_.current_block_ = pRec->retired_.list_head_;
417 pRec->retired_.current_cell_ = pRec->retired_.current_block_->first();
418
419 for ( retired_block* block = pRec->retired_.list_head_; block; block = block->next_ ) {
420 bool const end_block = block == last_block;
421 size_t const size = end_block ? last_block_cell - block->first() : retired_block::c_capacity;
422
423 retired_count += retired_block::c_capacity;
424 free_count += retire_data( plist, pRec->retired_, block, size );
425
426 if ( end_block )
427 break;
428 }
429 CDS_HPSTAT( pRec->free_call_count_ += free_count );
430
431 // If the count of freed elements is too small, increase retired array
432 if ( free_count < retired_count / 4 && last_block == pRec->retired_.list_tail_ && last_block_cell == last_block->last())

Callers

nothing calls this directly

Calls 13

copy_hazardsFunction · 0.85
sortClass · 0.85
retire_dataFunction · 0.70
syncMethod · 0.45
loadMethod · 0.45
reserveMethod · 0.45
firstMethod · 0.45
sizeMethod · 0.45
compare_exchange_weakMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
lastMethod · 0.45

Tested by

no test coverage detected