/// Returns singleton instance
static general_instant * instance()
{
- return static_cast<general_instant *>( base_class::instance() );
+ return static_cast<general_instant *>( base_class::instance());
}
/// Checks if the singleton is created and ready to use
public:
/// Retires \p p pointer
/**
- The method calls \ref synchronize to wait for the end of grace period
+ The method calls \p synchronize() to wait for the end of grace period
and calls \p p disposer.
*/
virtual void retire_ptr( retired_ptr& p )
{
synchronize();
- if ( p.m_p ) {
- // TSan ignores atomic_thread_fence in synchronize()
- //CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( p.m_p );
+ if ( p.m_p )
p.free();
- }
}
/// Retires the pointer chain [\p itFirst, \p itLast)
while ( itFirst != itLast ) {
retired_ptr p( *itFirst );
++itFirst;
- if ( p.m_p ) {
- // TSan ignores atomic_thread_fence in synchronize()
- //CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( p.m_p );
+ if ( p.m_p )
p.free();
- }
+ }
+ }
+ }
+
+ /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
+ template <typename Func>
+ void batch_retire( Func e )
+ {
+ retired_ptr p{ e() };
+ if ( p.m_p ) {
+ synchronize();
+ while ( p.m_p ) {
+ retired_ptr pr( p );
+ p = e();
+ pr.free();
}
}
}
/// Waits to finish a grace period
void synchronize()
{
- atomics::atomic_thread_fence( atomics::memory_order_acquire );
- {
- std::unique_lock<lock_type> sl( m_Lock );
- flip_and_wait();
- flip_and_wait();
- }
- atomics::atomic_thread_fence( atomics::memory_order_release );
+ assert( !is_locked());
+ std::unique_lock<lock_type> sl( m_Lock );
+ flip_and_wait();
+ flip_and_wait();
}
//@cond