| 175 | } |
| 176 | |
| 177 | CDS_EXPORT_API smr::~smr() |
| 178 | { |
| 179 | CDS_DEBUG_ONLY( const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; ) |
| 180 | CDS_DEBUG_ONLY( const cds::OS::ThreadId mainThreadId = cds::OS::get_current_thread_id(); ) |
| 181 | |
| 182 | CDS_HPSTAT( statistics( s_postmortem_stat )); |
| 183 | |
| 184 | thread_record* pHead = thread_list_.load( atomics::memory_order_relaxed ); |
| 185 | thread_list_.store( nullptr, atomics::memory_order_release ); |
| 186 | |
| 187 | thread_record* pNext = nullptr; |
| 188 | for ( thread_record* hprec = pHead; hprec; hprec = pNext ) |
| 189 | { |
| 190 | assert( hprec->thread_id_.load( atomics::memory_order_relaxed ) == nullThreadId |
| 191 | || hprec->thread_id_.load( atomics::memory_order_relaxed ) == mainThreadId ); |
| 192 | |
| 193 | retired_array& retired = hprec->retired_; |
| 194 | |
| 195 | // delete retired data |
| 196 | for ( retired_block* block = retired.list_head_; block && block != retired.current_block_; block = block->next_ ) { |
| 197 | for ( retired_ptr* p = block->first(); p != block->last(); ++p ) { |
| 198 | p->free(); |
| 199 | CDS_HPSTAT( ++s_postmortem_stat.free_count ); |
| 200 | } |
| 201 | } |
| 202 | if ( retired.current_block_ ) { |
| 203 | for ( retired_ptr* p = retired.current_block_->first(); p != retired.current_cell_; ++p ) { |
| 204 | p->free(); |
| 205 | CDS_HPSTAT( ++s_postmortem_stat.free_count ); |
| 206 | } |
| 207 | } |
| 208 | hprec->retired_.fini(); |
| 209 | hprec->hazards_.clear(); |
| 210 | |
| 211 | pNext = hprec->next_; |
| 212 | hprec->free_.store( true, atomics::memory_order_relaxed ); |
| 213 | destroy_thread_data( hprec ); |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | /*static*/ CDS_EXPORT_API void smr::attach_thread() |
| 218 | { |