Move libcds 1.6.0 from SVN
[libcds.git] / cds / urcu / general_buffered.h
1 //$$CDS-header$$
2
3 #ifndef _CDS_URCU_GENERAL_BUFFERED_H
4 #define _CDS_URCU_GENERAL_BUFFERED_H
5
6 #include <cds/urcu/details/gpb.h>
7
8 namespace cds { namespace urcu {
9
10     /// User-space general-purpose RCU with deferred buffered reclamation
11     /** @anchor cds_urcu_general_buffered_gc
12
13         This is a wrapper around general_buffered class used for metaprogramming.
14
15         Template arguments:
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 Backoff - back-off schema, default is cds::backoff::Default
20     */
21     template <
22 #ifdef CDS_DOXGEN_INVOKED
23         class Buffer = cds::container::VyukovMPMCCycleQueue<
24             retired_ptr
25             ,cds::opt::buffer< cds::opt::v::dynamic_buffer< retired_ptr > >
26         >
27         ,class Lock = cds_std::mutex
28         ,class Backoff = cds::backoff::Default
29 #else
30         class Buffer
31        ,class Lock
32        ,class Backoff
33 #endif
34     >
35     class gc< general_buffered< Buffer, Lock, Backoff > >: public details::gc_common
36     {
37     public:
38         typedef general_buffered< Buffer, Lock, Backoff >  rcu_implementation   ;    ///< Wrapped URCU implementation
39
40         typedef typename rcu_implementation::rcu_tag     rcu_tag     ;   ///< URCU tag
41         typedef typename rcu_implementation::thread_gc   thread_gc   ;   ///< Thread-side RCU part
42         typedef typename rcu_implementation::scoped_lock scoped_lock ;   ///< Access lock class
43
44         using details::gc_common::atomic_marked_ptr;
45
46     public:
47         /// Creates URCU \p %general_buffered singleton.
48         gc( size_t nBufferCapacity = 256 )
49         {
50             rcu_implementation::Construct( nBufferCapacity );
51         }
52
53         /// Destroys URCU \p %general_instant singleton
54         ~gc()
55         {
56             rcu_implementation::Destruct( true );
57         }
58
59     public:
60         /// Waits to finish a grace period and clears the buffer
61         /**
62             After grace period finished the function frees all retired pointer
63             from internal buffer.
64         */
65         static void synchronize()
66         {
67             rcu_implementation::instance()->synchronize();
68         }
69
70         /// Places retired pointer <\p p, \p pFunc> to internal buffer
71         /**
72             If the buffer is full, \ref synchronize function is invoked.
73         */
74         template <typename T>
75         static void retire_ptr( T * p, void (* pFunc)(T *) )
76         {
77             retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
78             retire_ptr( rp );
79         }
80
81         /// Places retired pointer \p p with \p Disposer to internal buffer
82         /**
83             If the buffer is full, \ref synchronize function is invoked.
84         */
85         template <typename Disposer, typename T>
86         static void retire_ptr( T * p )
87         {
88             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
89         }
90
91         /// Places retired pointer \p p to internal buffer
92         /**
93             If the buffer is full, \ref synchronize function is invoked.
94         */
95         static void retire_ptr( retired_ptr& p )
96         {
97             rcu_implementation::instance()->retire_ptr(p);
98         }
99
100         /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
101         template <typename ForwardIterator>
102         static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
103         {
104             rcu_implementation::instance()->batch_retire( itFirst, itLast );
105         }
106
107          /// Acquires access lock (so called RCU reader-side lock)
108         /**
109             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
110         */
111         static void access_lock()
112         {
113             thread_gc::access_lock();
114         }
115
116         /// Releases access lock (so called RCU reader-side lock)
117         /**
118             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
119         */
120         static void access_unlock()
121         {
122             thread_gc::access_unlock();
123         }
124
125         /// Returns the threshold of internal buffer
126         static size_t capacity()
127         {
128             return rcu_implementation::instance()->capacity();
129         }
130
131         /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
132         /**
133             Usually, this function is used internally to be convinced
134             that subsequent remove action is not lead to a deadlock.
135         */
136         static bool is_locked()
137         {
138             return thread_gc::is_locked();
139         }
140
141         /// Forces retired object removal
142         /**
143             This function calls \ref synchronize
144         */
145         static void force_dispose()
146         {
147             synchronize();
148         }
149     };
150
151 }} // namespace cds::urcu
152
153 #endif // #ifndef _CDS_URCU_GENERAL_BUFFERED_H