3 #ifndef CDSLIB_URCU_GENERAL_BUFFERED_H
4 #define CDSLIB_URCU_GENERAL_BUFFERED_H
6 #include <cds/urcu/details/gpb.h>
8 namespace cds { namespace urcu {
10 /// User-space general-purpose RCU with deferred buffered reclamation
11 /** @anchor cds_urcu_general_buffered_gc
13 This is a wrapper around \p general_buffered class.
16 - \p Buffer - lock-free queue or lock-free bounded queue.
17 Default is \p cds::container::VyukovMPMCCycleQueue< retired_ptr >
18 - \p Lock - mutex type, default is \p std::mutex
19 - \p Backoff - back-off schema, default is \p cds::backoff::Default
22 #ifdef CDS_DOXGEN_INVOKED
23 class Buffer = cds::container::VyukovMPMCCycleQueue< retired_ptr >
24 ,class Lock = std::mutex
25 ,class Backoff = cds::backoff::Default
32 class gc< general_buffered< Buffer, Lock, Backoff > >: public details::gc_common
35 typedef general_buffered< Buffer, Lock, Backoff > rcu_implementation ; ///< Wrapped URCU implementation
37 typedef typename rcu_implementation::rcu_tag rcu_tag ; ///< URCU tag
38 typedef typename rcu_implementation::thread_gc thread_gc ; ///< Thread-side RCU part
39 typedef typename rcu_implementation::scoped_lock scoped_lock ; ///< Access lock class
41 using details::gc_common::atomic_marked_ptr;
44 /// Creates URCU \p %general_buffered singleton.
45 gc( size_t nBufferCapacity = 256 )
47 rcu_implementation::Construct( nBufferCapacity );
50 /// Destroys URCU \p %general_instant singleton
53 rcu_implementation::Destruct( true );
57 /// Waits to finish a grace period and clears the buffer
59 After grace period finished the function frees all retired pointer
62 static void synchronize()
64 rcu_implementation::instance()->synchronize();
67 /// Places retired pointer <\p p, \p pFunc> to internal buffer
69 If the buffer is full, \ref synchronize function is invoked.
72 static void retire_ptr( T * p, void (* pFunc)(T *) )
74 retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
78 /// Places retired pointer \p p with \p Disposer to internal buffer
80 If the buffer is full, \ref synchronize function is invoked.
82 template <typename Disposer, typename T>
83 static void retire_ptr( T * p )
85 retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
88 /// Places retired pointer \p p to internal buffer
90 If the buffer is full, \ref synchronize function is invoked.
92 static void retire_ptr( retired_ptr& p )
94 rcu_implementation::instance()->retire_ptr(p);
97 /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
98 template <typename ForwardIterator>
99 static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
101 rcu_implementation::instance()->batch_retire( itFirst, itLast );
104 /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
105 template <typename Func>
106 static void batch_retire( Func e )
108 rcu_implementation::instance()->batch_retire( e );
111 /// Acquires access lock (so called RCU reader-side lock)
113 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
115 static void access_lock()
117 thread_gc::access_lock();
120 /// Releases access lock (so called RCU reader-side lock)
122 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
124 static void access_unlock()
126 thread_gc::access_unlock();
129 /// Returns the threshold of internal buffer
130 static size_t capacity()
132 return rcu_implementation::instance()->capacity();
135 /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
137 Usually, this function is used internally to be convinced
138 that subsequent remove action is not lead to a deadlock.
140 static bool is_locked()
142 return thread_gc::is_locked();
145 /// Forces retired object removal
147 This function calls \ref synchronize
149 static void force_dispose()
155 }} // namespace cds::urcu
157 #endif // #ifndef CDSLIB_URCU_GENERAL_BUFFERED_H