tagged_ptr_ptrcompression.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // tagged pointer, for aba prevention
  2. //
  3. // Copyright (C) 2008, 2009, 2016 Tim Blechmann, based on code by Cory Nelson
  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_PTRCOMPRESSION_HPP_INCLUDED
  9. #define BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED
  10. #include <cstddef> /* for std::size_t */
  11. #include <limits>
  12. #include <boost/cstdint.hpp>
  13. #include <boost/predef.h>
  14. namespace boost {
  15. namespace lockfree {
  16. namespace detail {
  17. #if BOOST_ARCH_X86_64 || defined (__aarch64__)
  18. template <class T>
  19. class tagged_ptr
  20. {
  21. typedef boost::uint64_t compressed_ptr_t;
  22. public:
  23. typedef boost::uint16_t tag_t;
  24. private:
  25. union cast_unit
  26. {
  27. compressed_ptr_t value;
  28. tag_t tag[4];
  29. };
  30. static const int tag_index = 3;
  31. static const compressed_ptr_t ptr_mask = 0xffffffffffffUL; //(1L<<48L)-1;
  32. static T* extract_ptr(volatile compressed_ptr_t const & i)
  33. {
  34. return (T*)(i & ptr_mask);
  35. }
  36. static tag_t extract_tag(volatile compressed_ptr_t const & i)
  37. {
  38. cast_unit cu;
  39. cu.value = i;
  40. return cu.tag[tag_index];
  41. }
  42. static compressed_ptr_t pack_ptr(T * ptr, tag_t tag)
  43. {
  44. cast_unit ret;
  45. ret.value = compressed_ptr_t(ptr);
  46. ret.tag[tag_index] = tag;
  47. return ret.value;
  48. }
  49. public:
  50. /** uninitialized constructor */
  51. tagged_ptr(void) BOOST_NOEXCEPT//: ptr(0), tag(0)
  52. {}
  53. /** copy constructor */
  54. #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
  55. tagged_ptr(tagged_ptr const & p):
  56. ptr(p.ptr)
  57. {}
  58. #else
  59. tagged_ptr(tagged_ptr const & p) = default;
  60. #endif
  61. explicit tagged_ptr(T * p, tag_t t = 0):
  62. ptr(pack_ptr(p, t))
  63. {}
  64. /** unsafe set operation */
  65. /* @{ */
  66. #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
  67. tagged_ptr & operator= (tagged_ptr const & p)
  68. {
  69. ptr = p.ptr;
  70. return *this;
  71. }
  72. #else
  73. tagged_ptr & operator= (tagged_ptr const & p) = default;
  74. #endif
  75. void set(T * p, tag_t t)
  76. {
  77. ptr = pack_ptr(p, t);
  78. }
  79. /* @} */
  80. /** comparing semantics */
  81. /* @{ */
  82. bool operator== (volatile tagged_ptr const & p) const
  83. {
  84. return (ptr == p.ptr);
  85. }
  86. bool operator!= (volatile tagged_ptr const & p) const
  87. {
  88. return !operator==(p);
  89. }
  90. /* @} */
  91. /** pointer access */
  92. /* @{ */
  93. T * get_ptr() const
  94. {
  95. return extract_ptr(ptr);
  96. }
  97. void set_ptr(T * p)
  98. {
  99. tag_t tag = get_tag();
  100. ptr = pack_ptr(p, tag);
  101. }
  102. /* @} */
  103. /** tag access */
  104. /* @{ */
  105. tag_t get_tag() const
  106. {
  107. return extract_tag(ptr);
  108. }
  109. tag_t get_next_tag() const
  110. {
  111. tag_t next = (get_tag() + 1u) & (std::numeric_limits<tag_t>::max)();
  112. return next;
  113. }
  114. void set_tag(tag_t t)
  115. {
  116. T * p = get_ptr();
  117. ptr = pack_ptr(p, t);
  118. }
  119. /* @} */
  120. /** smart pointer support */
  121. /* @{ */
  122. T & operator*() const
  123. {
  124. return *get_ptr();
  125. }
  126. T * operator->() const
  127. {
  128. return get_ptr();
  129. }
  130. operator bool(void) const
  131. {
  132. return get_ptr() != 0;
  133. }
  134. /* @} */
  135. protected:
  136. compressed_ptr_t ptr;
  137. };
  138. #else
  139. #error unsupported platform
  140. #endif
  141. } /* namespace detail */
  142. } /* namespace lockfree */
  143. } /* namespace boost */
  144. #endif /* BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED */