diff --git a/src/Makefile.am b/src/Makefile.am index 4829ba1..9e7b135 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -58,6 +58,7 @@ noinst_HEADERS = \ iomanager.hh \ main.hh \ mainwindow.hh \ + observer.hh \ startgui.hh \ graphicalterminalio.hh \ parseopts.hh diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 111f6b9..0b1dd6f 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -47,13 +47,18 @@ libbackend_la_LDFLAGS = $(PYTHON_EXTRA_LDFLAGS) \ # Please keep this in sorted order: libbackend_la_SOURCES = \ + history.cc \ + observedSubject.cc \ process.cc \ schedulable.cc \ schedulableStatus.cc \ simulationStatus.cc \ slice.cc + noinst_HEADERS = \ + history.hh \ + observedSubject.hh \ process.hh \ schedulable.hh \ schedulableStatus.hh \ diff --git a/src/backend/history.cc b/src/backend/history.cc new file mode 100644 index 0000000..5c162b6 --- /dev/null +++ b/src/backend/history.cc @@ -0,0 +1,127 @@ +// src/backend/history.cc - Copyright 2005, 2006, University +// of Padova, dept. of Pure and Applied +// Mathematics +// +// This file is part of SGPEMv2. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// SGPEMv2 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SGPEMv2; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#include "history.hh" +using namespace std; +using namespace sgpem; +using namespace memory; + +//History::instance; //static object +History History::_instance(10); //dummy parameter + +History::History(int) //private constructor. The parameter is discarded + :_total_time_elapsed(0) +{ +} + + +History& +History::getInstance() +{ + return _instance; +} + + +/** + Returns a pointer to a copy of the SchedulableStatus object relative to this instant. + It can be NULL if time is out of range or if the SimulationStatus object relative to + this instant has no running entities. +*/ +smart_ptr +History::getScheduledAt (int time) +{ + if (time >= _total_time_elapsed || time < 0) //out of range + return smart_ptr(NULL); + + return getSimulationStatusAt(time)->getRunning(); +} + +/** + Returns a pointer to a copy of the SimulationStatus object relative to this instant or NULL + if time is out of range. +*/ +smart_ptr +History::getSimulationStatusAt (int time) +{ + if (time >= _total_time_elapsed || time < 0) //out of range + return smart_ptr(NULL); + + int trascorso = 0; + for(vector::iterator i=_slices.begin(); i < _slices.end(); i++) + if (time < trascorso + i->getDuration()) //FOUND!! + return smart_ptr(new SimulationStatus(i->getSimulationStatus())); + else //Go on... + trascorso += i->getDuration(); + + //never reached + return smart_ptr(NULL); +} + +int +History::getCurrentTime() +{ + return _total_time_elapsed; +} + +/** + Appends to the history a SimulationStatus creating a Slice with duration of 1 instant. + Calls the method notify() in quality of ObservedSubject, updating all observers. +*/ +void +History::enqueueSlice (SimulationStatus status) +{ + if (_slices.size() == 0){ + _slices.push_back(Slice(0, 1, status)); + _total_time_elapsed = 1; + notify(); + return; + } + + //check the last slice + Slice& last = _slices[_slices.size()-1]; + if (last.getSimulationStatus() == status) //increments the duration by ONE unit + { + last.setDuration(last.getDuration()+1); + } + else //insert a new slice CONTIGUOUS to the last one + { + _slices.push_back(Slice(last.getStartedAt() + last.getDuration(), 1, status)); + } + _total_time_elapsed++; //one instant is passed... + notify(); +} + +/** + Removes all the informations about the simulation following the specified instant. +*/ +void +History::truncateAt (int instant) +{ + //reach the instant + vector::iterator i = _slices.begin(); + for (int k=0; k < instant; k++) + i++; + //replaces the current vector with the "trimmed" one. + _slices = vector(_slices.begin(),i); + _total_time_elapsed = instant; +} + + + diff --git a/src/backend/history.hh b/src/backend/history.hh new file mode 100644 index 0000000..6db2780 --- /dev/null +++ b/src/backend/history.hh @@ -0,0 +1,71 @@ +// src/backend/history.hh - Copyright 2005, 2006, University +// of Padova, dept. of Pure and Applied +// Mathematics +// +// This file is part of SGPEMv2. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// SGPEMv2 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SGPEMv2; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef HISTORY_HH +#define HISTORY_HH 1 + +#include "config.h" + +#include +#include + +#include "slice.hh" +#include "observedSubject.hh" +#include "simulationStatus.hh" +#include "schedulableStatus.hh" +#include "../templates/smartp.hh" + +namespace sgpem +{ + +/** \brief Manages the history of the simulation + + Manages the history of the simulation from the instant 0 to the current time, + i.e. permits to know the state of each schedulable object inside this time interval. + In particoular it's possible to know which entity was running at a precise moment. + + In a future iteration it will be possible to revert the entire simulation to a state + present in the history ("undo operation") + +*/ + class History; + + class SG_DLLEXPORT History : public ObservedSubject { + public: + + memory::smart_ptr getScheduledAt (int time); + memory::smart_ptr getSimulationStatusAt (int time); + int getCurrentTime(); + void enqueueSlice (sgpem::SimulationStatus status); + void truncateAt (int instant); + + static History& getInstance(); + + private: + History(int); //private constructor. The parameter is discarded + static History _instance; + int _total_time_elapsed; + std::vector _slices; + }; + +} + +#endif //HISTORY_H + diff --git a/src/backend/observedSubject.cc b/src/backend/observedSubject.cc new file mode 100644 index 0000000..475506d --- /dev/null +++ b/src/backend/observedSubject.cc @@ -0,0 +1,63 @@ +// src/backend/observedSubject.cc - Copyright 2005, 2006, University +// of Padova, dept. of Pure and Applied +// Mathematics +// +// This file is part of SGPEMv2. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// SGPEMv2 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SGPEMv2; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#include "observedSubject.hh" +using namespace std; +using namespace sgpem; + + +ObservedSubject::~ObservedSubject() +{ +} + +/** + Calls update() in each Observer +*/ +void +ObservedSubject::notify() +{ + for(vector::iterator i = _attached.begin(); i < _attached.end(); i++) + (*i)->update(); +} + +/** + Attachs an Observer to this ObservedSubject. +*/ +void +ObservedSubject::attach(Observer* o) +{ + _attached.push_back(o); +} + +/** + Detachs the observer from this ObservedSubject. +*/ + +bool +ObservedSubject::detach(Observer* o) +{ + vector::iterator i = find(_attached.begin(), _attached.end(), o); + if (i == _attached.end()) + return false; + + _attached.erase(i); // FOUND and POPPED + return true; +} + diff --git a/src/backend/observedSubject.hh b/src/backend/observedSubject.hh new file mode 100644 index 0000000..b2e39f0 --- /dev/null +++ b/src/backend/observedSubject.hh @@ -0,0 +1,54 @@ +// src/backend/observedSubject.hh - Copyright 2005, 2006, University +// of Padova, dept. of Pure and Applied +// Mathematics +// +// This file is part of SGPEMv2. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// SGPEMv2 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SGPEMv2; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef OBSERVEDSUBJECT_HH +#define OBSERVEDSUBJECT_HH 1 + +#include "config.h" + +#include +#include + +#include "../observer.hh" + +namespace sgpem +{ + /** + Abstract class which represents an observed entity who calls Update() in all Observer objects. + See "Observer Pattern" for more information. + */ + class ObservedSubject; + + class SG_DLLEXPORT ObservedSubject + { + public: + virtual ~ObservedSubject() =0; + + void notify(); + void attach(sgpem::Observer*); + bool detach(sgpem::Observer*); + + private: + std::vector _attached; + }; +} + + +#endif diff --git a/src/backend/process.cc b/src/backend/process.cc index f3608c9..29be6e4 100644 --- a/src/backend/process.cc +++ b/src/backend/process.cc @@ -34,5 +34,5 @@ Process::~Process() Glib::ustring Process::getType() const { - return _("Process"); + return "Process"; } diff --git a/src/backend/schedulableStatus.cc b/src/backend/schedulableStatus.cc index 26698e6..b128afb 100644 --- a/src/backend/schedulableStatus.cc +++ b/src/backend/schedulableStatus.cc @@ -71,6 +71,10 @@ SchedulableStatus::getSchedulable() const return _ref; } - +bool +SchedulableStatus::operator==(const SchedulableStatus& dx) const +{ + return (_ref==dx._ref)&&(_last==dx._last)&&(_timeLeft==dx._timeLeft)&&(_myState==dx._myState); +} \ No newline at end of file diff --git a/src/backend/schedulableStatus.hh b/src/backend/schedulableStatus.hh index 082b936..30d7c34 100644 --- a/src/backend/schedulableStatus.hh +++ b/src/backend/schedulableStatus.hh @@ -51,7 +51,7 @@ class SG_DLLEXPORT SchedulableStatus SchedulableStatus(const Schedulable& obj); //SchedulableStatus(const SchedulableStatus& obj); //copy constructor - //SchedulableStatus& operator=(const SchedulableStatus&); + bool operator==(const SchedulableStatus&) const; int getCpuTimeLeft() const; void giveCpuTime(const int& time); diff --git a/src/backend/simulationStatus.cc b/src/backend/simulationStatus.cc index 40a4258..e712a63 100644 --- a/src/backend/simulationStatus.cc +++ b/src/backend/simulationStatus.cc @@ -21,7 +21,11 @@ #include "simulationStatus.hh" using namespace sgpem; using namespace std; +using namespace memory; + /** \brief Creates the SimulationStatus object with no SchedulableStatus object + + */ SimulationStatus::SimulationStatus() { } @@ -52,14 +56,41 @@ SimulationStatus::setRunning(SchedulableStatus entity) the NULL pointer. */ -auto_ptr +smart_ptr +SimulationStatus::getRunning() +{ + for (list::iterator f=_set.begin(); f != _set.end(); f++) + if (f->getState() == SchedulableStatus::state_running){ //there can be only ONE running schedulable objext + return smart_ptr(new SchedulableStatus(*f)); + } + return smart_ptr(NULL); +} + +smart_ptr SimulationStatus::getRunning() const { - for (uint i=0; i < _set.size(); i++) - if (_set[i].getState() == SchedulableStatus::state_running){ //there can be only ONE running schedulable objext - SchedulableStatus* s = const_cast( &_set[i]); - return auto_ptr(s); + for (list::const_iterator f=_set.begin(); f != _set.end(); f++) + if (f->getState() == SchedulableStatus::state_running){ //there can be only ONE running schedulable objext + return smart_ptr(new SchedulableStatus(*f)); } - return auto_ptr(NULL); + return smart_ptr(NULL); //NOT FOUND RUNNING ENTITIES +} + + + /** + \brief Returns TRUE if the two objects have the same SchedulableStatus objects + */ +bool +SimulationStatus::operator==(const SimulationStatus& dx) const +{ + if (_set.size() != dx._set.size()) + return false; + + //check if dx has ALL and ONLY the elements holded by _set with no order importance + for(list::const_iterator f=_set.begin(); f != _set.end(); f++) + if (find(dx._set.begin(), dx._set.end(), *f) == dx._set.end()) //element NOT found!! + return false; + + + return true; } - diff --git a/src/backend/simulationStatus.hh b/src/backend/simulationStatus.hh index 52d3ac8..c1596f4 100644 --- a/src/backend/simulationStatus.hh +++ b/src/backend/simulationStatus.hh @@ -22,10 +22,10 @@ #define SIMULATIONSTATUS_HH 1 #include "config.h" -#include -#include +#include #include "schedulableStatus.hh" +#include "../templates/smartp.hh" namespace sgpem { @@ -43,11 +43,15 @@ namespace sgpem SimulationStatus(); SimulationStatus(const SimulationStatus&); - std::auto_ptr getRunning() const; - void setRunning(SchedulableStatus); + bool operator==(const SimulationStatus&) const; + memory::smart_ptr getRunning(); //this method isn't const because it returns a pointer which CAN alter the object! + memory::smart_ptr getRunning() const; + void setRunning(SchedulableStatus); private: - std::vector _set; + //I used a list instead of a vector because this one could reallocate the internal elements + //making pointers returned by getRunning() point to nothing! SEGMENTATION-FAULT :-O + std::list _set; }; } diff --git a/src/backend/slice.cc b/src/backend/slice.cc index 9dbca12..ebb4fd8 100644 --- a/src/backend/slice.cc +++ b/src/backend/slice.cc @@ -35,13 +35,19 @@ Slice::getSimulationStatus() } int -Slice::getStartedAt() +Slice::getStartedAt() const { return _started_at; } int -Slice::getDuration() +Slice::getDuration() const { return _duration; } + +void +Slice::setDuration(const int& i) +{ + _duration = i; +} \ No newline at end of file diff --git a/src/backend/slice.hh b/src/backend/slice.hh index 2eefa4c..ef90099 100644 --- a/src/backend/slice.hh +++ b/src/backend/slice.hh @@ -42,8 +42,9 @@ namespace sgpem Slice(const int& start, const int& duration, const SimulationStatus& status); SimulationStatus& getSimulationStatus(); - int getStartedAt(); - int getDuration(); + int getStartedAt() const; + int getDuration() const; + void setDuration(const int&); private: SimulationStatus _ref; diff --git a/src/main.cc b/src/main.cc index 14a1323..b87d894 100644 --- a/src/main.cc +++ b/src/main.cc @@ -25,6 +25,8 @@ #include "parseopts.hh" #include "startgui.hh" +#include "templates/smartp.hh" +#include "backend/history.hh" #include "backend/slice.hh" #include "backend/schedulable.hh" #include "backend/schedulableStatus.hh" @@ -32,12 +34,12 @@ #include "backend/process.hh" #include -#include #include #include using namespace std; using namespace sgpem; + using namespace memory; int main(int argc, char* argv[]) @@ -48,7 +50,7 @@ main(int argc, char* argv[]) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - + /* // Parses options and prepares vector with // filenames of documents to be opened vector filenames; @@ -58,23 +60,60 @@ main(int argc, char* argv[]) parse_options(a_count, a_ptr); filenames.insert(filenames.begin(), a_ptr, a_ptr+a_count); } - -start_gui(argc, argv); + */ +//start_gui(argc, argv); //SMOKE-TEST for backend classes cout << "\n\n********************************"; - Process p("P1", 0,10,5); - SchedulableStatus ss(p); - SchedulableStatus ss2(ss); - SimulationStatus sim; - sim.setRunning(ss); + Process p1("P1", 0,10,1); + Process p2("P2", 0,30,2); + Process p3("P3", 5,15,3); - Slice sl(0,5, sim); + SchedulableStatus ss1(p1); + SchedulableStatus ss2(p2); + SchedulableStatus ss3(p3); + + SimulationStatus sim1; sim1.setRunning(p1); + SimulationStatus sim2; sim2.setRunning(p2); + SimulationStatus sim3; sim3.setRunning(p3); + + History h(History::getInstance()); + + h.enqueueSlice(sim1); + h.enqueueSlice(sim1); + h.enqueueSlice(sim2); + h.enqueueSlice(sim1); + h.enqueueSlice(sim2); + h.enqueueSlice(sim1); + h.enqueueSlice(sim2); + h.enqueueSlice(sim3); + h.enqueueSlice(sim3); + h.enqueueSlice(sim1); + h.enqueueSlice(sim3); + h.enqueueSlice(sim1); + + h.truncateAt(3); + + smart_ptr quale; + + quale = h.getSimulationStatusAt(0); + if (quale) cout << "\n" << quale->getRunning()->getSchedulable()->getName(); else cout << "NO"; + quale = h.getSimulationStatusAt(1); + if (quale) cout << "\n" << quale->getRunning()->getSchedulable()->getName(); else cout << "NO"; + quale = h.getSimulationStatusAt(2); + if (quale) cout << "\n" << quale->getRunning()->getSchedulable()->getName(); else cout << "NO"; + + h.truncateAt(2); + + smart_ptr quale2; + quale2 = h.getScheduledAt(0); + if (quale2) cout << "\n" << quale2->getSchedulable()->getName(); else cout << "NO"; + quale2 = h.getScheduledAt(1); + if (quale2) cout << "\n" << quale2->getSchedulable()->getName(); else cout << "NO"; + quale2 = h.getScheduledAt(2); + if (quale2) cout << "\n" << quale2->getSchedulable()->getName(); else cout << "NO"; + cout << "\n\n"; - - cout << "AAA " <getSchedulable()->getName(); - - cout << "\n\n"; return 0; } diff --git a/src/observer.hh b/src/observer.hh new file mode 100644 index 0000000..432fcfc --- /dev/null +++ b/src/observer.hh @@ -0,0 +1,47 @@ +// src/frontend/observer.hh - Copyright 2005, 2006, University +// of Padova, dept. of Pure and Applied +// Mathematics +// +// This file is part of SGPEMv2. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// SGPEMv2 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SGPEMv2; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef OBSERVER_HH +#define OBSERVER_HH 1 + +#include "config.h" + +namespace sgpem +{ + /** + Abstract class which represents an observed entity who calls Update() in all Observer objects. + See "Observer Pattern" for more information. + */ + class Observer; + + class SG_DLLEXPORT Observer + { + public: + virtual ~Observer()=0; + + virtual void update(); + + private: + }; + +} + + +#endif \ No newline at end of file