2006-02-17 23:19:25 +01:00
|
|
|
// src/backend/text_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 "text_simulation.hh"
|
|
|
|
using namespace std;
|
|
|
|
using namespace sgpem;
|
|
|
|
using namespace memory;
|
|
|
|
using Glib::Thread;
|
|
|
|
using Glib::ustring;
|
|
|
|
|
|
|
|
|
|
|
|
TextSimulation::~TextSimulation()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Adds an IO_device and creates a thread which loops the read-parse-execute process
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
TextSimulation::add_io_device(smart_ptr<IOManager> io)
|
|
|
|
{
|
|
|
|
_devices.push_back(io);
|
|
|
|
|
|
|
|
pair<TextSimulation*, int> p(this, 0);
|
|
|
|
|
|
|
|
Thread::create( sigc::bind(&TextSimulation::_io_loop, p), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::parse_command(pair< pair<TextSimulation*, int>, const ustring > p)
|
|
|
|
{
|
|
|
|
TextSimulation* obj = p.first.first;
|
|
|
|
int quale = p.first.second;
|
|
|
|
ustring str = p.second;
|
|
|
|
|
|
|
|
if (str.length() == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//CAPITALIZE alla grguments
|
|
|
|
str = str.uppercase();
|
|
|
|
|
|
|
|
vector<ustring> arguments;
|
|
|
|
uint f=0;
|
|
|
|
static const ustring whitespaces = " \r\b\n\t\a";
|
|
|
|
//fills the vector with parameters
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
f = str.find_first_of(whitespaces);
|
|
|
|
if (f > str.length())
|
|
|
|
{
|
|
|
|
//the end of the string
|
|
|
|
arguments.push_back(str);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//add the token
|
|
|
|
arguments.push_back(str.substr(0, f));
|
|
|
|
//trim the initial whitespaces
|
|
|
|
str = str.substr(f+1);
|
|
|
|
f = str.find_first_not_of(whitespaces);
|
|
|
|
str = str.substr(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (arguments.size() == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool show_help = false;
|
|
|
|
int param = 0;
|
|
|
|
check:
|
|
|
|
|
|
|
|
if (arguments[param] == "RUN")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- RUN COMMAND --\nStarts the simulation. It can be continuous or step-by-step"
|
|
|
|
" depending the mode configured with SetMode (default=continuous)"));
|
|
|
|
return;
|
|
|
|
}
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->run();
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
else if (arguments[param] == "PAUSE")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will restart it."));
|
|
|
|
return;
|
|
|
|
}
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->pause();
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
else if (arguments[param] == "STOP")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- STOP COMMAND --\nStops the simulation. The next call to RUN will "
|
|
|
|
"bring the simulation to the FIRST instant and start it."));
|
|
|
|
return;
|
|
|
|
}
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->stop();
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
else if (arguments[param] == "RESET")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- RESET COMMAND --\nResets the simulation jumping back to the first instant."));
|
|
|
|
return;
|
|
|
|
}
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->reset();
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
else if (arguments[param] == "QUIT")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- QUIT COMMAND --\nExits the program."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
obj->_devices[quale]->write_buffer(_("\n\n*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n\n"));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "HELP")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
2006-02-21 12:09:55 +01:00
|
|
|
"\n-- Do you really want me to explain what HELP means? --"
|
|
|
|
"\n ************** YOU ARE JOKING ME !!! ************\n\n"));
|
2006-02-17 23:19:25 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (arguments.size() == 1)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer( "\nAvaiable commands:\nRUN\nPAUSE\nSTOP\nRESET\nQUIT\nHELP"
|
|
|
|
"\nGETMODE\nSETMODE\nSETTIMER\nGETTIMER\nJUMPTO\nGETPOLICY"
|
|
|
|
"\nSETPOLICY\nGETPOLICYATTRIBUTES"
|
|
|
|
"\n\nHELP followed by a command shows help about it."
|
|
|
|
"\n ex. HELP RUN shows help about the command RUN");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
show_help = true;
|
|
|
|
param = 1;
|
|
|
|
goto check;
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "SETMODE")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- SetMode COMMAND --\nPermits to change the mode of the simulation.\n\nSintax: Setmode <param>\n\t<param> can take values:\n"
|
|
|
|
"\n\t\tCONTINUOUS - when calling RUN the simulation will show an animation using the wait-interval set by SETTIMER\n"
|
|
|
|
"\n\t\tSTEP - when calling RUN the simulation will show only one step of the animation\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (arguments.size() != 2)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters."
|
|
|
|
"\nType HELP SETMODE for the description of the sintax"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (arguments[1] == "CONTINUOUS")
|
|
|
|
obj->set_mode(true);
|
|
|
|
else if (arguments[1] == "STEP")
|
|
|
|
obj->set_mode(false);
|
|
|
|
else
|
|
|
|
obj->_devices[quale]->write_buffer(_("\nERROR: the second parameter can be only CONTINUOUS or STEP"));
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "GETMODE")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- GetMode COMMAND --\nReturns\n\tCONTINUOUS : if the simulation is shown with an animation"
|
|
|
|
"\n\tSTEP : if if the simulation is shown step-by-step"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (obj->get_mode())
|
|
|
|
obj->_devices[quale]->write_buffer(_("\nCONTINUOUS"));
|
|
|
|
else
|
|
|
|
obj->_devices[quale]->write_buffer(_("\nSTEP"));
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "SETTIMER")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- SetTimer COMMAND --\nPermits to change the interval between a step and the following one during a continuous animation."
|
|
|
|
"\n\nSintax: SetTimer <param>\n\t<param> must be an integer value > 0 and < 10000.\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (arguments.size() != 2)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters."
|
|
|
|
"\nType HELP SETTIMER for the description of the sintax"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int num;
|
|
|
|
if (string_to_int(arguments[1], num) && num > 0 && num < 10000)
|
|
|
|
obj->set_timer(num);
|
|
|
|
else
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\nERROR: the second parameter has a wrong value."
|
|
|
|
"\nType HELP SETTIMER for the description of the sintax"));
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "GETTIMER")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- GetTimer COMMAND --\nReturns the number of milliseconds the simulation "
|
|
|
|
"in the continuous mode waits between a step and the following one"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ustring ss;
|
|
|
|
int_to_string(obj->get_timer(), ss);
|
|
|
|
obj->_devices[quale]->write_buffer(ss);
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "JUMPTO")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- JumpTo COMMAND --\nPermits to jump to a desired instant of the simulation."
|
|
|
|
" All states of the simulation before <param> will be recalculated and printed out."
|
|
|
|
"\n\nSintax: JumpTo <param>\n\t<param> must be an integer value >= 0"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (arguments.size() != 2)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters."
|
|
|
|
"\nType HELP JUMPTO for the description of the sintax"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int num;
|
|
|
|
if (string_to_int(arguments[1], num) && num >= 0)
|
|
|
|
obj->jump_to(num);
|
|
|
|
else
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\nERROR: the second parameter has a wrong value."
|
|
|
|
"\nType HELP JUMPTO for the description of the sintax"));
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "GETPOLICY")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- GetPolicy COMMAND --\nReturns the name and the description of the current applied policy."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
obj->_devices[quale]->write_buffer(obj->get_policy()->get_description());
|
|
|
|
}
|
|
|
|
else if (arguments[param] == "GETPOLICYATTRIBUTES")
|
|
|
|
{
|
|
|
|
if (show_help)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer(_(
|
|
|
|
"\n-- GetPolicyAttributes COMMAND --\nReturns the list of attributes of the current applied policy."
|
|
|
|
"\nThe description of each parameter includes:"
|
|
|
|
"\n\tthe NAME of the marameter with its type\n\tits current VALUE"
|
|
|
|
"\n\tits LOWER and UPPER bounds\n\twhether the parameter is REQUIRED"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ustring temp;
|
|
|
|
|
|
|
|
const PolicyParameters& param = obj->get_policy()->get_parameters();
|
|
|
|
map<ustring, PolicyParameters::Parameter<int> > map_i = param.get_registered_int_parameters();
|
|
|
|
map<ustring, PolicyParameters::Parameter<int> >::iterator i_i = map_i.begin();
|
|
|
|
|
|
|
|
for(; i_i != map_i.end(); i_i++)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer("\nint\t" + i_i->second.get_name());
|
|
|
|
int_to_string(i_i->second.get_value(), temp);
|
|
|
|
obj->_devices[quale]->write_buffer("\tvalue=" + temp);
|
|
|
|
int_to_string(i_i->second.get_lower_bound(), temp);
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->_devices[quale]->write_buffer("\t\tlower=" + temp);
|
2006-02-17 23:19:25 +01:00
|
|
|
int_to_string(i_i->second.get_upper_bound(), temp);
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->_devices[quale]->write_buffer("\t\tupper=" + temp);
|
2006-02-17 23:19:25 +01:00
|
|
|
if (i_i->second.is_required())
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->_devices[quale]->write_buffer("\t\trequired=true");
|
2006-02-17 23:19:25 +01:00
|
|
|
else
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->_devices[quale]->write_buffer("\t\trequired=false");
|
|
|
|
}
|
|
|
|
|
|
|
|
map<ustring, PolicyParameters::Parameter<float> > map_f = param.get_registered_float_parameters();
|
|
|
|
map<ustring, PolicyParameters::Parameter<float> >::iterator i_f = map_f.begin();
|
|
|
|
|
|
|
|
for(; i_f != map_f.end(); i_f++)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer("\nfloat\t" + i_f->second.get_name());
|
|
|
|
float_to_string(i_f->second.get_value(), temp);
|
|
|
|
obj->_devices[quale]->write_buffer("\tvalue=" + temp);
|
|
|
|
float_to_string(i_f->second.get_lower_bound(), temp);
|
|
|
|
obj->_devices[quale]->write_buffer("\t\tlower=" + temp);
|
|
|
|
float_to_string(i_f->second.get_upper_bound(), temp);
|
|
|
|
obj->_devices[quale]->write_buffer("\t\tupper=" + temp);
|
|
|
|
if (i_f->second.is_required())
|
|
|
|
obj->_devices[quale]->write_buffer("\t\trequired=true");
|
|
|
|
else
|
|
|
|
obj->_devices[quale]->write_buffer("\t\trequired=false");
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
map<ustring, PolicyParameters::Parameter<ustring> > map_s = param.get_registered_string_parameters();
|
|
|
|
map<ustring, PolicyParameters::Parameter<ustring> >::iterator i_s = map_s.begin();
|
|
|
|
|
|
|
|
for(; i_s != map_s.end(); i_s++)
|
|
|
|
{
|
|
|
|
obj->_devices[quale]->write_buffer("\nustring\t" + i_s->second.get_name());
|
|
|
|
obj->_devices[quale]->write_buffer("\tvalue=" + i_s->second.get_value());
|
|
|
|
if (i_s->second.is_required())
|
|
|
|
obj->_devices[quale]->write_buffer(" required=true");
|
|
|
|
else
|
|
|
|
obj->_devices[quale]->write_buffer(" required=false");
|
|
|
|
}
|
2006-02-21 12:09:55 +01:00
|
|
|
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->_devices[quale]->write_buffer(_("\nCommand not recognized: "));
|
2006-02-17 23:19:25 +01:00
|
|
|
obj->_devices[quale]->write_buffer(arguments[param]);
|
2006-02-21 12:09:55 +01:00
|
|
|
obj->_devices[quale]->write_buffer(_("\nTyper HELP for a list of avaiable commands."));
|
2006-02-17 23:19:25 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::update()
|
|
|
|
{
|
2006-02-21 12:09:55 +01:00
|
|
|
History& h = History::get_instance();
|
|
|
|
int when, pri;
|
|
|
|
ustring temp;
|
|
|
|
|
|
|
|
when = h.get_current_time();
|
|
|
|
smart_ptr<SchedulableList> ll = h.get_simulation_status_at(when);
|
|
|
|
|
|
|
|
int_to_string(when, temp);
|
|
|
|
if (when<10)
|
|
|
|
_devices[0]->write_buffer("\n ");
|
|
|
|
else
|
|
|
|
_devices[0]->write_buffer("\n");
|
|
|
|
_devices[0]->write_buffer(temp + ") [RUNS]");
|
|
|
|
|
|
|
|
//insert the RUNNING ONE
|
|
|
|
smart_ptr<SchedulableStatus> running = h.get_scheduled_at(when);
|
|
|
|
if (running)
|
|
|
|
{
|
|
|
|
pri = running->get_schedulable()->get_priority();
|
|
|
|
int_to_string(pri, temp);
|
|
|
|
_devices[0]->write_buffer(" " + running->get_schedulable()->get_name() + "_(" + temp + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
_devices[0]->write_buffer(" --[READY]");
|
|
|
|
//insert the READY ones
|
|
|
|
for (uint i = 0; i < ll->size(); i++)
|
|
|
|
if (ll->get_item_at(i)->get_state() == SchedulableStatus::state_ready)
|
|
|
|
{
|
|
|
|
pri = ll->get_item_at(i)->get_schedulable()->get_priority();
|
|
|
|
int_to_string(pri, temp);
|
|
|
|
_devices[0]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
|
|
|
|
}
|
2006-02-17 23:19:25 +01:00
|
|
|
|
2006-02-21 12:09:55 +01:00
|
|
|
_devices[0]->write_buffer(" --[BLOCKED]");
|
|
|
|
//insert the BLOCKED ones
|
|
|
|
for (uint i = 0; i < ll->size(); i++)
|
|
|
|
if (ll->get_item_at(i)->get_state() == SchedulableStatus::state_blocked)
|
|
|
|
{
|
|
|
|
pri = ll->get_item_at(i)->get_schedulable()->get_priority();
|
|
|
|
int_to_string(pri, temp);
|
|
|
|
_devices[0]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
_devices[0]->write_buffer(" --[FUTURE]");
|
|
|
|
//insert the FUTURE ones
|
|
|
|
for (uint i = 0; i < ll->size(); i++)
|
|
|
|
if (ll->get_item_at(i)->get_state() == SchedulableStatus::state_future)
|
|
|
|
{
|
|
|
|
pri = ll->get_item_at(i)->get_schedulable()->get_priority();
|
|
|
|
int_to_string(pri, temp);
|
|
|
|
_devices[0]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
_devices[0]->write_buffer(" --[TERM]");
|
|
|
|
//insert the TERMINATED ones
|
|
|
|
for (uint i = 0; i < ll->size(); i++)
|
|
|
|
if (ll->get_item_at(i)->get_state() == SchedulableStatus::state_terminated)
|
|
|
|
{
|
|
|
|
pri = ll->get_item_at(i)->get_schedulable()->get_priority();
|
|
|
|
int_to_string(pri, temp);
|
|
|
|
_devices[0]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
|
|
|
|
}
|
|
|
|
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::_io_loop(pair<TextSimulation* , int > pun)
|
|
|
|
{
|
|
|
|
while(true)
|
|
|
|
{
|
|
|
|
//reads the command
|
|
|
|
ustring str;
|
|
|
|
pun.first->_devices[pun.second]->write_buffer("\nSGPEM=> ");
|
|
|
|
str = pun.first->_devices[pun.second]->read_command();
|
|
|
|
|
|
|
|
pair<pair<TextSimulation*, int>, const ustring> p(pair<TextSimulation*, int>(pun.first, pun.second), str);
|
|
|
|
|
|
|
|
if (pun.first->_devices[pun.second]->is_full_duplex())
|
|
|
|
//if the IOManager can read AND write at the same time then create a new thread
|
|
|
|
//thath will write to it while going on reading the next command
|
|
|
|
Thread::create( sigc::bind(&TextSimulation::parse_command, p), true);
|
|
|
|
else
|
|
|
|
//no read is possible: only write
|
|
|
|
pun.first->parse_command(p);
|
|
|
|
}
|
|
|
|
}
|