timeval_demo.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // timeval_demo.cpp ----------------------------------------------------------//
  2. // Copyright 2008 Howard Hinnant
  3. // Copyright 2008 Beman Dawes
  4. // Copyright 2009 Vicente J. Botet Escriba
  5. // Copyright (c) Microsoft Corporation 2014
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // See http://www.boost.org/LICENSE_1_0.txt
  8. /*
  9. This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
  10. was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
  11. Many thanks to Howard for making his code available under the Boost license.
  12. The original code was modified to conform to Boost conventions and to section
  13. 20.9 Time utilities [time] of the C++ committee's working paper N2798.
  14. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
  15. time2_demo contained this comment:
  16. Much thanks to Andrei Alexandrescu,
  17. Walter Brown,
  18. Peter Dimov,
  19. Jeff Garland,
  20. Terry Golubiewski,
  21. Daniel Krugler,
  22. Anthony Williams.
  23. */
  24. #define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
  25. #include <boost/chrono/chrono.hpp>
  26. #include <boost/type_traits.hpp>
  27. #include <iostream>
  28. #if defined(BOOST_CHRONO_MAC_API)
  29. #include <sys/time.h> //for gettimeofday and timeval
  30. #endif
  31. #if defined(BOOST_CHRONO_WINDOWS_API)
  32. # include <windows.h>
  33. #endif
  34. #if defined(BOOST_CHRONO_WINDOWS_API)
  35. namespace
  36. {
  37. #if defined UNDER_CE || BOOST_PLAT_WINDOWS_RUNTIME
  38. // Windows CE and Windows store does not define timeval
  39. struct timeval {
  40. long tv_sec; /* seconds */
  41. long tv_usec; /* and microseconds */
  42. };
  43. #endif
  44. int gettimeofday(struct timeval * tp, void *)
  45. {
  46. FILETIME ft;
  47. #if defined(UNDER_CE)
  48. // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
  49. SYSTEMTIME st;
  50. ::GetSystemTime( &st );
  51. ::SystemTimeToFileTime( &st, &ft );
  52. #else
  53. ::GetSystemTimeAsFileTime( &ft ); // never fails
  54. #endif
  55. long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
  56. # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
  57. t -= 116444736000000000LL;
  58. # else
  59. t -= 116444736000000000;
  60. # endif
  61. t /= 10; // microseconds
  62. tp->tv_sec = static_cast<long>( t / 1000000UL);
  63. tp->tv_usec = static_cast<long>( t % 1000000UL);
  64. return 0;
  65. }
  66. } // unnamed namespace
  67. #endif
  68. // timeval clock demo
  69. // Demonstrate the use of a timeval-like struct to be used as the representation
  70. // type for both duraiton and time_point.
  71. namespace timeval_demo
  72. {
  73. class xtime {
  74. private:
  75. long tv_sec;
  76. long tv_usec;
  77. void fixup() {
  78. if (tv_usec < 0) {
  79. tv_usec += 1000000;
  80. --tv_sec;
  81. }
  82. }
  83. public:
  84. explicit xtime(long sec, long usec) {
  85. tv_sec = sec;
  86. tv_usec = usec;
  87. if (tv_usec < 0 || tv_usec >= 1000000) {
  88. tv_sec += tv_usec / 1000000;
  89. tv_usec %= 1000000;
  90. fixup();
  91. }
  92. }
  93. explicit xtime(long long usec)
  94. {
  95. tv_usec = static_cast<long>(usec % 1000000);
  96. tv_sec = static_cast<long>(usec / 1000000);
  97. fixup();
  98. }
  99. // explicit
  100. operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
  101. xtime& operator += (xtime rhs) {
  102. tv_sec += rhs.tv_sec;
  103. tv_usec += rhs.tv_usec;
  104. if (tv_usec >= 1000000) {
  105. tv_usec -= 1000000;
  106. ++tv_sec;
  107. }
  108. return *this;
  109. }
  110. xtime& operator -= (xtime rhs) {
  111. tv_sec -= rhs.tv_sec;
  112. tv_usec -= rhs.tv_usec;
  113. fixup();
  114. return *this;
  115. }
  116. xtime& operator %= (xtime rhs) {
  117. long long t = tv_sec * 1000000 + tv_usec;
  118. long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
  119. t %= r;
  120. tv_sec = static_cast<long>(t / 1000000);
  121. tv_usec = static_cast<long>(t % 1000000);
  122. fixup();
  123. return *this;
  124. }
  125. friend xtime operator+(xtime x, xtime y) {return x += y;}
  126. friend xtime operator-(xtime x, xtime y) {return x -= y;}
  127. friend xtime operator%(xtime x, xtime y) {return x %= y;}
  128. friend bool operator==(xtime x, xtime y)
  129. { return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
  130. friend bool operator<(xtime x, xtime y) {
  131. if (x.tv_sec == y.tv_sec)
  132. return (x.tv_usec < y.tv_usec);
  133. return (x.tv_sec < y.tv_sec);
  134. }
  135. friend bool operator!=(xtime x, xtime y) { return !(x == y); }
  136. friend bool operator> (xtime x, xtime y) { return y < x; }
  137. friend bool operator<=(xtime x, xtime y) { return !(y < x); }
  138. friend bool operator>=(xtime x, xtime y) { return !(x < y); }
  139. friend std::ostream& operator<<(std::ostream& os, xtime x)
  140. {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
  141. };
  142. class xtime_clock
  143. {
  144. public:
  145. typedef xtime rep;
  146. typedef boost::micro period;
  147. typedef boost::chrono::duration<rep, period> duration;
  148. typedef boost::chrono::time_point<xtime_clock> time_point;
  149. static time_point now();
  150. };
  151. xtime_clock::time_point
  152. xtime_clock::now()
  153. {
  154. #if defined(BOOST_CHRONO_WINDOWS_API)
  155. timeval tv;
  156. gettimeofday(&tv, 0);
  157. xtime xt( tv.tv_sec, tv.tv_usec);
  158. return time_point(duration(xt));
  159. #elif defined(BOOST_CHRONO_MAC_API)
  160. timeval tv;
  161. gettimeofday(&tv, 0);
  162. xtime xt( tv.tv_sec, tv.tv_usec);
  163. return time_point(duration(xt));
  164. #elif defined(BOOST_CHRONO_POSIX_API)
  165. //time_point t(0,0);
  166. timespec ts;
  167. ::clock_gettime( CLOCK_REALTIME, &ts );
  168. xtime xt( ts.tv_sec, ts.tv_nsec/1000);
  169. return time_point(duration(xt));
  170. #endif // POSIX
  171. }
  172. void test_xtime_clock()
  173. {
  174. using namespace boost::chrono;
  175. std::cout << "timeval_demo system clock test\n";
  176. std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
  177. std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
  178. std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
  179. xtime_clock::duration delay(milliseconds(5));
  180. xtime_clock::time_point start = xtime_clock::now();
  181. while (xtime_clock::now() - start <= delay)
  182. {
  183. }
  184. xtime_clock::time_point stop = xtime_clock::now();
  185. xtime_clock::duration elapsed = stop - start;
  186. std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
  187. }
  188. } // timeval_demo
  189. int main()
  190. {
  191. timeval_demo::test_xtime_clock();
  192. return 0;
  193. }