2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
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.
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.
31 #ifndef CDSLIB_URCU_SIGNAL_BUFFERED_H
32 #define CDSLIB_URCU_SIGNAL_BUFFERED_H
34 #include <cds/urcu/details/sig_buffered.h>
35 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
37 namespace cds { namespace urcu {
39 /// User-space signal-handled RCU with deferred buffered reclamation
40 /** @anchor cds_urcu_signal_buffered_gc
42 This is a wrapper around \p signal_buffered class.
45 - \p Buffer - lock-free queue or lock-free bounded queue.
46 Default is \p cds::container::VyukovMPMCCycleQueue< retired_ptr >
47 - \p Lock - mutex type, default is \p std::mutex
48 - \p Backoff - back-off schema, default is \p cds::backoff::Default
51 #ifdef CDS_DOXGEN_INVOKED
52 class Buffer = cds::container::VyukovMPMCCycleQueue< retired_ptr >
53 ,class Lock = std::mutex
54 ,class Backoff = cds::backoff::Default
61 class gc< signal_buffered< Buffer, Lock, Backoff > >: public details::gc_common
64 typedef signal_buffered< Buffer, Lock, Backoff > rcu_implementation ; ///< Wrapped URCU implementation
66 typedef typename rcu_implementation::rcu_tag rcu_tag ; ///< URCU tag
67 typedef typename rcu_implementation::thread_gc thread_gc ; ///< Thread-side RCU part
68 typedef typename rcu_implementation::scoped_lock scoped_lock ; ///< Access lock class
70 using details::gc_common::atomic_marked_ptr;
73 /// Creates URCU \p %signal_buffered singleton.
75 The \p nBufferCapacity parameter defines RCU threshold.
77 The \p nSignal parameter defines a signal number stated for RCU, default is \p SIGUSR1
79 gc( size_t nBufferCapacity = 256, int nSignal = SIGUSR1 )
81 rcu_implementation::Construct( nBufferCapacity, nSignal );
84 /// Destroys URCU \p %general_instant singleton
87 rcu_implementation::Destruct( true );
91 /// Waits to finish a grace period and clears the buffer
93 After grace period finished the function frees all retired pointer
96 static void synchronize()
98 rcu_implementation::instance()->synchronize();
101 /// Places retired pointer <\p p, \p pFunc> to internal buffer
103 If the buffer is full, \ref synchronize function is invoked.
105 template <typename T>
106 static void retire_ptr( T * p, void (* pFunc)(T *))
108 retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
112 /// Places retired pointer \p p with \p Disposer to internal buffer
114 If the buffer is full, \ref synchronize function is invoked.
116 template <typename Disposer, typename T>
117 static void retire_ptr( T * p )
119 retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
122 /// Places retired pointer \p p to internal buffer
124 If the buffer is full, \ref synchronize function is invoked.
126 static void retire_ptr( retired_ptr& p )
128 rcu_implementation::instance()->retire_ptr(p);
131 /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
132 template <typename ForwardIterator>
133 static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
135 rcu_implementation::instance()->batch_retire( itFirst, itLast );
138 /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
139 template <typename Func>
140 static void batch_retire( Func e )
142 rcu_implementation::instance()->batch_retire( e );
145 /// Acquires access lock (so called RCU reader-side lock)
147 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
149 static void access_lock()
151 thread_gc::access_lock();
154 /// Releases access lock (so called RCU reader-side lock)
156 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
158 static void access_unlock()
160 thread_gc::access_unlock();
163 /// Returns the threshold of internal buffer
164 static size_t capacity()
166 return rcu_implementation::instance()->capacity();
169 /// Returns the signal number stated for RCU
170 static int signal_no()
172 return rcu_implementation::instance()->signal_no();
175 /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
177 Usually, this function is used internally to be convinced
178 that subsequent remove action is not lead to a deadlock.
180 static bool is_locked()
182 return thread_gc::is_locked();
185 /// Forces retired object removal
187 This function calls \ref synchronize
189 static void force_dispose()
197 class gc< signal_buffered_stripped >: public gc< signal_buffered<>>
202 }} // namespace cds::urcu
204 #endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
205 #endif // #ifndef CDSLIB_URCU_SIGNAL_BUFFERED_H