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