simulated_thread_interface_demo.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // simulated_thread_interface_demo.cpp ----------------------------------------------------------//
  2. // Copyright 2008 Howard Hinnant
  3. // Copyright 2008 Beman Dawes
  4. // Copyright 2009 Vicente J. Botet Escriba
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // See http://www.boost.org/LICENSE_1_0.txt
  7. /*
  8. This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
  9. was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
  10. Many thanks to Howard for making his code available under the Boost license.
  11. The original code was modified to conform to Boost conventions and to section
  12. 20.9 Time utilities [time] of the C++ committee's working paper N2798.
  13. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
  14. time2_demo contained this comment:
  15. Much thanks to Andrei Alexandrescu,
  16. Walter Brown,
  17. Peter Dimov,
  18. Jeff Garland,
  19. Terry Golubiewski,
  20. Daniel Krugler,
  21. Anthony Williams.
  22. */
  23. #define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
  24. #include <boost/chrono/chrono.hpp>
  25. #include <boost/type_traits.hpp>
  26. #include <iostream>
  27. #include <ostream>
  28. #include <stdexcept>
  29. #include <climits>
  30. //////////////////////////////////////////////////////////
  31. ///////////// simulated thread interface /////////////////
  32. //////////////////////////////////////////////////////////
  33. namespace {
  34. void print_time(boost::chrono::system_clock::time_point t)
  35. {
  36. using namespace boost::chrono;
  37. time_t c_time = system_clock::to_time_t(t);
  38. std::tm* tmptr = std::localtime(&c_time);
  39. system_clock::duration d = t.time_since_epoch();
  40. std::cout << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec
  41. << '.' << (d - duration_cast<seconds>(d)).count();
  42. }
  43. }
  44. namespace boost {
  45. namespace this_thread {
  46. template <class Rep, class Period>
  47. void sleep_for(const boost::chrono::duration<Rep, Period>& d)
  48. {
  49. boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
  50. if (t < d)
  51. ++t;
  52. if (t > boost::chrono::microseconds(0))
  53. std::cout << "sleep_for " << t.count() << " microseconds\n";
  54. }
  55. template <class Clock, class Duration>
  56. void sleep_until(const boost::chrono::time_point<Clock, Duration>& t)
  57. {
  58. using namespace boost::chrono;
  59. typedef time_point<Clock, Duration> Time;
  60. typedef system_clock::time_point SysTime;
  61. if (t > Clock::now())
  62. {
  63. typedef typename boost::common_type<typename Time::duration,
  64. typename SysTime::duration>::type D;
  65. /* auto */ D d = t - Clock::now();
  66. microseconds us = duration_cast<microseconds>(d);
  67. if (us < d)
  68. ++us;
  69. SysTime st = system_clock::now() + us;
  70. std::cout << "sleep_until ";
  71. ::print_time(st);
  72. std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
  73. }
  74. }
  75. } // this_thread
  76. struct mutex {};
  77. struct timed_mutex
  78. {
  79. bool try_lock() {std::cout << "timed_mutex::try_lock()\n"; return true;}
  80. template <class Rep, class Period>
  81. bool try_lock_for(const boost::chrono::duration<Rep, Period>& d)
  82. {
  83. boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
  84. if (t <= boost::chrono::microseconds(0))
  85. return try_lock();
  86. std::cout << "try_lock_for " << t.count() << " microseconds\n";
  87. return true;
  88. }
  89. template <class Clock, class Duration>
  90. bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& t)
  91. {
  92. using namespace boost::chrono;
  93. typedef time_point<Clock, Duration> Time;
  94. typedef system_clock::time_point SysTime;
  95. if (t <= Clock::now())
  96. return try_lock();
  97. typedef typename boost::common_type<typename Time::duration,
  98. typename Clock::duration>::type D;
  99. /* auto */ D d = t - Clock::now();
  100. microseconds us = duration_cast<microseconds>(d);
  101. SysTime st = system_clock::now() + us;
  102. std::cout << "try_lock_until ";
  103. ::print_time(st);
  104. std::cout << " which is " << (st - system_clock::now()).count()
  105. << " microseconds away\n";
  106. return true;
  107. }
  108. };
  109. struct condition_variable
  110. {
  111. template <class Rep, class Period>
  112. bool wait_for(mutex&, const boost::chrono::duration<Rep, Period>& d)
  113. {
  114. boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
  115. std::cout << "wait_for " << t.count() << " microseconds\n";
  116. return true;
  117. }
  118. template <class Clock, class Duration>
  119. bool wait_until(mutex&, const boost::chrono::time_point<Clock, Duration>& t)
  120. {
  121. using namespace boost::chrono;
  122. typedef time_point<Clock, Duration> Time;
  123. typedef system_clock::time_point SysTime;
  124. if (t <= Clock::now())
  125. return false;
  126. typedef typename boost::common_type<typename Time::duration,
  127. typename Clock::duration>::type D;
  128. /* auto */ D d = t - Clock::now();
  129. microseconds us = duration_cast<microseconds>(d);
  130. SysTime st = system_clock::now() + us;
  131. std::cout << "wait_until ";
  132. ::print_time(st);
  133. std::cout << " which is " << (st - system_clock::now()).count()
  134. << " microseconds away\n";
  135. return true;
  136. }
  137. };
  138. }
  139. //////////////////////////////////////////////////////////
  140. //////////// Simple sleep and wait examples //////////////
  141. //////////////////////////////////////////////////////////
  142. boost::mutex m;
  143. boost::timed_mutex mut;
  144. boost::condition_variable cv;
  145. void basic_examples()
  146. {
  147. std::cout << "Running basic examples\n";
  148. using namespace boost;
  149. using namespace boost::chrono;
  150. system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
  151. this_thread::sleep_for(seconds(3));
  152. this_thread::sleep_for(nanoseconds(300));
  153. this_thread::sleep_until(time_limit);
  154. // this_thread::sleep_for(time_limit); // desired compile-time error
  155. // this_thread::sleep_until(seconds(3)); // desired compile-time error
  156. mut.try_lock_for(milliseconds(30));
  157. mut.try_lock_until(time_limit);
  158. // mut.try_lock_for(time_limit); // desired compile-time error
  159. // mut.try_lock_until(milliseconds(30)); // desired compile-time error
  160. cv.wait_for(m, minutes(1)); // real code would put this in a loop
  161. cv.wait_until(m, time_limit); // real code would put this in a loop
  162. // For those who prefer floating point
  163. this_thread::sleep_for(duration<double>(0.25));
  164. this_thread::sleep_until(system_clock::now() + duration<double>(1.5));
  165. }
  166. int main()
  167. {
  168. basic_examples();
  169. return 0;
  170. }