3 #ifndef _CDS_URCU_DISPOSE_THREAD_H
4 #define _CDS_URCU_DISPOSE_THREAD_H
6 //#include <cds/backoff_strategy.h>
7 #include <cds/details/std/thread.h>
8 #include <cds/details/std/mutex.h>
9 #include <cds/details/std/condition_variable.h>
10 #include <cds/details/std/memory.h> // unique_ptr
11 #include <cds/details/aligned_type.h>
13 namespace cds { namespace urcu {
15 /// Reclamation thread for \p general_threaded and \p signal_threaded URCU
17 The object of this class contains a reclamation thread object and
18 necessary synchronization object(s). The object manages reclamation thread
19 and defines a set of messages (i.e. methods) to communicate with the thread.
21 Template argument \p Buffer defines the buffer type of \ref general_threaded (or \ref signal_threaded) URCU.
23 template <class Buffer>
27 typedef Buffer buffer_type ; ///< Buffer type
30 typedef cds_std::thread thread_type;
31 typedef cds_std::mutex mutex_type;
32 typedef cds_std::condition_variable condvar_type;
33 typedef cds_std::unique_lock< mutex_type > unique_lock;
35 class dispose_thread_starter: public thread_type
37 static void thread_func( dispose_thread * pThis )
43 dispose_thread_starter( dispose_thread * pThis )
44 : thread_type( thread_func, pThis )
48 typedef char thread_placeholder[ sizeof(dispose_thread_starter) ];
49 typename cds::details::aligned_type< thread_placeholder, alignof( dispose_thread_starter ) >::type m_threadPlaceholder;
50 dispose_thread_starter * m_DisposeThread;
52 // synchronization with disposing thread
54 condvar_type m_cvDataReady;
56 // Task for thread (dispose cycle)
57 buffer_type * volatile m_pBuffer;
58 uint64_t volatile m_nCurEpoch;
61 bool volatile m_bQuit;
63 // disposing pass sync
64 condvar_type m_cvReady;
65 bool volatile m_bReady;
68 private: // methods called from disposing thread
72 buffer_type * pBuffer;
78 unique_lock lock( m_Mutex );
80 // signal that we are ready to dispose
82 m_cvReady.notify_one();
84 // wait new data portion
86 m_cvDataReady.wait( lock );
89 m_bReady = false ; // we are busy
92 nCurEpoch = m_nCurEpoch;
94 m_pBuffer = null_ptr<buffer_type *>();
98 dispose_buffer( pBuffer, nCurEpoch );
102 void dispose_buffer( buffer_type * pBuf, uint64_t nCurEpoch )
105 while ( pBuf->pop( p ) ) {
106 if ( p.m_nEpoch <= nCurEpoch )
119 : m_pBuffer( null_ptr<buffer_type *>() )
126 public: // methods called from any thread
127 /// Start reclamation thread
129 This function is called by \ref general_threaded object to start
130 internal reclamation thread.
134 m_DisposeThread = new (m_threadPlaceholder) dispose_thread_starter( this );
137 /// Stop reclamation thread
139 This function is called by \ref general_threaded object to
140 start reclamation cycle and then to terminate reclamation thread.
142 \p buf buffer contains retired objects ready to free.
144 void stop( buffer_type& buf, uint64_t nCurEpoch )
147 unique_lock lock( m_Mutex );
149 // wait while retiring pass done
151 m_cvReady.wait( lock );
153 // give a new work and set stop flag
155 m_nCurEpoch = nCurEpoch;
158 m_cvDataReady.notify_one();
160 m_DisposeThread->join();
163 /// Start reclamation cycle
165 This function is called by \ref general_threaded object
166 to notify the reclamation thread about new work.
167 \p buf buffer contains retired objects ready to free.
168 The reclamation thread should free all \p buf objects
169 \p m_nEpoch field of which is no more than \p nCurEpoch.
171 If \p bSync parameter is \p true the calling thread should
172 wait until disposing done.
174 void dispose( buffer_type& buf, uint64_t nCurEpoch, bool bSync )
176 unique_lock lock( m_Mutex );
178 // wait while disposing pass done
180 m_cvReady.wait( lock );
186 m_nCurEpoch = nCurEpoch;
189 m_cvDataReady.notify_one();
193 m_cvReady.wait( lock );
197 }} // namespace cds::urcu
199 #endif // #ifdef _CDS_URCU_DISPOSE_THREAD_H