#include <cds/intrusive/base.h>
#include <cds/details/marked_ptr.h>
#include <cds/intrusive/queue_stat.h>
-#include <cds/intrusive/single_link_struct.h>
+#include <cds/intrusive/details/single_link_struct.h>
#include <cds/ref.h>
#include <cds/intrusive/details/dummy_node_holder.h>
--- /dev/null
+//$$CDS-header$$
+
+#ifndef __CDS_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H
+#define __CDS_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H
+
+#include <cds/intrusive/base.h>
+#include <cds/gc/default_gc.h>
+#include <cds/cxx11_atomic.h>
+#include <cds/gc/hrc.h>
+
+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 <class GC, typename Tag = opt::none>
+ struct node: public GC::container_node
+ {
+ typedef GC gc ; ///< Garbage collector
+ typedef Tag tag ; ///< tag
+
+ typedef typename gc::template atomic_ref<node> atomic_node_ptr ; ///< atomic pointer
+
+ /// Rebind node for other template parameters
+ template <class GC2, typename Tag2 = tag>
+ struct rebind {
+ typedef node<GC2, Tag2> 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 <typename Tag>
+ struct node< gc::HRC, Tag>: public gc::HRC::container_node
+ {
+ typedef gc::HRC gc ; ///< Garbage collector
+ typedef Tag tag ; ///< tag
+
+ typedef gc::atomic_ref<node> 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<gc, tag> 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 <typename NodeTraits, typename... Options >
+ struct traits_hook: public hook< opt::traits_hook_tag, Options... >
+ {
+ //@cond
+ typedef NodeTraits node_traits;
+ //@endcond
+ };
+
+ /// Check link
+ template <typename Node>
+ 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 <class GC, typename Node, opt::link_check_type LinkType >
+ struct link_checker_selector;
+
+ template <typename Node>
+ struct link_checker_selector< gc::HRC, Node, opt::never_check_link >
+ {
+ typedef link_checker<Node> type;
+ };
+
+ template <typename Node>
+ struct link_checker_selector< gc::HRC, Node, opt::debug_check_link >
+ {
+ typedef link_checker<Node> type;
+ };
+
+ template <typename GC, typename Node>
+ struct link_checker_selector< GC, Node, opt::never_check_link >
+ {
+ typedef intrusive::opt::v::empty_link_checker<Node> type;
+ };
+
+ template <typename GC, typename Node>
+ struct link_checker_selector< GC, Node, opt::debug_check_link >
+ {
+# ifdef _DEBUG
+ typedef link_checker<Node> type;
+# else
+ typedef intrusive::opt::v::empty_link_checker<Node> type;
+# endif
+ };
+
+ template <typename GC, typename Node>
+ struct link_checker_selector< GC, Node, opt::always_check_link >
+ {
+ typedef link_checker<Node> 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
#define __CDS_INTRUSIVE_MSQUEUE_H
#include <type_traits>
-#include <cds/intrusive/single_link_struct.h>
+#include <cds/intrusive/details/single_link_struct.h>
#include <cds/intrusive/queue_stat.h>
#include <cds/intrusive/details/dummy_node_holder.h>
+++ /dev/null
-//$$CDS-header$$
-
-#ifndef __CDS_INTRUSIVE_SINGLE_LINK_STRUCT_H
-#define __CDS_INTRUSIVE_SINGLE_LINK_STRUCT_H
-
-#include <cds/intrusive/base.h>
-#include <cds/gc/default_gc.h>
-#include <cds/cxx11_atomic.h>
-#include <cds/gc/hrc.h>
-
-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 <class GC, typename Tag = opt::none>
- struct node: public GC::container_node
- {
- typedef GC gc ; ///< Garbage collector
- typedef Tag tag ; ///< tag
-
- typedef typename gc::template atomic_ref<node> atomic_node_ptr ; ///< atomic pointer
-
- /// Rebind node for other template parameters
- template <class GC2, typename Tag2 = tag>
- struct rebind {
- typedef node<GC2, Tag2> 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 <typename Tag>
- struct node< gc::HRC, Tag>: public gc::HRC::container_node
- {
- typedef gc::HRC gc ; ///< Garbage collector
- typedef Tag tag ; ///< tag
-
- typedef gc::atomic_ref<node> 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<gc, tag> 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 <typename NodeTraits, typename... Options >
- struct traits_hook: public hook< opt::traits_hook_tag, Options... >
- {
- //@cond
- typedef NodeTraits node_traits;
- //@endcond
- };
-
- /// Check link
- template <typename Node>
- 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 <class GC, typename Node, opt::link_check_type LinkType >
- struct link_checker_selector;
-
- template <typename Node>
- struct link_checker_selector< gc::HRC, Node, opt::never_check_link >
- {
- typedef link_checker<Node> type;
- };
-
- template <typename Node>
- struct link_checker_selector< gc::HRC, Node, opt::debug_check_link >
- {
- typedef link_checker<Node> type;
- };
-
- template <typename GC, typename Node>
- struct link_checker_selector< GC, Node, opt::never_check_link >
- {
- typedef intrusive::opt::v::empty_link_checker<Node> type;
- };
-
- template <typename GC, typename Node>
- struct link_checker_selector< GC, Node, opt::debug_check_link >
- {
-# ifdef _DEBUG
- typedef link_checker<Node> type;
-# else
- typedef intrusive::opt::v::empty_link_checker<Node> type;
-# endif
- };
-
- template <typename GC, typename Node>
- struct link_checker_selector< GC, Node, opt::always_check_link >
- {
- typedef link_checker<Node> 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
#define __CDS_INTRUSIVE_TREIBER_STACK_H
#include <type_traits>
-#include <cds/intrusive/single_link_struct.h>
+#include <cds/intrusive/details/single_link_struct.h>
#include <cds/ref.h>
#include <cds/algo/elimination.h>
#include <cds/opt/buffer.h>
<ClInclude Include="..\..\..\cds\intrusive\cuckoo_set.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\details\dummy_node_holder.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\details\ellen_bintree_base.h" />\r
+ <ClInclude Include="..\..\..\cds\intrusive\details\single_link_struct.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\ellen_bintree_hp.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\ellen_bintree_impl.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\ellen_bintree_ptb.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\optimistic_queue.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\queue_stat.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\segmented_queue.h" />\r
- <ClInclude Include="..\..\..\cds\intrusive\single_link_struct.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\split_list.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\split_list_base.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\split_list_nogc.h" />\r
<ClInclude Include="..\..\..\cds\intrusive\segmented_queue.h">\r
<Filter>Header Files\cds\intrusive</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\..\cds\intrusive\single_link_struct.h">\r
- <Filter>Header Files\cds\intrusive</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\..\cds\intrusive\split_list.h">\r
<Filter>Header Files\cds\intrusive</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\..\cds\compiler\gcc\x86\cxx11_atomic32.h">\r
<Filter>Header Files\cds\compiler\gcc\x86</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\..\..\cds\intrusive\details\single_link_struct.h">\r
+ <Filter>Header Files\cds\intrusive\details</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
#ifndef CDSTEST_HDR_TEST_INTRUSIVE_SINGLELINK_NODE_H
#define CDSTEST_HDR_TEST_INTRUSIVE_SINGLELINK_NODE_H
-#include <cds/intrusive/single_link_struct.h>
+#include <cds/intrusive/details/single_link_struct.h>
namespace queue {
namespace ci = cds::intrusive;
//$$CDS-header$$
#include "cppunit/cppunit_proxy.h"
-#include <cds/intrusive/single_link_struct.h>
+#include <cds/intrusive/details/single_link_struct.h>
namespace stack {