Merge branch 'integration' of github.com:khizmax/libcds into integration
[libcds.git] / cds / urcu / general_threaded.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_URCU_GENERAL_THREADED_H
4 #define CDSLIB_URCU_GENERAL_THREADED_H
5
6 #include <cds/urcu/details/gpt.h>
7
8 namespace cds { namespace urcu {
9
10     /// User-space general-purpose RCU with special thread for deferred reclamation
11     /** @anchor cds_urcu_general_threaded_gc
12
13         This is a wrapper around \p general_threaded class.
14
15         Template arguments:
16         - \p Buffer - lock-free MPSC (muliple producer/single consumer) queue.
17             Default is \p cds::container::VyukovMPSCCycleQueue< 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 \p cds::backoff::Default
22
23     */
24     template <
25 #ifdef CDS_DOXGEN_INVOKED
26         class Buffer = cds::container::VyukovMPSCCycleQueue< epoch_retired_ptr >
27         ,class Lock = std::mutex
28         ,class DisposerThread = dispose_thread<Buffer>
29         ,class Backoff = cds::backoff::Default
30 #else
31         class Buffer
32        ,class Lock
33        ,class DisposerThread
34        ,class Backoff
35 #endif
36     >
37     class gc< general_threaded< Buffer, Lock, DisposerThread, Backoff > >: public details::gc_common
38     {
39     public:
40         typedef general_threaded< Buffer, Lock, DisposerThread, Backoff >  rcu_implementation   ;    ///< Wrapped URCU implementation
41
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
45
46         using details::gc_common::atomic_marked_ptr;
47
48     public:
49         /// Creates URCU \p %general_threaded singleton.
50         gc( size_t nBufferCapacity = 256 )
51         {
52             rcu_implementation::Construct( nBufferCapacity );
53         }
54
55         /// Destroys URCU \p %general_threaded singleton
56         ~gc()
57         {
58             rcu_implementation::Destruct( true );
59         }
60
61     public:
62         /// Waits to finish a grace period and calls disposing thread
63         /**
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.
67         */
68         static void synchronize()
69         {
70             rcu_implementation::instance()->synchronize();
71         }
72
73         /// Retires pointer \p p by the disposer \p pFunc
74         /**
75             If the buffer is full, \ref synchronize function is invoked.
76         */
77         template <typename T>
78         static void retire_ptr( T * p, void (* pFunc)(T *) )
79         {
80             retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
81             retire_ptr( rp );
82         }
83
84         /// Retires pointer \p p using \p Disposer
85         /**
86             If the buffer is full, \ref synchronize function is invoked.
87         */
88         template <typename Disposer, typename T>
89         static void retire_ptr( T * p )
90         {
91             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
92         }
93
94         /// Retires pointer \p p of type \ref cds_urcu_retired_ptr "retired_ptr"
95         /**
96             If the buffer is full, \ref synchronize function is invoked.
97         */
98         static void retire_ptr( retired_ptr& p )
99         {
100             rcu_implementation::instance()->retire_ptr(p);
101         }
102
103         /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
104         template <typename ForwardIterator>
105         static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
106         {
107             rcu_implementation::instance()->batch_retire( itFirst, itLast );
108         }
109
110         /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
111         template <typename Func>
112         static void batch_retire( Func e )
113         {
114             rcu_implementation::instance()->batch_retire( e );
115         }
116
117          /// Acquires access lock (so called RCU reader-side lock)
118         /**
119             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
120         */
121         static void access_lock()
122         {
123             thread_gc::access_lock();
124         }
125
126         /// Releases access lock (so called RCU reader-side lock)
127         /**
128             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
129         */
130         static void access_unlock()
131         {
132             thread_gc::access_unlock();
133         }
134
135         /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
136         /**
137             Usually, this function is used internally to be convinced
138             that subsequent remove action is not lead to a deadlock.
139         */
140         static bool is_locked()
141         {
142             return thread_gc::is_locked();
143         }
144
145         /// Returns the threshold of internal buffer
146         static size_t capacity()
147         {
148             return rcu_implementation::instance()->capacity();
149         }
150
151         /// Forces retired object removal (synchronous version of \ref synchronize)
152         /**
153             The function calls \ref synchronize and waits until reclamation thread
154             frees retired objects.
155         */
156         static void force_dispose()
157         {
158             rcu_implementation::instance()->force_dispose();
159         }
160     };
161
162 }} // namespace cds::urcu
163
164 #endif // #ifndef CDSLIB_URCU_GENERAL_THREADED_H