//@cond
template <typename ThreadData>
struct thread_list_record {
- ThreadData * m_pNext ; ///< Next item in thread list
- atomics::atomic<OS::ThreadId> m_idOwner ; ///< Owner thread id; 0 - the record is free (not owned)
+ ThreadData * m_pNext; ///< Next item in thread list
+ atomics::atomic<OS::ThreadId> m_idOwner; ///< Owner thread id; 0 - the record is free (not owned)
thread_list_record()
: m_pNext( nullptr )
template <typename RCUtag, class Alloc = CDS_DEFAULT_ALLOCATOR >
class thread_list {
public:
- typedef thread_data<RCUtag> thread_record;
- typedef cds::details::Allocator< thread_record, Alloc > allocator_type;
+ typedef thread_data<RCUtag> thread_record;
+ typedef cds::details::Allocator< thread_record, Alloc > allocator_type;
private:
- atomics::atomic<thread_record *> m_pHead;
+ atomics::atomic<thread_record *> m_pHead;
public:
thread_list()
cds::OS::ThreadId const nullThreadId = cds::OS::c_NullThreadId;
cds::OS::ThreadId const curThreadId = cds::OS::get_current_thread_id();
- // First try to reuse a retired (non-active) HP record
+ // First, try to reuse a retired (non-active) HP record
for ( pRec = m_pHead.load( atomics::memory_order_acquire ); pRec; pRec = pRec->m_list.m_pNext ) {
cds::OS::ThreadId thId = nullThreadId;
if ( !pRec->m_list.m_idOwner.compare_exchange_strong( thId, curThreadId, atomics::memory_order_seq_cst, atomics::memory_order_relaxed ) )
pRec = allocator_type().New();
pRec->m_list.m_idOwner.store( curThreadId, atomics::memory_order_relaxed );
- atomics::atomic_thread_fence( atomics::memory_order_release );
-
thread_record * pOldHead = m_pHead.load( atomics::memory_order_acquire );
do {
pRec->m_list.m_pNext = pOldHead;
CDS_DEBUG_ONLY( cds::OS::ThreadId const nullThreadId = cds::OS::c_NullThreadId; )
CDS_DEBUG_ONLY( cds::OS::ThreadId const mainThreadId = cds::OS::get_current_thread_id() ;)
- thread_record * p = m_pHead.exchange( nullptr, atomics::memory_order_seq_cst );
+ thread_record * p = m_pHead.exchange( nullptr, atomics::memory_order_acquire );
while ( p ) {
thread_record * pNext = p->m_list.m_pNext;
/// 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 )
/// Waits to finish a grace period
void synchronize()
{
+ assert( !is_locked());
std::unique_lock<lock_type> sl( m_Lock );
flip_and_wait();
flip_and_wait();