Added stripped classes for uRCU implementations
[libcds.git] / cds / urcu / signal_threaded.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
29 */
30
31 #ifndef CDSLIB_URCU_SIGNAL_THREADED_H
32 #define CDSLIB_URCU_SIGNAL_THREADED_H
33
34 #include <cds/urcu/details/sig_threaded.h>
35
36 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
37
38 namespace cds { namespace urcu {
39
40     /// User-space signal-handled RCU with special thread for deferred reclamation
41     /** @anchor cds_urcu_signal_threaded_gc
42
43         This is a wrapper around \p signal_threaded class.
44
45         Template arguments:
46         - \p Buffer - lock-free MPSC (muliple producer/single consumer) queue.
47             Default is \p cds::container::VyukovMPSCCycleQueue< epoch_retired_ptr >
48         - \p Lock - mutex type, default is \p std::mutex
49         - \p DisposerThread - reclamation thread class, default is \p %general_threaded_dispose_thread
50             See \ref cds::urcu::dispose_thread for class interface.
51         - \p Backoff - back-off schema, default is \p cds::backoff::Default
52
53     */
54     template <
55 #ifdef CDS_DOXGEN_INVOKED
56         class Buffer = cds::container::VyukovMPSCCycleQueue< epoch_retired_ptr >
57         ,class Lock = std::mutex
58         ,class DisposerThread = dispose_thread<Buffer>
59         ,class Backoff = cds::backoff::Default
60 #else
61         class Buffer
62        ,class Lock
63        ,class DisposerThread
64        ,class Backoff
65 #endif
66     >
67     class gc< signal_threaded< Buffer, Lock, DisposerThread, Backoff > >: public details::gc_common
68     {
69     public:
70         typedef signal_threaded< Buffer, Lock, DisposerThread, Backoff >  rcu_implementation   ;    ///< Wrapped URCU implementation
71
72         typedef typename rcu_implementation::rcu_tag     rcu_tag     ;   ///< URCU tag
73         typedef typename rcu_implementation::thread_gc   thread_gc   ;   ///< Thread-side RCU part
74         typedef typename rcu_implementation::scoped_lock scoped_lock ;   ///< Access lock class
75
76         using details::gc_common::atomic_marked_ptr;
77
78     public:
79         /// Creates URCU \p %general_threaded singleton.
80         /**
81             The \p nBufferCapacity parameter defines RCU threshold.
82
83             The \p nSignal parameter defines a signal number stated for RCU, default is \p SIGUSR1
84         */
85         gc( size_t nBufferCapacity = 256, int nSignal = SIGUSR1 )
86         {
87             rcu_implementation::Construct( nBufferCapacity, nSignal );
88         }
89
90         /// Destroys URCU \p %signal_threaded singleton
91         ~gc()
92         {
93             rcu_implementation::Destruct( true );
94         }
95
96     public:
97         /// Waits to finish a grace period and calls disposing thread
98         /**
99             After grace period finished the function gives new task to disposing thread.
100             Unlike \ref force_dispose the \p %synchronize function does not wait for
101             task ending. Only a "task ready" message is sent to disposing thread.
102         */
103         static void synchronize()
104         {
105             rcu_implementation::instance()->synchronize();
106         }
107
108         /// Retires pointer \p p by the disposer \p pFunc
109         /**
110             If the buffer is full, \ref synchronize function is invoked.
111         */
112         template <typename T>
113         static void retire_ptr( T * p, void (* pFunc)(T *) )
114         {
115             retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
116             retire_ptr( rp );
117         }
118
119         /// Retires pointer \p p using \p Disposer
120         /**
121             If the buffer is full, \ref synchronize function is invoked.
122         */
123         template <typename Disposer, typename T>
124         static void retire_ptr( T * p )
125         {
126             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
127         }
128
129         /// Retires pointer \p p of type \ref cds_urcu_retired_ptr "retired_ptr"
130         /**
131             If the buffer is full, \ref synchronize function is invoked.
132         */
133         static void retire_ptr( retired_ptr& p )
134         {
135             rcu_implementation::instance()->retire_ptr(p);
136         }
137
138         /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
139         template <typename ForwardIterator>
140         static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
141         {
142             rcu_implementation::instance()->batch_retire( itFirst, itLast );
143         }
144
145         /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
146         template <typename Func>
147         static void batch_retire( Func e )
148         {
149             rcu_implementation::instance()->batch_retire( e );
150         }
151
152          /// Acquires access lock (so called RCU reader-side lock)
153         /**
154             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
155         */
156         static void access_lock()
157         {
158             thread_gc::access_lock();
159         }
160
161         /// Releases access lock (so called RCU reader-side lock)
162         /**
163             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
164         */
165         static void access_unlock()
166         {
167             thread_gc::access_unlock();
168         }
169
170         /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
171         /**
172             Usually, this function is used internally to be convinced
173             that subsequent remove action is not lead to a deadlock.
174         */
175         static bool is_locked()
176         {
177             return thread_gc::is_locked();
178         }
179
180         /// Returns the threshold of internal buffer
181         static size_t capacity()
182         {
183             return rcu_implementation::instance()->capacity();
184         }
185
186         /// Returns the signal number stated for RCU
187         static int signal_no()
188         {
189             return rcu_implementation::instance()->signal_no();
190         }
191
192         /// Forces retired object removal (synchronous version of \ref synchronize)
193         /**
194             The function calls \ref synchronize and waits until reclamation thread
195             frees retired objects.
196         */
197         static void force_dispose()
198         {
199             rcu_implementation::instance()->force_dispose();
200         }
201     };
202
203     //@cond
204     template<>
205     class gc< signal_threaded_stripped >: public gc< signal_threaded<>>
206     {};
207     //@endcond
208
209 }} // namespace cds::urcu
210
211 #endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
212 #endif // #ifndef CDSLIB_URCU_SIGNAL_THREADED_H