2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
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_THREADED_H
32 #define CDSLIB_URCU_SIGNAL_THREADED_H
34 #include <cds/urcu/details/sig_threaded.h>
36 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
38 namespace cds { namespace urcu {
40 /// User-space signal-handled RCU with special thread for deferred reclamation
41 /** @anchor cds_urcu_signal_threaded_gc
43 This is a wrapper around \p signal_threaded class.
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
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
67 class gc< signal_threaded< Buffer, Lock, DisposerThread, Backoff > >: public details::gc_common
70 typedef signal_threaded< Buffer, Lock, DisposerThread, Backoff > rcu_implementation ; ///< Wrapped URCU implementation
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
76 using details::gc_common::atomic_marked_ptr;
79 /// Creates URCU \p %general_threaded singleton.
81 The \p nBufferCapacity parameter defines RCU threshold.
83 The \p nSignal parameter defines a signal number stated for RCU, default is \p SIGUSR1
85 gc( size_t nBufferCapacity = 256, int nSignal = SIGUSR1 )
87 rcu_implementation::Construct( nBufferCapacity, nSignal );
90 /// Destroys URCU \p %signal_threaded singleton
93 rcu_implementation::Destruct( true );
97 /// Waits to finish a grace period and calls disposing thread
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.
103 static void synchronize()
105 rcu_implementation::instance()->synchronize();
108 /// Retires pointer \p p by the disposer \p pFunc
110 If the buffer is full, \ref synchronize function is invoked.
112 template <typename T>
113 static void retire_ptr( T * p, void (* pFunc)(T *))
115 retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
119 /// Retires pointer \p p using \p Disposer
121 If the buffer is full, \ref synchronize function is invoked.
123 template <typename Disposer, typename T>
124 static void retire_ptr( T * p )
126 retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
129 /// Retires pointer \p p of type \ref cds_urcu_retired_ptr "retired_ptr"
131 If the buffer is full, \ref synchronize function is invoked.
133 static void retire_ptr( retired_ptr& p )
135 rcu_implementation::instance()->retire_ptr(p);
138 /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
139 template <typename ForwardIterator>
140 static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
142 rcu_implementation::instance()->batch_retire( itFirst, itLast );
145 /// Retires the pointer chain until \p Func returns \p nullptr retired pointer
146 template <typename Func>
147 static void batch_retire( Func e )
149 rcu_implementation::instance()->batch_retire( e );
152 /// Acquires access lock (so called RCU reader-side lock)
154 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
156 static void access_lock()
158 thread_gc::access_lock();
161 /// Releases access lock (so called RCU reader-side lock)
163 For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
165 static void access_unlock()
167 thread_gc::access_unlock();
170 /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
172 Usually, this function is used internally to be convinced
173 that subsequent remove action is not lead to a deadlock.
175 static bool is_locked()
177 return thread_gc::is_locked();
180 /// Returns the threshold of internal buffer
181 static size_t capacity()
183 return rcu_implementation::instance()->capacity();
186 /// Returns the signal number stated for RCU
187 static int signal_no()
189 return rcu_implementation::instance()->signal_no();
192 /// Forces retired object removal (synchronous version of \ref synchronize)
194 The function calls \ref synchronize and waits until reclamation thread
195 frees retired objects.
197 static void force_dispose()
199 rcu_implementation::instance()->force_dispose();
205 class gc< signal_threaded_stripped >: public gc< signal_threaded<>>
209 }} // namespace cds::urcu
211 #endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
212 #endif // #ifndef CDSLIB_URCU_SIGNAL_THREADED_H