3 #ifndef CDSLIB_URCU_DISPOSE_THREAD_H
4 #define CDSLIB_URCU_DISPOSE_THREAD_H
9 #include <condition_variable>
10 #include <cds/details/aligned_type.h>
12 namespace cds { namespace urcu {
14 /// Reclamation thread for \p general_threaded and \p signal_threaded URCU
16 The object of this class contains a reclamation thread object and
17 necessary synchronization object(s). The object manages reclamation thread
18 and defines a set of messages (i.e. methods) to communicate with the thread.
20 Template argument \p Buffer defines the buffer type of \ref general_threaded (or \ref signal_threaded) URCU.
22 template <class Buffer>
26 typedef Buffer buffer_type ; ///< Buffer type
29 typedef std::thread thread_type;
30 typedef std::mutex mutex_type;
31 typedef std::condition_variable condvar_type;
32 typedef std::unique_lock< mutex_type > unique_lock;
34 class dispose_thread_starter: public thread_type
36 static void thread_func( dispose_thread * pThis )
42 dispose_thread_starter( dispose_thread * pThis )
43 : thread_type( thread_func, pThis )
47 typedef char thread_placeholder[ sizeof(dispose_thread_starter) ];
48 typename cds::details::aligned_type< thread_placeholder, alignof( dispose_thread_starter ) >::type m_threadPlaceholder;
49 dispose_thread_starter * m_DisposeThread;
51 // synchronization with disposing thread
53 condvar_type m_cvDataReady;
55 // Task for thread (dispose cycle)
56 buffer_type * volatile m_pBuffer;
57 uint64_t volatile m_nCurEpoch;
60 bool volatile m_bQuit;
62 // disposing pass sync
63 condvar_type m_cvReady;
64 bool volatile m_bReady;
67 private: // methods called from disposing thread
71 buffer_type * pBuffer;
77 unique_lock lock( m_Mutex );
79 // signal that we are ready to dispose
81 m_cvReady.notify_one();
83 // wait new data portion
85 m_cvDataReady.wait( lock );
88 m_bReady = false ; // we are busy
91 nCurEpoch = m_nCurEpoch;
97 dispose_buffer( pBuffer, nCurEpoch );
101 void dispose_buffer( buffer_type * pBuf, uint64_t nCurEpoch )
104 while ( pBuf->pop( p ) ) {
105 if ( p.m_nEpoch <= nCurEpoch )
118 : m_pBuffer( nullptr )
125 public: // methods called from any thread
126 /// Start reclamation thread
128 This function is called by \ref general_threaded object to start
129 internal reclamation thread.
133 m_DisposeThread = new (m_threadPlaceholder) dispose_thread_starter( this );
136 /// Stop reclamation thread
138 This function is called by \ref general_threaded object to
139 start reclamation cycle and then to terminate reclamation thread.
141 \p buf buffer contains retired objects ready to free.
143 void stop( buffer_type& buf, uint64_t nCurEpoch )
146 unique_lock lock( m_Mutex );
148 // wait while retiring pass done
150 m_cvReady.wait( lock );
152 // give a new work and set stop flag
154 m_nCurEpoch = nCurEpoch;
157 m_cvDataReady.notify_one();
159 m_DisposeThread->join();
162 /// Start reclamation cycle
164 This function is called by \ref general_threaded object
165 to notify the reclamation thread about new work.
166 \p buf buffer contains retired objects ready to free.
167 The reclamation thread should free all \p buf objects
168 \p m_nEpoch field of which is no more than \p nCurEpoch.
170 If \p bSync parameter is \p true the calling thread should
171 wait until disposing done.
173 void dispose( buffer_type& buf, uint64_t nCurEpoch, bool bSync )
175 unique_lock lock( m_Mutex );
177 // wait while disposing pass done
179 m_cvReady.wait( lock );
185 m_nCurEpoch = nCurEpoch;
188 m_cvDataReady.notify_one();
192 m_cvReady.wait( lock );
196 }} // namespace cds::urcu
198 #endif // #ifdef CDSLIB_URCU_DISPOSE_THREAD_H