Added copyright and license
[libcds.git] / cds / urcu / general_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_GENERAL_THREADED_H
32 #define CDSLIB_URCU_GENERAL_THREADED_H
33
34 #include <cds/urcu/details/gpt.h>
35
36 namespace cds { namespace urcu {
37
38     /// User-space general-purpose RCU with special thread for deferred reclamation
39     /** @anchor cds_urcu_general_threaded_gc
40
41         This is a wrapper around \p general_threaded class.
42
43         Template arguments:
44         - \p Buffer - lock-free MPSC (muliple producer/single consumer) queue.
45             Default is \p cds::container::VyukovMPSCCycleQueue< retired_ptr >
46         - \p Lock - mutex type, default is \p std::mutex
47         - \p DisposerThread - reclamation thread class, default is \p cds::urcu::dispose_thread
48             See \ref cds::urcu::dispose_thread for class interface.
49         - \p Backoff - back-off schema, default is \p cds::backoff::Default
50
51     */
52     template <
53 #ifdef CDS_DOXGEN_INVOKED
54         class Buffer = cds::container::VyukovMPSCCycleQueue< epoch_retired_ptr >
55         ,class Lock = std::mutex
56         ,class DisposerThread = dispose_thread<Buffer>
57         ,class Backoff = cds::backoff::Default
58 #else
59         class Buffer
60        ,class Lock
61        ,class DisposerThread
62        ,class Backoff
63 #endif
64     >
65     class gc< general_threaded< Buffer, Lock, DisposerThread, Backoff > >: public details::gc_common
66     {
67     public:
68         typedef general_threaded< Buffer, Lock, DisposerThread, Backoff >  rcu_implementation   ;    ///< Wrapped URCU implementation
69
70         typedef typename rcu_implementation::rcu_tag     rcu_tag     ;   ///< URCU tag
71         typedef typename rcu_implementation::thread_gc   thread_gc   ;   ///< Thread-side RCU part
72         typedef typename rcu_implementation::scoped_lock scoped_lock ;   ///< Access lock class
73
74         using details::gc_common::atomic_marked_ptr;
75
76     public:
77         /// Creates URCU \p %general_threaded singleton.
78         gc( size_t nBufferCapacity = 256 )
79         {
80             rcu_implementation::Construct( nBufferCapacity );
81         }
82
83         /// Destroys URCU \p %general_threaded singleton
84         ~gc()
85         {
86             rcu_implementation::Destruct( true );
87         }
88
89     public:
90         /// Waits to finish a grace period and calls disposing thread
91         /**
92             After grace period finished the function gives new task to disposing thread.
93             Unlike \ref force_dispose the \p %synchronize function does not wait for
94             task ending. Only a "task ready" message is sent to disposing thread.
95         */
96         static void synchronize()
97         {
98             rcu_implementation::instance()->synchronize();
99         }
100
101         /// Retires pointer \p p by the disposer \p pFunc
102         /**
103             If the buffer is full, \ref synchronize function is invoked.
104         */
105         template <typename T>
106         static void retire_ptr( T * p, void (* pFunc)(T *) )
107         {
108             retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
109             retire_ptr( rp );
110         }
111
112         /// Retires pointer \p p using \p Disposer
113         /**
114             If the buffer is full, \ref synchronize function is invoked.
115         */
116         template <typename Disposer, typename T>
117         static void retire_ptr( T * p )
118         {
119             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
120         }
121
122         /// Retires pointer \p p of type \ref cds_urcu_retired_ptr "retired_ptr"
123         /**
124             If the buffer is full, \ref synchronize function is invoked.
125         */
126         static void retire_ptr( retired_ptr& p )
127         {
128             rcu_implementation::instance()->retire_ptr(p);
129         }
130
131         /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
132         template <typename ForwardIterator>
133         static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
134         {
135             rcu_implementation::instance()->batch_retire( itFirst, itLast );
136         }
137
138         /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
139         template <typename Func>
140         static void batch_retire( Func e )
141         {
142             rcu_implementation::instance()->batch_retire( e );
143         }
144
145          /// Acquires access lock (so called RCU reader-side lock)
146         /**
147             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
148         */
149         static void access_lock()
150         {
151             thread_gc::access_lock();
152         }
153
154         /// Releases access lock (so called RCU reader-side lock)
155         /**
156             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
157         */
158         static void access_unlock()
159         {
160             thread_gc::access_unlock();
161         }
162
163         /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
164         /**
165             Usually, this function is used internally to be convinced
166             that subsequent remove action is not lead to a deadlock.
167         */
168         static bool is_locked()
169         {
170             return thread_gc::is_locked();
171         }
172
173         /// Returns the threshold of internal buffer
174         static size_t capacity()
175         {
176             return rcu_implementation::instance()->capacity();
177         }
178
179         /// Forces retired object removal (synchronous version of \ref synchronize)
180         /**
181             The function calls \ref synchronize and waits until reclamation thread
182             frees retired objects.
183         */
184         static void force_dispose()
185         {
186             rcu_implementation::instance()->force_dispose();
187         }
188     };
189
190 }} // namespace cds::urcu
191
192 #endif // #ifndef CDSLIB_URCU_GENERAL_THREADED_H