| 276 | } |
| 277 | |
| 278 | CDS_EXPORT_API smr::thread_record* smr::alloc_thread_data() |
| 279 | { |
| 280 | thread_record * hprec = nullptr; |
| 281 | const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; |
| 282 | const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id(); |
| 283 | |
| 284 | // First try to reuse a free (non-active) DHP record |
| 285 | for ( hprec = thread_list_.load( atomics::memory_order_acquire ); hprec; hprec = hprec->next_ ) { |
| 286 | cds::OS::ThreadId thId = nullThreadId; |
| 287 | if ( !hprec->thread_id_.compare_exchange_strong( thId, curThreadId, atomics::memory_order_relaxed, atomics::memory_order_relaxed )) |
| 288 | continue; |
| 289 | hprec->free_.store( false, atomics::memory_order_release ); |
| 290 | break; |
| 291 | } |
| 292 | |
| 293 | if ( !hprec ) { |
| 294 | // No HP records available for reuse |
| 295 | // Allocate and push a new HP record |
| 296 | hprec = create_thread_data(); |
| 297 | hprec->thread_id_.store( curThreadId, atomics::memory_order_relaxed ); |
| 298 | |
| 299 | thread_record* pOldHead = thread_list_.load( atomics::memory_order_acquire ); |
| 300 | do { |
| 301 | hprec->next_ = pOldHead; |
| 302 | } while ( !thread_list_.compare_exchange_weak( pOldHead, hprec, atomics::memory_order_release, atomics::memory_order_acquire )); |
| 303 | } |
| 304 | |
| 305 | hprec->hazards_.init(); |
| 306 | hprec->retired_.init(); |
| 307 | |
| 308 | return hprec; |
| 309 | } |
| 310 | |
| 311 | CDS_EXPORT_API void smr::free_thread_data( thread_record* pRec, bool callHelpScan ) |
| 312 | { |
no test coverage detected