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