Source code repo: http://github.com/khizmax/libcds/
Download: http://sourceforge.net/projects/libcds/files/
-
+
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CDSLIB_GC_DETAILS_HP_H
/// Set vector size. Uses internally
void size( size_t nSize )
{
- assert( nSize <= capacity() );
+ assert( nSize <= capacity());
m_nSize = nSize;
}
/// Pushes retired pointer to the vector
void push( retired_ptr const& p )
{
- assert( m_nSize < capacity() );
+ assert( m_nSize < capacity());
m_arr[ m_nSize ] = p;
++m_nSize;
}
- /// Checks if the vector is full (size() == capacity() )
+ /// Checks if the vector is full (size() == capacity())
bool isFull() const CDS_NOEXCEPT
{
return m_nSize >= capacity();
char padding[cds::c_nCacheLineSize];
atomics::atomic<unsigned int> m_nSync; ///< dummy var to introduce synchronizes-with relationship between threads
+ char padding2[cds::c_nCacheLineSize];
/// Ctor
- hp_record( const cds::gc::hp::GarbageCollector& HzpMgr ); // inline
+ hp_record( const cds::gc::hp::GarbageCollector& HzpMgr ); // inline
~hp_record()
{}
//@endcond
};
- /// Not enough required Hazard Pointer count
+ /// Not enough Hazard Pointer
class too_many_hazard_ptr : public std::length_error
{
public:
//@cond
too_many_hazard_ptr()
- : std::length_error( "Not enough required Hazard Pointer count" )
+ : std::length_error( "Not enough Hazard Pointer" )
{}
//@endcond
};
~hplist_node()
{
assert( m_idOwner.load( atomics::memory_order_relaxed ) == OS::c_NullThreadId );
- assert( m_bFree.load(atomics::memory_order_relaxed) );
+ assert( m_bFree.load(atomics::memory_order_relaxed));
}
//@endcond
};
public: // Internals for threads
/// Allocates Hazard Pointer GC record. For internal use only
- details::hp_record * alloc_hp_record();
+ details::hp_record* alloc_hp_record();
/// Free HP record. For internal use only
- void free_hp_record( details::hp_record * pRec );
+ void free_hp_record( details::hp_record* pRec );
/// The main garbage collecting function
/**
*/
class ThreadGC
{
- GarbageCollector& m_HzpManager; ///< Hazard Pointer GC singleton
- details::hp_record * m_pHzpRec; ///< Pointer to thread's HZP record
+ GarbageCollector& m_HzpManager; ///< Hazard Pointer GC singleton
+ details::hp_record* m_pHzpRec; ///< Pointer to thread's HZP record
public:
/// Default constructor
ThreadGC()
- : m_HzpManager( GarbageCollector::instance() ),
+ : m_HzpManager( GarbageCollector::instance()),
m_pHzpRec( nullptr )
{}
}
/// Checks if thread GC is initialized
- bool isInitialized() const { return m_pHzpRec != nullptr; }
+ bool isInitialized() const { return m_pHzpRec != nullptr; }
/// Initialization. Repeat call is available
void init()
void fini()
{
if ( m_pHzpRec ) {
- details::hp_record * pRec = m_pHzpRec;
+ details::hp_record* pRec = m_pHzpRec;
m_pHzpRec = nullptr;
m_HzpManager.free_hp_record( pRec );
}
}
/// Initializes HP guard \p guard
- details::hp_guard& allocGuard()
+ details::hp_guard* allocGuard()
{
assert( m_pHzpRec );
return m_pHzpRec->m_hzp.alloc();
}
/// Frees HP guard \p guard
- void freeGuard( details::hp_guard& guard )
+ void freeGuard( details::hp_guard* guard )
{
assert( m_pHzpRec );
m_pHzpRec->m_hzp.free( guard );
/// Initializes HP guard array \p arr
template <size_t Count>
- void allocGuard( details::hp_array<Count>& arr )
+ size_t allocGuard( details::hp_array<Count>& arr )
{
assert( m_pHzpRec );
- m_pHzpRec->m_hzp.alloc( arr );
+ return m_pHzpRec->m_hzp.alloc( arr );
}
/// Frees HP guard array \p arr
/// Places retired pointer \p and its deleter \p pFunc into thread's array of retired pointer for deferred reclamation
template <typename T>
- void retirePtr( T * p, void (* pFunc)(T *) )
+ void retirePtr( T * p, void (* pFunc)(T *))
{
- /*
- union {
- T * p;
- hazard_pointer hp;
- } cast_ptr;
- cast_ptr.p = p;
-
- union{
- void( *pFunc )(T *);
- free_retired_ptr_func hpFunc;
- } cast_func;
- cast_func.pFunc = pFunc;
-
- retirePtr( details::retired_ptr( cast_ptr.hp, cast_func.hpFunc ) );
- */
retirePtr( details::retired_ptr( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc )));
}
{
m_pHzpRec->m_arrRetired.push( p );
- if ( m_pHzpRec->m_arrRetired.isFull() ) {
+ if ( m_pHzpRec->m_arrRetired.isFull()) {
// Max of retired pointer count is reached. Do scan
scan();
}
}
};
- /// Auto hp_guard.
- /**
- This class encapsulates Hazard Pointer guard to protect a pointer against deletion.
- It allocates one HP from thread's HP array in constructor and free the hazard pointer allocated
- in destructor.
- */
- class guard
- {
- details::hp_guard& m_hp ; ///< Hazard pointer guarded
-
- public:
- typedef details::hp_guard::hazard_ptr hazard_ptr ; ///< Hazard pointer type
-
- public:
- /// Allocates HP guard
- guard(); // inline in hp_impl.h
-
- /// Allocates HP guard from \p gc and protects the pointer \p p of type \p T
- template <typename T>
- explicit guard( T * p ); // inline in hp_impl.h
-
- /// Frees HP guard. The pointer guarded may be deleted after this.
- ~guard(); // inline in hp_impl.h
-
- /// Protects the pointer \p p against reclamation (guards the pointer).
- template <typename T>
- T * operator =( T * p )
- {
- return m_hp = p;
- }
-
- //@cond
- std::nullptr_t operator =(std::nullptr_t)
- {
- return m_hp = nullptr;
- }
- //@endcond
-
- /// Get raw guarded pointer
- hazard_ptr get() const
- {
- return m_hp;
- }
- };
-
- /// Auto-managed array of hazard pointers
- /**
- This class is wrapper around cds::gc::hp::details::hp_array class.
- \p Count is the size of HP array
- */
- template <size_t Count>
- class array : public details::hp_array<Count>
- {
- public:
- /// Rebind array for other size \p COUNT2
- template <size_t Count2>
- struct rebind {
- typedef array<Count2> other; ///< rebinding result
- };
-
- public:
- /// Allocates array of HP guard
- array(); // inline in hp_impl.h
-
- /// Frees array of HP guard
- ~array(); //inline in hp_impl.h
- };
-
} // namespace hp
}} // namespace cds::gc
//@endcond
namespace gc { namespace hp { namespace details {
inline retired_vector::retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr )
- : m_arr( HzpMgr.getMaxRetiredPtrCount() ),
+ : m_arr( HzpMgr.getMaxRetiredPtrCount()),
m_nSize(0)
{}
inline hp_record::hp_record( const cds::gc::hp::GarbageCollector& HzpMgr )
- : m_hzp( HzpMgr.getHazardPointerCount() )
+ : m_hzp( HzpMgr.getHazardPointerCount())
, m_arrRetired( HzpMgr )
, m_nSync( 0 )
{}