# ifdef CDS_DISABLE_SMR_EXCEPTION
assert( !full());
# else
- if ( full() )
+ if ( full())
CDS_THROW_EXCEPTION( not_enought_hazard_ptr());
# endif
guard* g = free_head_;
void free( guard* g ) CDS_NOEXCEPT
{
- assert( g >= array_ && g < array_ + capacity() );
+ assert( g >= array_ && g < array_ + capacity());
if ( g ) {
g->clear();
guard& operator[]( size_t idx )
{
- assert( idx < capacity() );
+ assert( idx < capacity());
return array_[idx];
}
size_t size() const CDS_NOEXCEPT
{
- return current_ - retired_;
+ return current_.load(atomics::memory_order_relaxed) - retired_;
}
bool push( retired_ptr&& p ) CDS_NOEXCEPT
{
- *current_ = p;
+ retired_ptr* cur = current_.load( atomics::memory_order_relaxed );
+ *cur = p;
CDS_HPSTAT( ++retire_call_count_ );
- return ++current_ < last_;
+ current_.store( cur + 1, atomics::memory_order_relaxed );
+ return cur + 1 < last_;
}
retired_ptr* first() const CDS_NOEXCEPT
retired_ptr* last() const CDS_NOEXCEPT
{
- return current_;
+ return current_.load( atomics::memory_order_relaxed );
}
void reset( size_t nSize ) CDS_NOEXCEPT
{
- current_ = first() + nSize;
+ current_.store( first() + nSize, atomics::memory_order_relaxed );
+ }
+
+ void interthread_clear()
+ {
+ current_.exchange( first(), atomics::memory_order_acq_rel );
}
bool full() const CDS_NOEXCEPT
{
- return current_ == last_;
+ return current_.load( atomics::memory_order_relaxed ) == last_;
}
static size_t calc_array_size( size_t capacity )
}
private:
- retired_ptr* current_;
- retired_ptr* const last_;
- retired_ptr* const retired_;
+ atomics::atomic<retired_ptr*> current_;
+ retired_ptr* const last_;
+ retired_ptr* const retired_;
# ifdef CDS_ENABLE_HPSTAT
public:
size_t retire_call_count_;
/// \p smr::scan() strategy
enum scan_type {
- classic, ///< classic scan as described in Michael's works (see smr::classic_scan() )
- inplace ///< inplace scan without allocation (see smr::inplace_scan() )
+ classic, ///< classic scan as described in Michael's works (see smr::classic_scan())
+ inplace ///< inplace scan without allocation (see smr::inplace_scan())
};
//@cond
# ifdef CDS_DISABLE_SMR_EXCEPTION
assert( false ); // not enough hazard ptr
# else
- CDS_THROW_EXCEPTION( not_enought_hazard_ptr() );
+ CDS_THROW_EXCEPTION( not_enought_hazard_ptr());
# endif
}
}
static CDS_EXPORT_API void detach_thread();
/// Get internal statistics
- void statistics( stat& st );
+ CDS_EXPORT_API void statistics( stat& st );
public: // for internal use only
/// The main garbage collecting function
@warning Can throw \p too_many_hazard_ptr_exception if internal hazard pointer objects are exhausted.
*/
Guard()
- : guard_( hp::smr::tls()->hazards_.alloc() )
+ : guard_( hp::smr::tls()->hazards_.alloc())
{}
/// Initilalizes an unlinked guard i.e. the guard contains no hazard pointer. Used for move semantics support
template <typename T>
T * assign( size_t nIndex, T * p )
{
- assert( nIndex < capacity() );
+ assert( nIndex < capacity());
guards_.set( nIndex, p );
hp::smr::tls()->sync();
template <typename T>
T * get( size_t nIndex ) const
{
- assert( nIndex < capacity() );
+ assert( nIndex < capacity());
return guards_[nIndex]->template get_as<T>();
}
\p func is a disposer: when \p p can be safely removed, \p func is called.
*/
template <typename T>
- static void retire( T * p, void( *func )( T * ))
+ static void retire( T * p, void( *func )( void * ))
{
hp::thread_data* rec = hp::smr::tls();
if ( !rec->retired_.push( hp::retired_ptr( p, func )))
The function clears \p st before gathering statistics.
@note Internal statistics is available only if you compile
- \p libcds and your program with \p -DCDS_ENABLE_HPSTAT key.
+ \p libcds and your program with \p -DCDS_ENABLE_HPSTAT.
*/
static void statistics( stat& st )
{
and can be accessible after destructing the global \p %HP object.
@note Internal statistics is available only if you compile
- \p libcds and your program with \p -DCDS_ENABLE_HPSTAT key.
+ \p libcds and your program with \p -DCDS_ENABLE_HPSTAT.
Usage:
\code
}
\endcode
*/
- static stat const& postmortem_statistics();
+ CDS_EXPORT_API static stat const& postmortem_statistics();
};
}} // namespace cds::gc