1 // Copyright (C) 2013 Vicente Botet
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #include <boost/atomic.hpp>
9 //#include <boost/log/trivial.hpp>
10 #include <boost/chrono.hpp>
11 #include <boost/chrono/chrono_io.hpp>
12 #include <boost/thread.hpp>
13 #include <boost/thread/condition_variable.hpp>
15 typedef boost::chrono::high_resolution_clock Clock
;
16 typedef Clock::time_point TimePoint
;
18 inline TimePoint
real_time_now()
24 boost::atomic
<bool> m_is_exiting
;
25 TimePoint m_next_tick_time
;
29 bool is_exiting() const
34 TimePoint
spawn_tasks() // note that in my app, this call takes more time than here
36 using namespace boost::chrono
;
37 const TimePoint now
= real_time_now();
39 if (m_next_tick_time
< now
) {
40 m_next_tick_time
= now
+ seconds(1);
41 //BOOST_LOG_TRIVIAL(info) << "TICK!";
44 return m_next_tick_time
;
51 using namespace boost::chrono
;
52 static const milliseconds MIN_TIME_TASKS_SPAWN_FREQUENCY
= milliseconds(1);
53 //microseconds(1); // THE SHORTER THE QUICKER TO REPRODUCE THE BUG
55 boost::condition_variable m_task_spawn_condition
;
58 boost::mutex main_thread_mutex
;
59 boost::unique_lock
< boost::mutex
> main_thread_lock(main_thread_mutex
);
61 //BOOST_LOG_TRIVIAL(info) << "[TaskScheduler::run_and_wait] Scheduling loop - BEGIN";
66 const TimePoint next_task_spawn_time
= foo
.spawn_tasks();
68 const TimePoint now
= real_time_now();
69 const TimePoint next_minimum_spawn_time
= now
+ MIN_TIME_TASKS_SPAWN_FREQUENCY
;
70 const TimePoint next_spawn_time
= next_task_spawn_time
> TimePoint()
71 && next_task_spawn_time
< next_minimum_spawn_time
72 ? next_task_spawn_time
: next_minimum_spawn_time
;
74 const TimePoint::duration wait_time
= next_spawn_time
- now
;
75 if (wait_time
> wait_time
.zero()) {
76 // BOOST_LOG_TRIVIAL(trace) << "WAIT TIME: " << wait_time; // UNCOMMENT THIS: MAKES IT WORKS. WAT??????
77 boost::this_thread::sleep_for(boost::chrono::seconds(1));
78 std::cout
<< next_spawn_time
<< std::endl
;
79 m_task_spawn_condition
.wait_until(
81 next_spawn_time
); // DON'T WORK: WILL WAIT IF next_spawn_time is too close!