3 #ifndef CDSLIB_URCU_GENERAL_THREADED_H
4 #define CDSLIB_URCU_GENERAL_THREADED_H
6 #include <cds/urcu/details/gpt.h>
8 namespace cds { namespace urcu {
10 /// User-space general-purpose RCU with special thread for deferred reclamation
11 /** @anchor cds_urcu_general_threaded_gc
13 This is a wrapper around general_threaded class used for metaprogramming.
16 - \p Buffer - lock-free queue or lock-free bounded queue.
17 Default is cds::container::VyukovMPMCCycleQueue< retired_ptr >
18 - \p Lock - mutex type, default is \p std::mutex
19 - \p DisposerThread - reclamation thread class, default is \p cds::urcu::dispose_thread
20 See \ref cds::urcu::dispose_thread for class interface.
21 - \p Backoff - back-off schema, default is cds::backoff::Default
25 #ifdef CDS_DOXGEN_INVOKED
26 class Buffer = cds::container::VyukovMPMCCycleQueue< epoch_retired_ptr >
27 ,class Lock = std::mutex
28 ,class DisposerThread = dispose_thread<Buffer>
29 ,class Backoff = cds::backoff::Default
37 class gc< general_threaded< Buffer, Lock, DisposerThread, Backoff > >: public details::gc_common
40 typedef general_threaded< Buffer, Lock, DisposerThread, Backoff > rcu_implementation ; ///< Wrapped URCU implementation
42 typedef typename rcu_implementation::rcu_tag rcu_tag ; ///< URCU tag
43 typedef typename rcu_implementation::thread_gc thread_gc ; ///< Thread-side RCU part
44 typedef typename rcu_implementation::scoped_lock scoped_lock ; ///< Access lock class
46 using details::gc_common::atomic_marked_ptr;
49 /// Creates URCU \p %general_threaded singleton.
50 gc( size_t nBufferCapacity = 256 )
52 rcu_implementation::Construct( nBufferCapacity );
55 /// Destroys URCU \p %general_threaded singleton
58 rcu_implementation::Destruct( true );
62 /// Waits to finish a grace period and calls disposing thread
64 After grace period finished the function gives new task to disposing thread.
65 Unlike \ref force_dispose the \p %synchronize function does not wait for
66 task ending. Only a "task ready" message is sent to disposing thread.
68 static void synchronize()
70 rcu_implementation::instance()->synchronize();
73 /// Retires pointer \p p by the disposer \p pFunc
75 If the buffer is full, \ref synchronize function is invoked.
78 static void retire_ptr( T * p, void (* pFunc)(T *) )
80 retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
84 /// Retires pointer \p p using \p Disposer
86 If the buffer is full, \ref synchronize function is invoked.
88 template <typename Disposer, typename T>
89 static void retire_ptr( T * p )
91 retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
94 /// Retires pointer \p p of type \ref cds_urcu_retired_ptr "retired_ptr"
96 If the buffer is full, \ref synchronize function is invoked.
98 static void retire_ptr( retired_ptr& p )
100 rcu_implementation::instance()->retire_ptr(p);
103 /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
104 template <typename ForwardIterator>
105 static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
107 rcu_implementation::instance()->batch_retire( itFirst, itLast );
110 /// Acquires access lock (so called RCU reader-side lock)
112 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
114 static void access_lock()
116 thread_gc::access_lock();
119 /// Releases access lock (so called RCU reader-side lock)
121 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
123 static void access_unlock()
125 thread_gc::access_unlock();
128 /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
130 Usually, this function is used internally to be convinced
131 that subsequent remove action is not lead to a deadlock.
133 static bool is_locked()
135 return thread_gc::is_locked();
138 /// Returns the threshold of internal buffer
139 static size_t capacity()
141 return rcu_implementation::instance()->capacity();
144 /// Forces retired object removal (synchronous version of \ref synchronize)
146 The function calls \ref synchronize and waits until reclamation thread
147 frees retired objects.
149 static void force_dispose()
151 rcu_implementation::instance()->force_dispose();
155 }} // namespace cds::urcu
157 #endif // #ifndef CDSLIB_URCU_GENERAL_THREADED_H