diff --git a/Makefile.am b/Makefile.am index e3fd02d..f33ef6e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -164,6 +164,7 @@ src_backend_libbackend_la_SOURCES = \ src/backend/invalid_plugin_exception.cc \ src/backend/key_file.cc \ src/backend/module.cc \ + src/backend/null_policy_exception.cc \ src/backend/plugin_manager.cc \ src/backend/policies_gatekeeper.cc \ src/backend/policy.cc \ @@ -199,6 +200,7 @@ pkginclude_HEADERS += \ src/backend/invalid_plugin_exception.hh \ src/backend/key_file.hh \ src/backend/module.hh \ + src/backend/null_policy_exception.hh \ src/backend/plugin.hh \ src/backend/plugin_manager.hh \ src/backend/policies_gatekeeper.hh \ diff --git a/plugins/pyloader/src/python_policy.cc b/plugins/pyloader/src/python_policy.cc index e4094e7..d51477e 100644 --- a/plugins/pyloader/src/python_policy.cc +++ b/plugins/pyloader/src/python_policy.cc @@ -176,7 +176,9 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException) { Py_UNBLOCK_THREADS; usleep(WAIT_FOR); // hack'a'ton! magggggiccc nummmbeeerrrrrs!! + cout << "got here..." << endl; Py_BLOCK_THREADS; + cout << "wow I also got here!" << endl; PyObject* retval = PyObject_CallMethod(_adapter, "mutex_test_lock", NULL); assert(retval); diff --git a/src/backend/concrete_simulation.cc b/src/backend/concrete_simulation.cc index 2b1c876..9217f61 100644 --- a/src/backend/concrete_simulation.cc +++ b/src/backend/concrete_simulation.cc @@ -33,7 +33,7 @@ using namespace memory; using Glib::usleep; ConcreteSimulation::ConcreteSimulation() : - _state(state_paused), _mode(true), _timer_interval(1000), _policy(NULL) + _state(state_stopped), _mode(true), _timer_interval(1000), _policy(NULL) {} void @@ -73,7 +73,7 @@ ConcreteSimulation::stop() } void -ConcreteSimulation::run() throw(UserInterruptException) +ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException) { switch(_state) { @@ -117,7 +117,12 @@ ConcreteSimulation::run() throw(UserInterruptException) try { - assert(get_policy() != NULL); + if(get_policy() == NULL) + { + stop(); + throw NullPolicyException("no policy selected"); + } + //step forward Scheduler::get_instance().step_forward(_history, *get_policy()); diff --git a/src/backend/concrete_simulation.hh b/src/backend/concrete_simulation.hh index fe56b92..42af261 100644 --- a/src/backend/concrete_simulation.hh +++ b/src/backend/concrete_simulation.hh @@ -33,7 +33,7 @@ namespace sgpem public: ConcreteSimulation(); - void run() throw(UserInterruptException); + void run() throw(UserInterruptException, NullPolicyException); void pause(); diff --git a/src/backend/dynamic_thread.cc b/src/backend/dynamic_thread.cc index 5187833..2b8f636 100644 --- a/src/backend/dynamic_thread.cc +++ b/src/backend/dynamic_thread.cc @@ -49,8 +49,9 @@ DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) DynamicThread::DynamicThread(const DynamicThread &other, DynamicProcess* parent) : Schedulable(), DynamicSchedulable(other), Thread(), - _state(other._state), _parent(parent), _ran_for(other._ran_for), - _last_acquisition(other._last_acquisition), _last_release(other._last_release) + _core(other._core), _state(other._state), _parent(parent), + _ran_for(other._ran_for), _last_acquisition(other._last_acquisition), + _last_release(other._last_release) { typedef vector::const_iterator ReqIt; diff --git a/src/backend/null_policy_exception.cc b/src/backend/null_policy_exception.cc new file mode 100644 index 0000000..8357c49 --- /dev/null +++ b/src/backend/null_policy_exception.cc @@ -0,0 +1,32 @@ +// src/backend/null_policy_exception.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 + +// Warning! This exception will be thrown across different libraries. +// It could be necessary to do dynamic type-checking when +// catching it (with typeinfo). + +#include "null_policy_exception.hh" +using namespace sgpem; + +NullPolicyException::NullPolicyException(const char* msg) + : std::runtime_error(msg) +{} + +NullPolicyException::~NullPolicyException() throw() {} diff --git a/src/backend/null_policy_exception.hh b/src/backend/null_policy_exception.hh new file mode 100644 index 0000000..cfccec0 --- /dev/null +++ b/src/backend/null_policy_exception.hh @@ -0,0 +1,46 @@ +// src/backend/null_policy_exception.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 + +// Warning! This exception will be thrown across different libraries. +// It could be necessary to do dynamic type-checking when +// catching it (with typeinfo). + +#ifndef NULL_POLICY_EXCEPTION +#define NULL_POLICY_EXCEPTION 1 + +#include "config.h" + +#include + +namespace sgpem +{ + class NullPolicyException; + + class SG_DLLEXPORT NullPolicyException : public std::runtime_error + { + public: + NullPolicyException(const char* msg = ""); + virtual ~NullPolicyException() throw (); + + private: + }; +} //~ namespace sgpem + +#endif diff --git a/src/backend/ready_queue.cc b/src/backend/ready_queue.cc index fd91f89..80a2375 100644 --- a/src/backend/ready_queue.cc +++ b/src/backend/ready_queue.cc @@ -57,6 +57,13 @@ ReadyQueue::get_item_at(position index) return *_scheds.at(index); } +const sgpem::Thread& +ReadyQueue::get_item_at(position index) const + throw (std::out_of_range) +{ + // Checks index access + return *_scheds.at(index); +} void ReadyQueue::append(Thread& thread) diff --git a/src/backend/ready_queue.hh b/src/backend/ready_queue.hh index 69fc3b4..eef3232 100644 --- a/src/backend/ready_queue.hh +++ b/src/backend/ready_queue.hh @@ -40,6 +40,7 @@ namespace sgpem void swap(position a, position b) throw (std::out_of_range); size_t size() const; Thread& get_item_at(position index) throw (std::out_of_range); + const Thread& get_item_at(position index) const throw (std::out_of_range); void append(Thread& schedulable); private: diff --git a/src/backend/simulation.hh b/src/backend/simulation.hh index 0a9eb6e..e1b6796 100644 --- a/src/backend/simulation.hh +++ b/src/backend/simulation.hh @@ -32,6 +32,7 @@ namespace sgpem #include "singleton.hh" #include "user_interrupt_exception.hh" +#include "null_policy_exception.hh" #include namespace sgpem @@ -76,7 +77,7 @@ namespace sgpem Advances the simulation by one or more steps, depending on the actual state and on the value set with set_mode(). */ - virtual void run() throw(UserInterruptException) = 0; + virtual void run() throw(UserInterruptException, NullPolicyException) = 0; /** \brief Pauses a running simulation. diff --git a/src/parse_opts.cc b/src/parse_opts.cc index 6b4ed4f..f45c530 100644 --- a/src/parse_opts.cc +++ b/src/parse_opts.cc @@ -23,10 +23,14 @@ #include "backend/global_preferences.hh" #include "backend/plugin_manager.hh" +#include "backend/policy_manager.hh" +#include "backend/policies_gatekeeper.hh" +#include "backend/module.hh" #include "text_simulation.hh" #include "io_manager.hh" #include "gui_builder.hh" #include "parse_opts.hh" +# #include #include @@ -35,7 +39,7 @@ #include using namespace sgpem; - +using namespace std; void parse_options(int argc, char** argv) @@ -110,7 +114,16 @@ parse_options(int argc, char** argv) // Now that GlobalPreferences has been initialized properly, // initialize plugins, too - PluginManager::get_instance(); + vector modules = PluginManager::get_instance().get_module_list(); + + for(vector::iterator it = modules.begin(); it != modules.end(); ++it) + (*it)->set_enabled(true); + + vector managers = PoliciesGatekeeper::get_instance().get_registered(); + + for(vector::iterator it = managers.begin(); it != managers.end(); ++it) + (*it)->init(); + if(no_gui_enabled) { diff --git a/src/text_simulation.cc b/src/text_simulation.cc index dff82f6..68103a8 100644 --- a/src/text_simulation.cc +++ b/src/text_simulation.cc @@ -89,10 +89,13 @@ namespace sgpem } - +TextSimulation::TextSimulation() +{ +} TextSimulation::~TextSimulation() -{} +{ +} /** Adds an IO_device and creates a thread which loops the read-parse-execute process @@ -120,7 +123,7 @@ TextSimulation::check_arguments_num(const Tokens& arguments, unsigned int num) return false; } else if(arguments.size() > num) - p_stderr(_("\nWARNING: some arguments will be ignored")); + p_stderr(_("\nWARNING: some arguments will be ignored\n")); return true; } @@ -187,10 +190,12 @@ template void TextSimulation::get_parameter(CommandParameter& parameter) { - bool correct = true; + bool correct; do { + correct = true; + ostringstream buf; buf << "\n"; @@ -333,6 +338,9 @@ TextSimulation::on_run(const Tokens& arguments) { check_arguments_num(arguments, 0); + // Listen for updates only during scheduling + Simulation::get_instance().get_history().attach(*this); + try { Simulation::get_instance().run(); @@ -343,6 +351,14 @@ TextSimulation::on_run(const Tokens& arguments) p_stderr(e.what()); p_stderr(_("\nSimulation is now stopped")); } + catch(NullPolicyException e) + { + p_stderr(_("\nERROR: ")); + p_stderr(e.what()); + p_stderr(_("\nSimulation is now stopped")); + } + + Simulation::get_instance().get_history().detach(*this); } void @@ -920,8 +936,8 @@ TextSimulation::on_show_cpu_policies(const Tokens& arguments) oss << "\t" << (*it)->get_description() << endl; p_stdout(oss.str()); + ++index; } - ++index; } } @@ -944,7 +960,10 @@ TextSimulation::on_add(const Tokens& arguments) } if(Simulation::get_instance().get_state() != Simulation::state_stopped) - p_stderr(_("WARNING: Simulation is not stopped, it will be automatically stopped")); + { + p_stderr(_("WARNING: Simulation is not stopped, it will be automatically stopped\n")); + Simulation::get_instance().stop(); + } //make a local copy which we'll probably modify Tokens args = arguments; @@ -1034,7 +1053,7 @@ TextSimulation::on_add_thread(const Tokens& arguments) } CommandParameter name(_("name"), "", "", false, ""); - CommandParameter cpu_time(_("cpu time"), 0, INT_MAX, true, 0); + CommandParameter cpu_time(_("cpu time"), 1, INT_MAX, true, 0); CommandParameter arrival_time(_("arrival time"), 0, INT_MAX, false, 0); CommandParameter base_priority(_("base priority"), 0, INT_MAX, false, 0); @@ -1209,10 +1228,9 @@ TextSimulation::on_remove_resource(const Tokens& arguments) ustring resource = arguments[0]; - const Environment& env = Simulation::get_instance().get_history().get_environment_at(0); - const Environment::Processes& processes = env.get_processes(); + //const Environment& env = Simulation::get_instance().get_history().get_environment_at(0); - ConcreteHistory::resource_key_t rid; + History::resource_key_t rid; try { @@ -1795,8 +1813,22 @@ TextSimulation::parse_command(TextSimulation& sim, const ustring& str) void -TextSimulation::update() +TextSimulation::update(const History& changed_history) { + p_stdout(_("\nqueue: { ")); + + const Environment& env = changed_history.get_last_environment(); + const ReadyQueue& q = env.get_sorted_queue(); + + for(unsigned int i = 0; i < q.size(); ++i) + { + const Thread& t = q.get_item_at(i); + + p_stdout(t.get_name() + " ~ "); + } + + p_stdout("}\n"); + // History& h = History::get_instance(); // int when, arr; // ustring temp; diff --git a/src/text_simulation.hh b/src/text_simulation.hh index 99fdf96..7974267 100644 --- a/src/text_simulation.hh +++ b/src/text_simulation.hh @@ -29,6 +29,7 @@ #include "templates/smartp.hh" //#include "backend/policy_parameters.hh" #include "backend/string_utils.hh" +#include "backend/history_observer.hh" #include "smartp.hh" @@ -55,9 +56,10 @@ 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 sigc::trackable + class SG_DLLEXPORT TextSimulation : public HistoryObserver { public: + TextSimulation(); ~TextSimulation(); /** @@ -120,13 +122,13 @@ namespace sgpem */ void add_io_device(memory::smart_ptr); + private: /** Prints the actual state of the simulation, with emphasis on the current status of the scheduling process (ready queue and running process). */ - void update(); + virtual void update(const History& changed_history); - private: bool check_arguments_num(const Tokens& arguments, unsigned int num); template void show(const Container& entities);