blob: 155e83999fd7c03833743688c4f78162a7a74f91 [file] [log] [blame]
Alexander Afanasyev45fba082012-03-12 18:05:24 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * 卞超轶 Chaoyi Bian <bcy@pku.edu.cn>
20 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
21 */
22
23#include "sync-scheduler.h"
24#include <boost/date_time/posix_time/posix_time.hpp>
25
26using namespace boost;
27using namespace std;
28
29namespace Sync {
30
31Scheduler::Scheduler ()
32 : m_threadRunning (true)
33{
34 m_thread = thread (&Scheduler::threadLoop, this);
35}
36
37Scheduler::~Scheduler ()
38{
39 m_threadRunning = false;
40 // cout << "Requested stop" << this_thread::get_id () << endl;
41 m_thread.interrupt ();
42 m_thread.join ();
43}
44
45void
46Scheduler::threadLoop ()
47{
48 while (m_threadRunning)
49 {
50 try
51 {
52 boost::system_time nextTime;
53 {
54 unique_lock<mutex> lock (m_eventsMutex);
55 while (m_threadRunning && m_events.size () == 0)
56 {
57 m_eventsCondition.wait (lock);
58 // cout << "Got something" << endl;
59 }
60
61 if (m_events.size () == 0) continue;
62
63 nextTime = m_events.begin ()->time;
64 }
65
66 if (nextTime - get_system_time () > posix_time::time_duration (0,0,0,0))
67 {
68 this_thread::sleep (nextTime - get_system_time ());
69
70 // sleeping
71
72 if (nextTime - get_system_time () > posix_time::time_duration (0,0,0,0))
73 continue; // something changes, try again
74 }
75
76 if (!m_threadRunning) continue;
77
78 Event event;
79
80 {
81 lock_guard<mutex> lock (m_eventsMutex);
82
83 BOOST_ASSERT (m_events.size () != 0);
84
85 event = m_events.begin ()->event;
86 m_events.erase (m_events.begin ());
87 }
88
89 event (); // calling the event outside the locked mutex
90 }
91 catch (thread_interrupted e)
92 {
93 // cout << "interrupted: " << this_thread::get_id () << endl;
94 // do nothing
95 }
96 }
97 // cout << "Exited...\n";
98}
99
100
101void
102Scheduler::schedule (const boost::system_time &abstime, Event event)
103{
104 {
105 lock_guard<mutex> lock (m_eventsMutex);
106 m_events.insert (LogicEvent (abstime, event));
107 }
108 m_eventsCondition.notify_one ();
109 m_thread.interrupt (); // interrupt sleep, if currently sleeping
110}
111
112void
113Scheduler::schedule (const boost::posix_time::time_duration &reltime, Event event)
114{
115 // cout << reltime << endl;
116 schedule (boost::get_system_time () + reltime, event);
117}
118
119} // Sync