tagged_ptr_dcas.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // tagged pointer, for aba prevention
  2. //
  3. // Copyright (C) 2008, 2016 Tim Blechmann
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED
  9. #define BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED
  10. #include <cstddef> /* for std::size_t */
  11. #include <limits>
  12. #include <boost/predef.h>
  13. namespace boost {
  14. namespace lockfree {
  15. namespace detail {
  16. template <class T>
  17. class
  18. #if BOOST_COMP_MSVC && BOOST_ARCH_X86_64
  19. BOOST_ALIGNMENT(16)
  20. #elif BOOST_COMP_MSVC && BOOST_ARCH_X86_32
  21. BOOST_ALIGNMENT(8)
  22. #else
  23. BOOST_ALIGNMENT(2 * sizeof(void*))
  24. #endif
  25. tagged_ptr
  26. {
  27. public:
  28. typedef std::size_t tag_t;
  29. /** uninitialized constructor */
  30. tagged_ptr(void) BOOST_NOEXCEPT//: ptr(0), tag(0)
  31. {}
  32. #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
  33. tagged_ptr(tagged_ptr const & p):
  34. ptr(p.ptr), tag(p.tag)
  35. {}
  36. #else
  37. tagged_ptr(tagged_ptr const & p) = default;
  38. #endif
  39. explicit tagged_ptr(T * p, tag_t t = 0):
  40. ptr(p), tag(t)
  41. {}
  42. /** unsafe set operation */
  43. /* @{ */
  44. #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
  45. tagged_ptr & operator= (tagged_ptr const & p)
  46. {
  47. set(p.ptr, p.tag);
  48. return *this;
  49. }
  50. #else
  51. tagged_ptr & operator= (tagged_ptr const & p) = default;
  52. #endif
  53. void set(T * p, tag_t t)
  54. {
  55. ptr = p;
  56. tag = t;
  57. }
  58. /* @} */
  59. /** comparing semantics */
  60. /* @{ */
  61. bool operator== (volatile tagged_ptr const & p) const
  62. {
  63. return (ptr == p.ptr) && (tag == p.tag);
  64. }
  65. bool operator!= (volatile tagged_ptr const & p) const
  66. {
  67. return !operator==(p);
  68. }
  69. /* @} */
  70. /** pointer access */
  71. /* @{ */
  72. T * get_ptr(void) const
  73. {
  74. return ptr;
  75. }
  76. void set_ptr(T * p)
  77. {
  78. ptr = p;
  79. }
  80. /* @} */
  81. /** tag access */
  82. /* @{ */
  83. tag_t get_tag() const
  84. {
  85. return tag;
  86. }
  87. tag_t get_next_tag() const
  88. {
  89. tag_t next = (get_tag() + 1) & (std::numeric_limits<tag_t>::max)();
  90. return next;
  91. }
  92. void set_tag(tag_t t)
  93. {
  94. tag = t;
  95. }
  96. /* @} */
  97. /** smart pointer support */
  98. /* @{ */
  99. T & operator*() const
  100. {
  101. return *ptr;
  102. }
  103. T * operator->() const
  104. {
  105. return ptr;
  106. }
  107. operator bool(void) const
  108. {
  109. return ptr != 0;
  110. }
  111. /* @} */
  112. protected:
  113. T * ptr;
  114. tag_t tag;
  115. };
  116. } /* namespace detail */
  117. } /* namespace lockfree */
  118. } /* namespace boost */
  119. #endif /* BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED */