diff --git a/Makefile.am b/Makefile.am index 39705a8..6640027 100644 --- a/Makefile.am +++ b/Makefile.am @@ -265,6 +265,7 @@ sgpemv2_LDADD = \ # Please keep this in sorted order: sgpemv2_SOURCES = \ + src/concrete_simulation.cc \ src/graphical_terminal_io.cc \ src/gui_builder.cc \ src/main.cc \ @@ -277,6 +278,7 @@ sgpemv2_SOURCES = \ src/text_simulation.cc noinst_HEADERS += \ + src/concrete_simulation.hh \ src/graphical_simulation.hh \ src/graphical_terminal_io.hh \ src/gui_builder.hh \ diff --git a/src/concrete_simulation.cc b/src/concrete_simulation.cc new file mode 100644 index 0000000..67f7f6c --- /dev/null +++ b/src/concrete_simulation.cc @@ -0,0 +1,199 @@ +// src/backend/concrete_simulation.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 "concrete_simulation.hh" +#include + +#include "smartp.tcc" + +using namespace std; +using namespace sgpem; +using namespace memory; +using Glib::usleep; + +ConcreteSimulation::ConcreteSimulation(): _state(state_paused), _mode(true), _timer_interval(1000) +{} + +void +ConcreteSimulation::set_timer(const int& t) +{ + _timer_interval = t; +} + +int +ConcreteSimulation::get_timer() const +{ + return _timer_interval; +} + +void +ConcreteSimulation::set_mode(const bool& b) +{ + _mode = b; +} + +bool +ConcreteSimulation::get_mode() const +{ + return _mode; +} + +void +ConcreteSimulation::pause() +{ + _state = state_paused; +} + +void +ConcreteSimulation::stop() +{ + _state = state_stopped; +} + +void +ConcreteSimulation::reset() +{ + _state = state_paused; + //History::get_instance().truncate_at(0); +} + +void +ConcreteSimulation::run() throw(UserInterruptException) +{ +// History& h = History::get_instance(); +// +// switch(_state) +// { +// case state_running: +// // FIXME: write out something, or just ignore user input? +// return; +// case state_stopped: +// h.truncate_at(0); +// break; +// default: +// break; +// } +// +// _state = state_running; +// +// //******* CONTINUOUS TIME +// +// if (_mode) +// { +// do +// { +// // chech for termination +// bool all_term = true; +// smart_ptr left = h.get_simulation_status_at(h.get_current_time()); +// for(uint i = 0; i < left->size(); i++) +// if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated) +// { +// all_term = false; +// break; +// } +// +// //if there are no processes left the termination message has already been notified +// //by the last execution of upadate() +// if (all_term) +// { +// _state = state_stopped; +// return; // Exit from loop +// } +// +// try +// { +// //step forward +// Scheduler::get_instance().step_forward(); +// +// //sleep +// Glib::usleep(_timer_interval*1000); +// +// } +// catch(UserInterruptException e) +// { +// stop(); +// throw; +// } +// +// //check the state +// if (_state == state_stopped || _state == state_paused) +// return; +// +// } +// while(true); +// } +// +// //******* STEP by STEP +// else +// { +// // chech for termination +// bool all_term = true; +// smart_ptr left = h.get_simulation_status_at(h.get_current_time()); +// for(uint i = 0; i < left->size(); i++) +// if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated) +// { +// all_term = false; +// break; +// } +// +// if (all_term) +// //if there are no processes left the termination message has already been notified +// //by the last execution of upadate() +// _state = state_paused; +// else +// { +// +// try +// { +// //step forward +// Scheduler::get_instance().step_forward(); +// } +// catch(UserInterruptException e) +// { +// throw; +// } +// } +// } + +} + + + +void +ConcreteSimulation::set_policy(Policy* p) +{ +// Scheduler::get_instance().set_policy(p); +} + + +Policy* +ConcreteSimulation::get_policy() +{ + //return &Scheduler::get_instance().get_policy(); + return NULL; +} + +vector +ConcreteSimulation::get_avaiable_policies() +{ + vector v; + //v.push_back(&Scheduler::get_instance().get_policy()); + return v; +} diff --git a/src/concrete_simulation.hh b/src/concrete_simulation.hh new file mode 100644 index 0000000..4285ba0 --- /dev/null +++ b/src/concrete_simulation.hh @@ -0,0 +1,69 @@ +// src/frontend/concrete_simulation.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 CONCRETE_SIMULATION_HH +#define CONCRETE_SIMULATION_HH 1 + +#include "simulation.hh" +#include "backend/concrete_history.hh" + +namespace sgpem +{ + class ConcreteSimulation; + + class ConcreteSimulation : public Simulation + { + public: + ConcreteSimulation(); + + void run() throw(UserInterruptException); + + void pause(); + + void stop(); + + void reset(); + + void set_timer(const int&); + + int get_timer() const; + + void set_mode(const bool&); + + bool get_mode() const; + + void set_policy(Policy*); + + Policy* get_policy(); + + std::vector get_avaiable_policies(); + + private: + state _state; + bool _mode; + int _timer_interval; + ConcreteHistory _history; + }; + +} + + +#endif + diff --git a/src/simulation.cc b/src/simulation.cc index dd5ad13..9966869 100644 --- a/src/simulation.cc +++ b/src/simulation.cc @@ -19,204 +19,22 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "simulation.hh" +#include "concrete_simulation.hh" -#include "smartp.tcc" - -using namespace std; +// Do not include in header file: +#include "singleton.tcc" using namespace sgpem; -using namespace memory; -using Glib::usleep; -Simulation::Simulation(): _state(state_paused), _mode(true), _timer_interval(1000) -{} +// Explicit template instantiation to allow to export symbols from the DSO. +template class SG_DLLEXPORT Singleton; -void -Simulation::set_timer(const int& t) + +Simulation::~Simulation() { - _timer_interval = t; } -int -Simulation::get_timer() const +Simulation& +Simulation::get_instance() { - return _timer_interval; -} - -void -Simulation::set_mode(const bool& b) -{ - _mode = b; -} - -bool -Simulation::get_mode() const -{ - return _mode; -} - -void -Simulation::pause() -{ - _state = state_paused; -} - -void -Simulation::stop() -{ - _state = state_stopped; -} - -void -Simulation::reset() -{ - _state = state_paused; - //History::get_instance().truncate_at(0); -} - -void -Simulation::run() throw(UserInterruptException) -{ -// History& h = History::get_instance(); -// -// switch(_state) -// { -// case state_running: -// // FIXME: write out something, or just ignore user input? -// return; -// case state_stopped: -// h.truncate_at(0); -// break; -// default: -// break; -// } -// -// _state = state_running; -// -// //******* CONTINUOUS TIME -// -// if (_mode) -// { -// do -// { -// // chech for termination -// bool all_term = true; -// smart_ptr left = h.get_simulation_status_at(h.get_current_time()); -// for(uint i = 0; i < left->size(); i++) -// if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated) -// { -// all_term = false; -// break; -// } -// -// //if there are no processes left the termination message has already been notified -// //by the last execution of upadate() -// if (all_term) -// { -// _state = state_stopped; -// return; // Exit from loop -// } -// -// try -// { -// //step forward -// Scheduler::get_instance().step_forward(); -// -// //sleep -// Glib::usleep(_timer_interval*1000); -// -// } -// catch(UserInterruptException e) -// { -// stop(); -// throw; -// } -// -// //check the state -// if (_state == state_stopped || _state == state_paused) -// return; -// -// } -// while(true); -// } -// -// //******* STEP by STEP -// else -// { -// // chech for termination -// bool all_term = true; -// smart_ptr left = h.get_simulation_status_at(h.get_current_time()); -// for(uint i = 0; i < left->size(); i++) -// if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated) -// { -// all_term = false; -// break; -// } -// -// if (all_term) -// //if there are no processes left the termination message has already been notified -// //by the last execution of upadate() -// _state = state_paused; -// else -// { -// -// try -// { -// //step forward -// Scheduler::get_instance().step_forward(); -// } -// catch(UserInterruptException e) -// { -// throw; -// } -// } -// } - -} - - -void -Simulation::jump_to(const uint& where) throw(UserInterruptException) -{ - //jump to position 0 - reset(); - bool old = _mode; - _mode = false; - - - try - { - // executes "where" steps - for (uint i = 0; i < where; i++) - run(); - } - catch(UserInterruptException e) - { - _mode = old; - throw; - } - - _state = state_paused; - _mode = old; -} - -/*void -Simulation::set_policy(Policy* p) -{ - Scheduler::get_instance().set_policy(p); - }*/ - - -Policy* -Simulation::get_policy() -{ - //return &Scheduler::get_instance().get_policy(); - return NULL; -} - -vector -Simulation::get_avaiable_policies() -{ - vector v; - //v.push_back(&Scheduler::get_instance().get_policy()); - return v; + return Singleton::get_instance(); } diff --git a/src/simulation.hh b/src/simulation.hh index 3b42568..18c357c 100644 --- a/src/simulation.hh +++ b/src/simulation.hh @@ -21,14 +21,17 @@ #ifndef SIMULATION_HH #define SIMULATION_HH 1 +namespace sgpem +{ + class ConcreteSimulation; + class Policy; +} + #include "config.h" -#include - -#include "observer.hh" -#include "backend/policy.hh" -#include "backend/history.hh" -#include "backend/scheduler.hh" +#include "singleton.hh" +#include "backend/user_interrupt_exception.hh" +#include namespace sgpem { @@ -54,7 +57,7 @@ namespace sgpem the Backend layers. */ - class SG_DLLEXPORT Simulation : public Observer + class SG_DLLEXPORT Simulation : public Singleton { public: enum state @@ -63,16 +66,16 @@ namespace sgpem state_paused, state_stopped }; - - Simulation(); - + + virtual ~Simulation(); + /** \brief Runs the simulation. Advances the simulation by one or more steps, depending on the actual state and on the value set with set_mode(). */ - void run() throw(UserInterruptException); + virtual void run() throw(UserInterruptException) = 0; /** \brief Pauses a running simulation. @@ -81,7 +84,7 @@ namespace sgpem Calling again run() will cause the simulation to start from the current simulation step. */ - void pause(); + virtual void pause() = 0; /** \brief Stops the simulation. @@ -89,7 +92,7 @@ namespace sgpem Behaves in the same way as pause(), except that the next call to run() will cause the simulation to start from the beginning. */ - void stop(); + virtual void stop() = 0; /** \brief Reset the simulation. @@ -98,12 +101,7 @@ namespace sgpem residual or temporary data to ensure the simulation has reached a clean and stable state. */ - void reset(); - - /** - \brief Causes the simulation to jump to the given time unit. - */ - void jump_to(const uint&) throw(UserInterruptException); + virtual void reset() = 0; /** \brief Setter for the attribute timer_interval. @@ -112,13 +110,13 @@ namespace sgpem interpreted when the simulation advancement mode is continue. The input value is in milliseconds, and it must be in range [0, 10000]. */ - void set_timer(const int&); + virtual void set_timer(const int&) = 0; /** \see set_timer() */ - int get_timer() const; - + virtual int get_timer() const = 0; + /** \brief This methods allows to change the way the simulation progresses. @@ -128,38 +126,37 @@ namespace sgpem waiting the time defined with set_timer() between each step, until all processes have terminated, or some error happens. */ - void set_mode(const bool&); + virtual void set_mode(const bool&) = 0; /** \return The simulation advancement mode: 0 if step-to-step, 1 if continue. */ - bool get_mode() const; + virtual bool get_mode() const = 0; /** \brief Setup the policy to be used by the system. The input pointer must be one of those returned by get_avaiable_policies(). */ - void set_policy(Policy*); + virtual void set_policy(Policy*) = 0; /** \return The policy currently in use. */ - Policy* get_policy(); + virtual Policy* get_policy() = 0; /** \return A collection of policies (scheduling algorithms), from which a user may choose. */ - std::vector get_avaiable_policies(); - - - private: - state _state; - bool _mode; - int _timer_interval; + virtual std::vector get_avaiable_policies() = 0; + /** + * Small kludge to avoid the need for declaration of ConcreteSimulation + * by the calling code of Simulation::get_instance() + */ + static Simulation& get_instance(); }; } diff --git a/src/text_simulation.cc b/src/text_simulation.cc index 7ac16e6..75e4ea2 100644 --- a/src/text_simulation.cc +++ b/src/text_simulation.cc @@ -320,7 +320,7 @@ TextSimulation::on_run(const Tokens& arguments) try { - run(); + Simulation::get_instance().run(); } catch(UserInterruptException e) { @@ -335,7 +335,7 @@ TextSimulation::on_pause(const Tokens& arguments) { check_arguments_num(arguments, 0); - pause(); + Simulation::get_instance().pause(); } void @@ -343,7 +343,7 @@ TextSimulation::on_stop(const Tokens& arguments) { check_arguments_num(arguments, 0); - stop(); + Simulation::get_instance().stop(); } void @@ -642,7 +642,7 @@ TextSimulation::on_get(const Tokens& arguments) if(attr == "SIMULATION_TICK") { ostringstream oss; - oss << "\nsimulation_tick = " << get_timer() << "ms" << endl; + oss << "\nsimulation_tick = " << Simulation::get_instance().get_timer() << "ms" << endl; p_stdout(oss.str()); } else @@ -672,7 +672,7 @@ TextSimulation::on_set(const Tokens& arguments) { try { - set_timer(string_to(value)); + Simulation::get_instance().set_timer(string_to(value)); } catch(domain_error e) { diff --git a/src/text_simulation.hh b/src/text_simulation.hh index fb509db..fae2781 100644 --- a/src/text_simulation.hh +++ b/src/text_simulation.hh @@ -55,7 +55,7 @@ namespace sgpem Any object returned after the call to Simulation will be returned to the output devices(s) in a human-readable format. */ - class SG_DLLEXPORT TextSimulation : public Simulation, public sigc::trackable + class SG_DLLEXPORT TextSimulation : public sigc::trackable { public: ~TextSimulation();