issue #11: replace _CDS_ header guard prefix with CDSLIB_
[libcds.git] / cds / urcu / signal_threaded.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_URCU_SIGNAL_THREADED_H
4 #define CDSLIB_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< epoch_retired_ptr >
29         ,class Lock = std::mutex
30         ,class DisposerThread = dispose_thread<Buffer>
31         ,class Backoff = cds::backoff::Default
32 #else
33         class Buffer
34        ,class Lock
35        ,class DisposerThread
36        ,class Backoff
37 #endif
38     >
39     class gc< signal_threaded< Buffer, Lock, DisposerThread, Backoff > >: public details::gc_common
40     {
41     public:
42         typedef signal_threaded< Buffer, Lock, DisposerThread, Backoff >  rcu_implementation   ;    ///< Wrapped URCU implementation
43
44         typedef typename rcu_implementation::rcu_tag     rcu_tag     ;   ///< URCU tag
45         typedef typename rcu_implementation::thread_gc   thread_gc   ;   ///< Thread-side RCU part
46         typedef typename rcu_implementation::scoped_lock scoped_lock ;   ///< Access lock class
47
48         using details::gc_common::atomic_marked_ptr;
49
50     public:
51         /// Creates URCU \p %general_threaded singleton.
52         /**
53             The \p nBufferCapacity parameter defines RCU threshold.
54
55             The \p nSignal parameter defines a signal number stated for RCU, default is \p SIGUSR1
56         */
57         gc( size_t nBufferCapacity = 256, int nSignal = SIGUSR1 )
58         {
59             rcu_implementation::Construct( nBufferCapacity, nSignal );
60         }
61
62         /// Destroys URCU \p %signal_threaded singleton
63         ~gc()
64         {
65             rcu_implementation::Destruct( true );
66         }
67
68     public:
69         /// Waits to finish a grace period and calls disposing thread
70         /**
71             After grace period finished the function gives new task to disposing thread.
72             Unlike \ref force_dispose the \p %synchronize function does not wait for
73             task ending. Only a "task ready" message is sent to disposing thread.
74         */
75         static void synchronize()
76         {
77             rcu_implementation::instance()->synchronize();
78         }
79
80         /// Retires pointer \p p by the disposer \p pFunc
81         /**
82             If the buffer is full, \ref synchronize function is invoked.
83         */
84         template <typename T>
85         static void retire_ptr( T * p, void (* pFunc)(T *) )
86         {
87             retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
88             retire_ptr( rp );
89         }
90
91         /// Retires pointer \p p using \p Disposer
92         /**
93             If the buffer is full, \ref synchronize function is invoked.
94         */
95         template <typename Disposer, typename T>
96         static void retire_ptr( T * p )
97         {
98             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
99         }
100
101         /// Retires pointer \p p of type \ref cds_urcu_retired_ptr "retired_ptr"
102         /**
103             If the buffer is full, \ref synchronize function is invoked.
104         */
105         static void retire_ptr( retired_ptr& p )
106         {
107             rcu_implementation::instance()->retire_ptr(p);
108         }
109
110         /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
111         template <typename ForwardIterator>
112         static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
113         {
114             rcu_implementation::instance()->batch_retire( itFirst, itLast );
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         /// Returns the signal number stated for RCU
152         static int signal_no()
153         {
154             return rcu_implementation::instance()->signal_no();
155         }
156
157         /// Forces retired object removal (synchronous version of \ref synchronize)
158         /**
159             The function calls \ref synchronize and waits until reclamation thread
160             frees retired objects.
161         */
162         static void force_dispose()
163         {
164             rcu_implementation::instance()->force_dispose();
165         }
166     };
167
168 }} // namespace cds::urcu
169
170 #endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
171 #endif // #ifndef CDSLIB_URCU_SIGNAL_THREADED_H