From: khizmax Date: Sat, 27 Sep 2014 14:24:33 +0000 (+0400) Subject: Move cds/intrusive/single_link_struct.h to cds/intrusive/details directory X-Git-Tag: v2.0.0~285 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b18cd709db95407e9e6b0ead1955f11f1c6560d4;p=libcds.git Move cds/intrusive/single_link_struct.h to cds/intrusive/details directory --- diff --git a/cds/intrusive/basket_queue.h b/cds/intrusive/basket_queue.h index 572feb43..3a2d4aed 100644 --- a/cds/intrusive/basket_queue.h +++ b/cds/intrusive/basket_queue.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/cds/intrusive/details/single_link_struct.h b/cds/intrusive/details/single_link_struct.h new file mode 100644 index 00000000..d3e3cc85 --- /dev/null +++ b/cds/intrusive/details/single_link_struct.h @@ -0,0 +1,227 @@ +//$$CDS-header$$ + +#ifndef __CDS_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H +#define __CDS_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H + +#include +#include +#include +#include + +namespace cds { namespace intrusive { + + /// Definitions common for single-linked data structures + /** @ingroup cds_intrusive_helper + */ + namespace single_link { + + /// Container's node + /** + Template parameters: + - GC - garbage collector used + - Tag - a tag used to distinguish between different implementation + */ + template + struct node: public GC::container_node + { + typedef GC gc ; ///< Garbage collector + typedef Tag tag ; ///< tag + + typedef typename gc::template atomic_ref atomic_node_ptr ; ///< atomic pointer + + /// Rebind node for other template parameters + template + struct rebind { + typedef node other ; ///< Rebinding result + }; + + atomic_node_ptr m_pNext ; ///< pointer to the next node in the container + + node() + : m_pNext( nullptr ) + {} + }; + + //@cond + // Specialization for HRC GC + template + struct node< gc::HRC, Tag>: public gc::HRC::container_node + { + typedef gc::HRC gc ; ///< Garbage collector + typedef Tag tag ; ///< tag + + typedef gc::atomic_ref atomic_node_ptr ; ///< atomic pointer + atomic_node_ptr m_pNext ; ///< pointer to the next node in the container + + node() + : m_pNext( nullptr ) + {} + + protected: + virtual void cleanUp( cds::gc::hrc::ThreadGC * pGC ) + { + assert( pGC != nullptr ); + typename gc::GuardArray<2> aGuards( *pGC ); + + while ( true ) { + node * pNext = aGuards.protect( 0, m_pNext ); + if ( pNext && pNext->m_bDeleted.load(atomics::memory_order_acquire) ) { + node * p = aGuards.protect( 1, pNext->m_pNext ); + m_pNext.compare_exchange_strong( pNext, p, atomics::memory_order_acquire, atomics::memory_order_relaxed ); + continue; + } + else { + break; + } + } + } + + virtual void terminate( cds::gc::hrc::ThreadGC * pGC, bool bConcurrent ) + { + if ( bConcurrent ) { + node * pNext = m_pNext.load(atomics::memory_order_relaxed); + do {} while ( !m_pNext.compare_exchange_weak( pNext, nullptr, atomics::memory_order_release, atomics::memory_order_relaxed ) ); + } + else { + m_pNext.store( nullptr, atomics::memory_order_relaxed ); + } + } + }; + //@endcond + + //@cond + struct default_hook { + typedef cds::gc::default_gc gc; + typedef opt::none tag; + }; + //@endcond + + //@cond + template < typename HookType, typename... Options> + struct hook + { + typedef typename opt::make_options< default_hook, Options...>::type options; + typedef typename options::gc gc; + typedef typename options::tag tag; + typedef node node_type; + typedef HookType hook_type; + }; + //@endcond + + + /// Base hook + /** + \p Options are: + - opt::gc - garbage collector used. + - opt::tag - tag + */ + template < typename... Options > + struct base_hook: public hook< opt::base_hook_tag, Options... > + {}; + + /// Member hook + /** + \p MemberOffset defines offset in bytes of \ref node member into your structure. + Use \p offsetof macro to define \p MemberOffset + + \p Options are: + - opt::gc - garbage collector used. + - opt::tag - tag + */ + template < size_t MemberOffset, typename... Options > + struct member_hook: public hook< opt::member_hook_tag, Options... > + { + //@cond + static const size_t c_nMemberOffset = MemberOffset; + //@endcond + }; + + /// Traits hook + /** + \p NodeTraits defines type traits for node. + See \ref node_traits for \p NodeTraits interface description + + \p Options are: + - opt::gc - garbage collector used. + - opt::tag - tag + */ + template + struct traits_hook: public hook< opt::traits_hook_tag, Options... > + { + //@cond + typedef NodeTraits node_traits; + //@endcond + }; + + /// Check link + template + struct link_checker { + //@cond + typedef Node node_type; + //@endcond + + /// Checks if the link field of node \p pNode is \p nullptr + /** + An asserting is generated if \p pNode link field is not \p nullptr + */ + static void is_empty( const node_type * pNode ) + { + assert( pNode->m_pNext.load( atomics::memory_order_relaxed ) == nullptr ); + } + }; + + //@cond + template + struct link_checker_selector; + + template + struct link_checker_selector< gc::HRC, Node, opt::never_check_link > + { + typedef link_checker type; + }; + + template + struct link_checker_selector< gc::HRC, Node, opt::debug_check_link > + { + typedef link_checker type; + }; + + template + struct link_checker_selector< GC, Node, opt::never_check_link > + { + typedef intrusive::opt::v::empty_link_checker type; + }; + + template + struct link_checker_selector< GC, Node, opt::debug_check_link > + { +# ifdef _DEBUG + typedef link_checker type; +# else + typedef intrusive::opt::v::empty_link_checker type; +# endif + }; + + template + struct link_checker_selector< GC, Node, opt::always_check_link > + { + typedef link_checker type; + }; + //@endcond + + /// Metafunction for selecting appropriate link checking policy + template < typename Node, opt::link_check_type LinkType > + struct get_link_checker + { + //@cond + typedef typename link_checker_selector< typename Node::gc, Node, LinkType>::type type; + //@endcond + }; + + } // namespace single_link + +}} // namespace cds::intrusive + + + +#endif // #ifndef __CDS_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H diff --git a/cds/intrusive/msqueue.h b/cds/intrusive/msqueue.h index bbf9857f..f81a1ad6 100644 --- a/cds/intrusive/msqueue.h +++ b/cds/intrusive/msqueue.h @@ -4,7 +4,7 @@ #define __CDS_INTRUSIVE_MSQUEUE_H #include -#include +#include #include #include diff --git a/cds/intrusive/single_link_struct.h b/cds/intrusive/single_link_struct.h deleted file mode 100644 index 960095f6..00000000 --- a/cds/intrusive/single_link_struct.h +++ /dev/null @@ -1,227 +0,0 @@ -//$$CDS-header$$ - -#ifndef __CDS_INTRUSIVE_SINGLE_LINK_STRUCT_H -#define __CDS_INTRUSIVE_SINGLE_LINK_STRUCT_H - -#include -#include -#include -#include - -namespace cds { namespace intrusive { - - /// Definitions common for single-linked data structures - /** @ingroup cds_intrusive_helper - */ - namespace single_link { - - /// Container's node - /** - Template parameters: - - GC - garbage collector used - - Tag - a tag used to distinguish between different implementation - */ - template - struct node: public GC::container_node - { - typedef GC gc ; ///< Garbage collector - typedef Tag tag ; ///< tag - - typedef typename gc::template atomic_ref atomic_node_ptr ; ///< atomic pointer - - /// Rebind node for other template parameters - template - struct rebind { - typedef node other ; ///< Rebinding result - }; - - atomic_node_ptr m_pNext ; ///< pointer to the next node in the container - - node() - : m_pNext( nullptr ) - {} - }; - - //@cond - // Specialization for HRC GC - template - struct node< gc::HRC, Tag>: public gc::HRC::container_node - { - typedef gc::HRC gc ; ///< Garbage collector - typedef Tag tag ; ///< tag - - typedef gc::atomic_ref atomic_node_ptr ; ///< atomic pointer - atomic_node_ptr m_pNext ; ///< pointer to the next node in the container - - node() - : m_pNext( nullptr ) - {} - - protected: - virtual void cleanUp( cds::gc::hrc::ThreadGC * pGC ) - { - assert( pGC != nullptr ); - typename gc::GuardArray<2> aGuards( *pGC ); - - while ( true ) { - node * pNext = aGuards.protect( 0, m_pNext ); - if ( pNext && pNext->m_bDeleted.load(atomics::memory_order_acquire) ) { - node * p = aGuards.protect( 1, pNext->m_pNext ); - m_pNext.compare_exchange_strong( pNext, p, atomics::memory_order_acquire, atomics::memory_order_relaxed ); - continue; - } - else { - break; - } - } - } - - virtual void terminate( cds::gc::hrc::ThreadGC * pGC, bool bConcurrent ) - { - if ( bConcurrent ) { - node * pNext = m_pNext.load(atomics::memory_order_relaxed); - do {} while ( !m_pNext.compare_exchange_weak( pNext, nullptr, atomics::memory_order_release, atomics::memory_order_relaxed ) ); - } - else { - m_pNext.store( nullptr, atomics::memory_order_relaxed ); - } - } - }; - //@endcond - - //@cond - struct default_hook { - typedef cds::gc::default_gc gc; - typedef opt::none tag; - }; - //@endcond - - //@cond - template < typename HookType, typename... Options> - struct hook - { - typedef typename opt::make_options< default_hook, Options...>::type options; - typedef typename options::gc gc; - typedef typename options::tag tag; - typedef node node_type; - typedef HookType hook_type; - }; - //@endcond - - - /// Base hook - /** - \p Options are: - - opt::gc - garbage collector used. - - opt::tag - tag - */ - template < typename... Options > - struct base_hook: public hook< opt::base_hook_tag, Options... > - {}; - - /// Member hook - /** - \p MemberOffset defines offset in bytes of \ref node member into your structure. - Use \p offsetof macro to define \p MemberOffset - - \p Options are: - - opt::gc - garbage collector used. - - opt::tag - tag - */ - template < size_t MemberOffset, typename... Options > - struct member_hook: public hook< opt::member_hook_tag, Options... > - { - //@cond - static const size_t c_nMemberOffset = MemberOffset; - //@endcond - }; - - /// Traits hook - /** - \p NodeTraits defines type traits for node. - See \ref node_traits for \p NodeTraits interface description - - \p Options are: - - opt::gc - garbage collector used. - - opt::tag - tag - */ - template - struct traits_hook: public hook< opt::traits_hook_tag, Options... > - { - //@cond - typedef NodeTraits node_traits; - //@endcond - }; - - /// Check link - template - struct link_checker { - //@cond - typedef Node node_type; - //@endcond - - /// Checks if the link field of node \p pNode is \p nullptr - /** - An asserting is generated if \p pNode link field is not \p nullptr - */ - static void is_empty( const node_type * pNode ) - { - assert( pNode->m_pNext.load( atomics::memory_order_relaxed ) == nullptr ); - } - }; - - //@cond - template - struct link_checker_selector; - - template - struct link_checker_selector< gc::HRC, Node, opt::never_check_link > - { - typedef link_checker type; - }; - - template - struct link_checker_selector< gc::HRC, Node, opt::debug_check_link > - { - typedef link_checker type; - }; - - template - struct link_checker_selector< GC, Node, opt::never_check_link > - { - typedef intrusive::opt::v::empty_link_checker type; - }; - - template - struct link_checker_selector< GC, Node, opt::debug_check_link > - { -# ifdef _DEBUG - typedef link_checker type; -# else - typedef intrusive::opt::v::empty_link_checker type; -# endif - }; - - template - struct link_checker_selector< GC, Node, opt::always_check_link > - { - typedef link_checker type; - }; - //@endcond - - /// Metafunction for selecting appropriate link checking policy - template < typename Node, opt::link_check_type LinkType > - struct get_link_checker - { - //@cond - typedef typename link_checker_selector< typename Node::gc, Node, LinkType>::type type; - //@endcond - }; - - } // namespace single_link - -}} // namespace cds::intrusive - - - -#endif // #ifndef __CDS_INTRUSIVE_SINGLE_LINK_STRUCT_H diff --git a/cds/intrusive/treiber_stack.h b/cds/intrusive/treiber_stack.h index ba69873c..48d17919 100644 --- a/cds/intrusive/treiber_stack.h +++ b/cds/intrusive/treiber_stack.h @@ -4,7 +4,7 @@ #define __CDS_INTRUSIVE_TREIBER_STACK_H #include -#include +#include #include #include #include diff --git a/projects/Win/vc12/cds.vcxproj b/projects/Win/vc12/cds.vcxproj index e417beaa..b1f56060 100644 --- a/projects/Win/vc12/cds.vcxproj +++ b/projects/Win/vc12/cds.vcxproj @@ -738,6 +738,7 @@ + @@ -938,7 +939,6 @@ - diff --git a/projects/Win/vc12/cds.vcxproj.filters b/projects/Win/vc12/cds.vcxproj.filters index ed80d9e2..27e6442c 100644 --- a/projects/Win/vc12/cds.vcxproj.filters +++ b/projects/Win/vc12/cds.vcxproj.filters @@ -611,9 +611,6 @@ Header Files\cds\intrusive - - Header Files\cds\intrusive - Header Files\cds\intrusive @@ -1277,5 +1274,8 @@ Header Files\cds\compiler\gcc\x86 + + Header Files\cds\intrusive\details + \ No newline at end of file diff --git a/tests/test-hdr/queue/hdr_intrusive_singlelink_node.h b/tests/test-hdr/queue/hdr_intrusive_singlelink_node.h index e6ecc3ae..a3d2f94f 100644 --- a/tests/test-hdr/queue/hdr_intrusive_singlelink_node.h +++ b/tests/test-hdr/queue/hdr_intrusive_singlelink_node.h @@ -3,7 +3,7 @@ #ifndef CDSTEST_HDR_TEST_INTRUSIVE_SINGLELINK_NODE_H #define CDSTEST_HDR_TEST_INTRUSIVE_SINGLELINK_NODE_H -#include +#include namespace queue { namespace ci = cds::intrusive; diff --git a/tests/test-hdr/stack/hdr_intrusive_treiber_stack.h b/tests/test-hdr/stack/hdr_intrusive_treiber_stack.h index 41077a08..5d3f312d 100644 --- a/tests/test-hdr/stack/hdr_intrusive_treiber_stack.h +++ b/tests/test-hdr/stack/hdr_intrusive_treiber_stack.h @@ -1,7 +1,7 @@ //$$CDS-header$$ #include "cppunit/cppunit_proxy.h" -#include +#include namespace stack {