rename michael_kvlist_pth.h to michael_kvlist_dhp.h
[libcds.git] / cds / intrusive / michael_list_hrc.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_INTRUSIVE_MICHAEL_LIST_HRC_H
4 #define __CDS_INTRUSIVE_MICHAEL_LIST_HRC_H
5
6 #include <cds/intrusive/impl/michael_list.h>
7 #include <cds/gc/hrc.h>
8
9 namespace cds { namespace intrusive { namespace michael_list {
10     //@cond
11     // Specialization for HRC GC
12     template <typename Tag>
13     struct node< gc::HRC, Tag>: public gc::HRC::container_node
14     {
15         typedef gc::HRC gc  ;   ///< Garbage collector
16         typedef Tag     tag ;   ///< tag
17
18         typedef cds::details::marked_ptr<node, 1>   marked_ptr         ;   ///< marked pointer
19         typedef typename gc::atomic_marked_ptr< marked_ptr>     atomic_marked_ptr   ;   ///< atomic marked pointer
20         atomic_marked_ptr m_pNext ; ///< pointer to the next node in the stack
21
22         node()
23             : m_pNext( nullptr )
24         {}
25
26     protected:
27         virtual void cleanUp( cds::gc::hrc::ThreadGC * pGC )
28         {
29             assert( pGC );
30             typename gc::GuardArray<2> aGuards( *pGC );
31
32             while ( true ) {
33                 marked_ptr pNextMarked( aGuards.protect( 0, m_pNext ));
34                 node * pNext = pNextMarked.ptr();
35                 if ( pNext && pNext->m_bDeleted.load(atomics::memory_order_acquire) ) {
36                     marked_ptr p = aGuards.protect( 1, pNext->m_pNext );
37                     m_pNext.compare_exchange_strong( pNextMarked, p, atomics::memory_order_acquire, atomics::memory_order_relaxed );
38                     continue;
39                 }
40                 else {
41                     break;
42                 }
43             }
44         }
45
46         virtual void terminate( cds::gc::hrc::ThreadGC * pGC, bool bConcurrent )
47         {
48             if ( bConcurrent ) {
49                 marked_ptr pNext = m_pNext.load(atomics::memory_order_acquire);
50                 do {} while ( !m_pNext.compare_exchange_weak( pNext, marked_ptr(), atomics::memory_order_release, atomics::memory_order_relaxed ) );
51             }
52             else {
53                 m_pNext.store( marked_ptr(), atomics::memory_order_relaxed );
54             }
55         }
56     };
57     //@endcond
58
59
60     //@cond
61     template <typename NODE>
62     struct link_checker_selector< gc::HRC, NODE, opt::never_check_link >
63     {
64         typedef link_checker<NODE>  type;
65     };
66
67     template <typename NODE>
68     struct link_checker_selector< gc::HRC, NODE, opt::debug_check_link >
69     {
70         typedef link_checker<NODE>  type;
71     };
72     //@endcond
73
74 }}}   // namespace cds::intrusive::michael_list
75
76 #endif // #ifndef __CDS_INTRUSIVE_MICHAEL_LIST_HP_H