public:
/// Iterator
- typedef retired_vector_impl::iterator iterator;
+ typedef retired_vector_impl::iterator iterator;
/// Constructor
retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) CDS_NOEXCEPT; // inline
/// Internal list of cds::gc::hp::details::hp_record
struct hplist_node : public details::hp_record
{
- hplist_node * m_pNextNode ; ///< next hazard ptr record in list
- atomics::atomic<OS::ThreadId> m_idOwner ; ///< Owner thread id; 0 - the record is free (not owned)
- atomics::atomic<bool> m_bFree ; ///< true if record if free (not owned)
+ hplist_node * m_pNextNode; ///< next hazard ptr record in list
+ atomics::atomic<OS::ThreadId> m_idOwner; ///< Owner thread id; 0 - the record is free (not owned)
+ atomics::atomic<bool> m_bFree; ///< true if record if free (not owned)
hplist_node( const GarbageCollector& HzpMgr )
: hp_record( HzpMgr ),
{
T pRet;
do {
- pRet = assign( nIndex, toGuard.load(atomics::memory_order_acquire) );
- } while ( pRet != toGuard.load(atomics::memory_order_relaxed));
+ pRet = assign( nIndex, toGuard.load(atomics::memory_order_relaxed) );
+ } while ( pRet != toGuard.load(atomics::memory_order_acquire));
return pRet;
}
{
T pRet;
do {
- assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_acquire) ));
- } while ( pRet != toGuard.load(atomics::memory_order_relaxed));
+ assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_relaxed) ));
+ } while ( pRet != toGuard.load(atomics::memory_order_acquire));
return pRet;
}
}
/// Returns max Hazard Pointer count
- size_t max_hazard_count() const
+ static size_t max_hazard_count()
{
return hp::GarbageCollector::instance().getHazardPointerCount();
}
/// Returns max count of thread
- size_t max_thread_count() const
+ static size_t max_thread_count()
{
return hp::GarbageCollector::instance().getMaxThreadCount();
}
/// Returns capacity of retired pointer array
- size_t retired_array_capacity() const
+ static size_t retired_array_capacity()
{
return hp::GarbageCollector::instance().getMaxRetiredPtrCount();
}
static void retire( T * p ) ; // inline in hp_impl.h
/// Get current scan strategy
- scan_type getScanType() const
+ static scan_type getScanType()
{
return static_cast<scan_type>( hp::GarbageCollector::instance().getScanType());
}
/// Set current scan strategy
- void setScanType(
+ static void setScanType(
scan_type nScanType ///< new scan strategy
)
{
details::retired_vector::iterator itRetired = arrRetired.begin();
details::retired_vector::iterator itRetiredEnd = arrRetired.end();
// arrRetired is not a std::vector!
- // clear is just set up item counter to 0, the items is not destroying
+ // clear() is just set up item counter to 0, the items is not destroyed
arrRetired.clear();
std::vector< void * >::iterator itBegin = plist.begin();
// LSB is used for marking pointers that cannot be deleted yet
details::retired_vector::iterator itRetired = pRec->m_arrRetired.begin();
details::retired_vector::iterator itRetiredEnd = pRec->m_arrRetired.end();
- for ( details::retired_vector::iterator it = itRetired; it != itRetiredEnd; ++it ) {
- if ( reinterpret_cast<ptr_atomic_t>(it->m_p) & 1 ) {
+ for ( auto it = itRetired; it != itRetiredEnd; ++it ) {
+ if ( reinterpret_cast<uintptr_t>(it->m_p) & 1 ) {
// found a pointer with LSB bit set - use classic_scan
classic_scan( pRec );
return;
std::sort( itRetired, itRetiredEnd, cds::gc::details::retired_ptr::less );
// Search guarded pointers in retired array
-
- hplist_node * pNode = m_pListHead.load(atomics::memory_order_acquire);
-
- while ( pNode ) {
- for ( size_t i = 0; i < m_nHazardPointerCount; ++i ) {
- void * hptr = pNode->m_hzp[i];
- if ( hptr ) {
- details::retired_ptr dummyRetired;
- dummyRetired.m_p = hptr;
- details::retired_vector::iterator it = std::lower_bound( itRetired, itRetiredEnd, dummyRetired, cds::gc::details::retired_ptr::less );
- if ( it != itRetiredEnd && it->m_p == hptr ) {
- // Mark retired pointer as guarded
- it->m_p = reinterpret_cast<void *>(reinterpret_cast<ptr_atomic_t>(it->m_p ) | 1);
+ hplist_node * pNode = m_pListHead.load( atomics::memory_order_acquire );
+
+ {
+ details::retired_ptr dummyRetired;
+ while ( pNode ) {
+ for ( size_t i = 0; i < m_nHazardPointerCount; ++i ) {
+ void * hptr = pNode->m_hzp[i];
+ if ( hptr ) {
+ dummyRetired.m_p = hptr;
+ details::retired_vector::iterator it = std::lower_bound( itRetired, itRetiredEnd, dummyRetired, cds::gc::details::retired_ptr::less );
+ if ( it != itRetiredEnd && it->m_p == hptr ) {
+ // Mark retired pointer as guarded
+ it->m_p = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(it->m_p) | 1);
+ }
}
}
+ pNode = pNode->m_pNextNode;
}
- pNode = pNode->m_pNextNode;
}
// Move all marked pointers to head of array
- details::retired_vector::iterator itInsert = itRetired;
- for ( details::retired_vector::iterator it = itRetired; it != itRetiredEnd; ++it ) {
- if ( reinterpret_cast<ptr_atomic_t>(it->m_p) & 1 ) {
- it->m_p = reinterpret_cast<void *>(reinterpret_cast<ptr_atomic_t>(it->m_p ) & ~1);
- *itInsert = *it;
- ++itInsert;
- CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_DeferredNode );
- }
- else {
- // Retired pointer may be freed
- DeletePtr( *it );
+ {
+ details::retired_vector::iterator itInsert = itRetired;
+ for ( auto it = itRetired; it != itRetiredEnd; ++it ) {
+ if ( reinterpret_cast<uintptr_t>(it->m_p) & 1 ) {
+ it->m_p = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(it->m_p) & ~1);
+ *itInsert = *it;
+ ++itInsert;
+ CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_DeferredNode );
+ }
+ else {
+ // Retired pointer may be freed
+ DeletePtr( *it );
+ }
}
+ pRec->m_arrRetired.size( itInsert - itRetired );
}
- pRec->m_arrRetired.size( itInsert - itRetired );
}
void GarbageCollector::HelpScan( details::hp_record * pThis )