timed_utils.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2023-2024. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_INTERPROCESS_TIMED_UTILS_HPP
  11. #define BOOST_INTERPROCESS_TIMED_UTILS_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #
  16. #if defined(BOOST_HAS_PRAGMA_ONCE)
  17. # pragma once
  18. #endif
  19. #include <boost/interprocess/detail/config_begin.hpp>
  20. #include <boost/interprocess/detail/workaround.hpp>
  21. #include <boost/interprocess/detail/timed_utils.hpp>
  22. //!\file
  23. //!Describes some simple time-related utilities that can be used to call synchronization primitive and ipc methods that required
  24. //!waiting until the resource is signalled or a timeout expires.
  25. //!
  26. //! These utilities are provided for those users that want to avoid dependence on std::chrono or boost::chrono or boost::date_time
  27. //! and just want to implement simple portable waits.
  28. namespace boost {
  29. namespace interprocess {
  30. //!Describes a simple duration type with microsecond resolution that can be used with the ustime time-point utility to call timed functions
  31. //! of Boost.Interprocess' synchronization classes that expect a time-point (timed_wait, wait_until, timed_lock, lock_until...)
  32. class ustime;
  33. //!Describes a simple duration type with microsecond resolution that can be used with the ustime time-point utility to call timed functions
  34. //! of Boost.Interprocess' synchronization classes that expect a duration type (wait_for, lock_for...)
  35. class usduration
  36. {
  37. public:
  38. friend class ustime;
  39. //!Constructs a duration type that stores microseconds from
  40. //!the passed count
  41. explicit usduration(boost::uint64_t microsecs = 0u)
  42. : m_microsecs(microsecs)
  43. {}
  44. //!Returns the stored microsecond
  45. //!count
  46. boost::uint64_t get_microsecs() const
  47. { return m_microsecs; }
  48. bool operator < (const usduration &other) const
  49. { return m_microsecs < other.m_microsecs; }
  50. bool operator > (const usduration &other) const
  51. { return m_microsecs > other.m_microsecs; }
  52. bool operator <= (const usduration &other) const
  53. { return m_microsecs <= other.m_microsecs; }
  54. bool operator >= (const usduration &other) const
  55. { return m_microsecs >= other.m_microsecs; }
  56. private:
  57. boost::uint64_t m_microsecs;
  58. };
  59. class ustime
  60. {
  61. public:
  62. //!Constructs a time point that is "microsecs" duration away
  63. //!from the epoch of the system
  64. explicit ustime(boost::uint64_t microsecs = 0u)
  65. : m_microsecs(microsecs)
  66. {}
  67. ustime &operator += (const usduration &other)
  68. { m_microsecs += other.m_microsecs; return *this; }
  69. ustime operator + (const usduration &other)
  70. { ustime r(*this); r += other; return r; }
  71. ustime &operator -= (const usduration &other)
  72. { m_microsecs -= other.m_microsecs; return *this; }
  73. ustime operator - (const usduration &other)
  74. { ustime r(*this); r -= other; return r; }
  75. friend usduration operator - (const ustime &l, const ustime &r)
  76. { return usduration(l.m_microsecs - r.m_microsecs); }
  77. bool operator < (const ustime &other) const
  78. { return m_microsecs < other.m_microsecs; }
  79. bool operator > (const ustime &other) const
  80. { return m_microsecs > other.m_microsecs; }
  81. bool operator <= (const ustime &other) const
  82. { return m_microsecs <= other.m_microsecs; }
  83. bool operator >= (const ustime &other) const
  84. { return m_microsecs >= other.m_microsecs; }
  85. //!Returns the stored count
  86. //!that represents microseconds from epoch
  87. boost::uint64_t get_microsecs() const
  88. { return m_microsecs; }
  89. private:
  90. boost::uint64_t m_microsecs;
  91. };
  92. //!Utility that returns a duration from
  93. //!a seconds count
  94. inline usduration usduration_from_seconds(boost::uint64_t sec)
  95. { return usduration(sec*uint64_t(1000000u)); }
  96. //!Utility that returns a duration from
  97. //!a milliseconds count
  98. inline usduration usduration_from_milliseconds(boost::uint64_t millisec)
  99. { return usduration(millisec*1000u); }
  100. //!Utility that returns a time_point in the future that is "msecs"
  101. //!milliseconds in the future from now.
  102. inline ustime ustime_delay_milliseconds(unsigned msecs)
  103. {
  104. return ustime(ipcdetail::universal_time_u64_us()) + usduration(msecs*1000u);
  105. }
  106. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  107. namespace ipcdetail {
  108. template<>
  109. class microsec_clock<ustime>
  110. {
  111. public:
  112. typedef ustime time_point;
  113. static ustime universal_time()
  114. { return ustime(universal_time_u64_us()); }
  115. };
  116. // duration_to_usduration
  117. template<class Duration>
  118. inline usduration duration_to_usduration(const Duration &d, typename enable_if_ptime_duration<Duration>::type* = 0)
  119. {
  120. return usduration(static_cast<boost::uint64_t>(d.total_microseconds()));
  121. }
  122. template<class Duration>
  123. inline usduration duration_to_usduration(const Duration &d, typename enable_if_duration<Duration>::type* = 0)
  124. {
  125. const double factor = double(Duration::period::num)*1000000.0/double(Duration::period::den);
  126. return usduration(static_cast<boost::uint64_t>(double(d.count())*factor));
  127. }
  128. inline usduration duration_to_usduration(const usduration &d)
  129. {
  130. return d;
  131. }
  132. // duration_to_ustime
  133. template<class Duration>
  134. inline ustime duration_to_ustime(const Duration &d)
  135. {
  136. return microsec_clock<ustime>::universal_time() + (duration_to_usduration)(d);
  137. }
  138. } //namespace ipcdetail {
  139. #endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  140. } //namespace interprocess {
  141. } //namespace boost {
  142. #include <boost/interprocess/detail/config_end.hpp>
  143. #endif //BOOST_INTERPROCESS_TIMED_UTILS_HPP