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 ) {
106 CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
108 CDS_TSAN_ANNOTATE_IGNORE_RW_END;
121 : m_pBuffer( nullptr )
128 public: // methods called from any thread
129 /// Start reclamation thread
131 This function is called by \ref general_threaded object to start
132 internal reclamation thread.
136 m_DisposeThread = new (m_threadPlaceholder) dispose_thread_starter( this );
139 /// Stop reclamation thread
141 This function is called by \ref general_threaded object to
142 start reclamation cycle and then to terminate reclamation thread.
144 \p buf buffer contains retired objects ready to free.
146 void stop( buffer_type& buf, uint64_t nCurEpoch )
149 unique_lock lock( m_Mutex );
151 // wait while retiring pass done
153 m_cvReady.wait( lock );
155 // give a new work and set stop flag
157 m_nCurEpoch = nCurEpoch;
160 m_cvDataReady.notify_one();
162 m_DisposeThread->join();
165 /// Start reclamation cycle
167 This function is called by \ref general_threaded object
168 to notify the reclamation thread about new work.
169 \p buf buffer contains retired objects ready to free.
170 The reclamation thread should free all \p buf objects
171 \p m_nEpoch field of which is no more than \p nCurEpoch.
173 If \p bSync parameter is \p true the calling thread should
174 wait until disposing done.
176 void dispose( buffer_type& buf, uint64_t nCurEpoch, bool bSync )
178 unique_lock lock( m_Mutex );
180 // wait while disposing pass done
182 m_cvReady.wait( lock );
188 m_nCurEpoch = nCurEpoch;
191 m_cvDataReady.notify_one();
195 m_cvReady.wait( lock );
199 }} // namespace cds::urcu
201 #endif // #ifdef CDSLIB_URCU_DISPOSE_THREAD_H