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

Method help_scan

extern/libcds/src/dhp.cpp:436–491  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

434 }
435
436 CDS_EXPORT_API void smr::help_scan( thread_data* pThis )
437 {
438 assert( static_cast<thread_record*>( pThis )->thread_id_.load( atomics::memory_order_relaxed ) == cds::OS::get_current_thread_id());
439 CDS_HPSTAT( ++pThis->help_scan_call_count_ );
440
441 const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId;
442 const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id();
443 for ( thread_record* hprec = thread_list_.load( atomics::memory_order_acquire ); hprec; hprec = hprec->next_ )
444 {
445 if ( hprec == static_cast<thread_record*>( pThis ))
446 continue;
447
448 // If free_ == true then hprec->retired_ is empty - we don't need to see it
449 if ( hprec->free_.load( atomics::memory_order_acquire )) {
450 CDS_TSAN_ANNOTATE_IGNORE_READS_BEGIN;
451 assert( hprec->retired_.empty());
452 CDS_TSAN_ANNOTATE_IGNORE_READS_END;
453 continue;
454 }
455
456 // Owns hprec
457 // Several threads may work concurrently so we use atomic technique
458 {
459 cds::OS::ThreadId curOwner = hprec->thread_id_.load( atomics::memory_order_relaxed );
460 if ( curOwner == nullThreadId ) {
461 if ( !hprec->thread_id_.compare_exchange_strong( curOwner, curThreadId, atomics::memory_order_acquire, atomics::memory_order_relaxed ))
462 continue;
463 }
464 else
465 continue;
466 }
467
468 // We own the thread record successfully. Now, we can see whether it has retired pointers.
469 // If it has ones then we move them to pThis that is private for current thread.
470 hprec->sync();
471 retired_array& src = hprec->retired_;
472 retired_array& dest = pThis->retired_;
473
474 for ( retired_block* block = src.list_head_; block; block = block->next_ ) {
475 retired_ptr* last = block == src.current_block_ ? src.current_cell_ : block->last();
476 for ( retired_ptr* p = block->first(); p != last; ++p ) {
477 if ( !dest.push( *p ))
478 scan( pThis );
479 }
480
481 if ( block == src.current_block_ )
482 break;
483 }
484
485 src.fini();
486 hprec->free_.store( true, atomics::memory_order_relaxed );
487 hprec->thread_id_.store( nullThreadId, atomics::memory_order_release );
488 }
489
490 scan( pThis );
491 }
492
493 CDS_EXPORT_API void smr::statistics( stat& st )

Callers

nothing calls this directly

Calls 12

assertClass · 0.85
scanFunction · 0.85
get_current_thread_idFunction · 0.50
loadMethod · 0.45
emptyMethod · 0.45
syncMethod · 0.45
lastMethod · 0.45
firstMethod · 0.45
pushMethod · 0.45
finiMethod · 0.45
storeMethod · 0.45

Tested by

no test coverage detected