2011-12-14 01:38:14 +00:00
|
|
|
// This file is part of BOINC.
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2011 University of California
|
|
|
|
//
|
|
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
|
|
// under the terms of the GNU Lesser General Public License
|
|
|
|
// as published by the Free Software Foundation,
|
|
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
// The world's smallest discrete event simulator.
|
|
|
|
// Uses the STL "heap" data structure for efficient event storage.
|
|
|
|
|
2011-11-03 03:29:07 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
using std::vector;
|
|
|
|
|
2011-12-14 01:38:14 +00:00
|
|
|
// base class for events.
|
|
|
|
// t is the time when the event occurs.
|
2011-12-16 19:45:31 +00:00
|
|
|
// handle() is the function to call then.
|
2011-12-14 01:38:14 +00:00
|
|
|
//
|
2011-11-03 03:29:07 +00:00
|
|
|
struct EVENT {
|
|
|
|
double t;
|
|
|
|
virtual void handle(){}
|
|
|
|
};
|
|
|
|
|
|
|
|
bool compare(EVENT* e1, EVENT* e2) {
|
|
|
|
return (e1->t > e2->t);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct SIMULATOR {
|
|
|
|
vector<EVENT*> events;
|
2011-11-19 00:29:55 +00:00
|
|
|
double now;
|
2011-12-14 01:38:14 +00:00
|
|
|
|
|
|
|
// add an event
|
|
|
|
//
|
2011-11-03 03:29:07 +00:00
|
|
|
void insert(EVENT* e) {
|
2011-12-06 04:21:27 +00:00
|
|
|
//printf("adding %x\n", e);
|
2011-11-03 03:29:07 +00:00
|
|
|
events.push_back(e);
|
|
|
|
push_heap(events.begin(), events.end(), compare);
|
|
|
|
}
|
2011-12-14 01:38:14 +00:00
|
|
|
|
|
|
|
// remove an event
|
|
|
|
//
|
2011-11-24 21:16:32 +00:00
|
|
|
void remove(EVENT* e) {
|
|
|
|
vector<EVENT*>::iterator i;
|
2011-12-06 04:21:27 +00:00
|
|
|
//printf("removing %x\n", e);
|
2011-11-24 21:16:32 +00:00
|
|
|
for (i=events.begin(); i!=events.end(); i++) {
|
|
|
|
if (*i == e) {
|
|
|
|
events.erase(i);
|
|
|
|
make_heap(events.begin(), events.end(), compare);
|
2011-12-06 04:21:27 +00:00
|
|
|
//printf("removed %x\n", e);
|
|
|
|
return;
|
2011-11-24 21:16:32 +00:00
|
|
|
}
|
|
|
|
}
|
2011-12-06 04:21:27 +00:00
|
|
|
//printf("%x not found\n", e);
|
2011-11-24 21:16:32 +00:00
|
|
|
}
|
2011-12-14 01:38:14 +00:00
|
|
|
|
|
|
|
// run the simulator for the given time period
|
|
|
|
//
|
2011-11-03 03:29:07 +00:00
|
|
|
void simulate(double dur) {
|
|
|
|
while (events.size()) {
|
|
|
|
EVENT* e = events.front();
|
|
|
|
pop_heap(events.begin(), events.end(), compare);
|
|
|
|
events.pop_back();
|
2011-11-19 00:29:55 +00:00
|
|
|
now = e->t;
|
|
|
|
if (now > dur) break;
|
2011-11-03 03:29:07 +00:00
|
|
|
e->handle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|