sgpemv2/src/text_simulation.cc

849 lines
28 KiB
C++
Raw Normal View History

// 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 "backend/string_utils.hh"
#include "backend/policies_gatekeeper.hh"
#include "backend/policy_manager.hh"
#include "backend/policy_parameters.hh"
#include "backend/history.hh"
#include "text_simulation.hh"
#include <sstream>
using namespace std;
using namespace sgpem;
using namespace memory;
using Glib::Thread;
using Glib::ustring;
#include "smartp.tcc"
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);
//if (!io->is_full_duplex())
// Thread::create( sigc::bind(&TextSimulation::_io_loop, p), true);
}
void
TextSimulation::arguments_ignored(const Tokens& arguments)
{
if(arguments.size() != 0)
p_stderr(_("\nWARNING: some arguments will be ignored"));
}
void
TextSimulation::on_run(const Tokens& arguments)
{
arguments_ignored(arguments);
try
{
run();
}
catch(UserInterruptException e)
{
p_stderr(_("\nERROR: "));
p_stderr(e.what());
p_stderr(_("\nSimulation is now stopped"));
}
}
void
TextSimulation::on_pause(const Tokens& arguments)
{
arguments_ignored(arguments);
pause();
}
void
TextSimulation::on_stop(const Tokens& arguments)
{
arguments_ignored(arguments);
stop();
}
void
TextSimulation::on_configure_cpu_policy(const Tokens& arguments)
{
arguments_ignored(arguments);
PolicyParameters& parameters = get_policy()->get_parameters();
p_stdout(_("\nPlease provide a value for each attribute"));
p_stdout(_("\nMandatory arguments are marked with an asterisk (*)"));
typedef map<ustring, PolicyParameters::Parameter<int> > IntParams;
typedef map<ustring, PolicyParameters::Parameter<float> > FloatParams;
typedef map<ustring, PolicyParameters::Parameter<ustring> > StringParams;
// TODO for int and double this code is easily replaced with a call to a
// template function. for strings we'll need to specialize it...
IntParams int_params = parameters.get_registered_int_parameters();
for(IntParams::iterator it = int_params.begin(); it != int_params.end();)
{
PolicyParameters::Parameter<int> &p = it->second;
ostringstream buf;
buf << "\n";
if(p.is_required())
buf << "*";
buf << p.get_name() << " (range: [" << p.get_lower_bound() << ", " <<
p.get_upper_bound() << "] default: " << p.get_default() << ") = ";
p_stdout(buf.str());
bool arg_provided = false;
bool correct = true;
ustring input = readline();
int value;
// FIXME semi-hack, it's a bit overkill to tokenize the string
// to find if it's only composed of white spaces...
// Indedeed there's a pro: by using extensively tokenize() we are more sure
// it's correct ;-)
if(tokenize(input).size() > 0)
{
try
{
value = string_to_int(input);
}
catch(domain_error e)
{
p_stderr(_("\nERROR: Please provide a valid integer value"));
correct = false;
}
if(value > p.get_upper_bound() || value < p.get_lower_bound())
{
p_stderr(_("\nERROR: Provided value is out of range"));
correct = false;
}
if(correct)
p.set_value(value);
}
else if(p.is_required())
{
p_stderr(_("\nERROR: This is a mandatory attribute; you MUST provide a valid value!"));
correct = false;
}
if(correct)
++it;
}
//FIXME code for float arguments
// StringParams string_params = parameters->get_registered_string_parameters();
//
// for(StringParams::iterator it = int_params.begin(); it != int_params.end();)
// {
// Parameter<ustring> &p = *it;
// ustring buf;
//
// buf = "\n";
//
// if(p.is_required())
// buf += "*";
//
// p_stdout(buf + p.get_name() + " = ");
//
// buf = read();
//
// // FIXME semi-hack, it's a bit overkill to tokenize the string
// // to find if it's only composed of white spaces...
// // Indedeed there's a pro: by using extensively tokenize() we are more sure
// // it's correct ;-)
// Tokens tokens = tokenize(input);
//
// if(tokens.size() == 0 && p.is_required())
// p_stderr(_("\nERROR: This is a mandatory atribute; you MUST provide a valid value!"));
// else
// {
// p.set_value(tokens[0]);
// ++it;
// }
//
// }
}
void
TextSimulation::on_help(const Tokens& arguments)
{
ustring command;
//make a local copy which we'll probably modify
Tokens args = arguments;
if(args.size() > 1)
{
command = args[0].uppercase();
args.erase(args.begin());
}
arguments_ignored(args);
if(command.size() == 0)
p_stdout(_("\nAvaiable commands:\nRUN\nPAUSE\nSTOP\nQUIT\nHELP"
"\nGET\nSET\nSHOW\nADD\nREMOVE"
"\n\nHELP followed by a command shows help about it."
"\n ex. HELP RUN shows help about the command RUN"));
else if(command == "RUN")
p_stdout(_("\n-- RUN COMMAND --\nStarts the simulation. It can be "
"continuous or step-by-step depending on the mode configured with "
"SET MODE (default=CONTINUOUS).\n\n"
"The output of RUN is one or more rows each of which represents the "
"state of the schedulable entities. It can be RUNNING, READY, BLOCKED, "
"FUTURE or TERMINATED."
"\nThe row begins with the number of the instant described by the "
"following lists of states. The instant 0 represents the INITIAL STATE "
"during which no process is running. The scheduler "
"activity begins at instant 1. Each schedulable entity is represented by "
"its name followed "
"by its priority enclosed between round parenthesis."));
else if(command == "STOP")
p_stdout(_("\n-- STOP COMMAND --\nStops the simulation. The next call to RUN will "
"bring the simulation to the FIRST instant and start it."));
else if(command == "PAUSE")
p_stdout(_("\n-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will restart it."));
else if(command == "CONFIGURE-CPU-POLICY")
p_stdout(_("\nFIXME"));
else if(command == "HELP")
p_stdout(_("\n-- Do you really want me to explain what HELP means? --"
"\n ************** YOU ARE JOKING ME !!! ************\n\n"));
else if(command == "GET")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "SET")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "SHOW")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "ADD")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "REMOVE")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "QUIT")
p_stderr(_("\nFIXME: Not implemented"));
else
p_stderr(_("\nERROR: Sorry, no help available for this command."));
}
void
TextSimulation::on_quit(const Tokens& arguments)
{
arguments_ignored(arguments);
p_stdout(_("\n\n*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n\n"));
// Is this ok? Really? Oh, sure, if it we always did it in this way, it is surely a Good Thing!
exit(1);
}
void
TextSimulation::on_get(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_set(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_show(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_add(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_remove(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::p_stdout(const ustring& str)
{
cout << str;
}
void
TextSimulation::p_stderr(const ustring& str)
{
cerr << str;
}
ustring
TextSimulation::readline()
{
string str;
getline(cin, str);
return str;
}
void
TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const ustring > p)
{
typedef void (TextSimulation::*f_ptr)(const Tokens&);
map<ustring, f_ptr> command_handlers;
command_handlers["RUN"] = &TextSimulation::on_run;
command_handlers["STOP"] = &TextSimulation::on_stop;
command_handlers["PAUSE"] = &TextSimulation::on_pause;
command_handlers["CONFIGURE-CPU-POLICY"] = &TextSimulation::on_configure_cpu_policy;
command_handlers["HELP"] = &TextSimulation::on_help;
command_handlers["GET"] = &TextSimulation::on_get;
command_handlers["SET"] = &TextSimulation::on_set;
command_handlers["SHOW"] = &TextSimulation::on_show;
command_handlers["ADD"] = &TextSimulation::on_add;
command_handlers["REMOVE"] = &TextSimulation::on_remove;
command_handlers["QUIT"] = &TextSimulation::on_quit;
ustring str = p.second;
Tokens arguments = tokenize(str);
if(arguments.size() == 0)
return;
if(command_handlers.find(arguments[0]) == command_handlers.end())
{
p_stderr(_("\nERROR: command not supported"));
return;
}
ustring key = arguments[0].uppercase();
arguments.erase(arguments.begin());
TextSimulation* obj = p.first.first;
(obj->*(command_handlers[key]))(arguments);
}
// ** Please do NOT delete this code, I still use it as a reference **
//void
//TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const ustring > p)
//{
//
// TextSimulation* obj = p.first.first;
// ustring str = p.second;
// //looks for the IOManager who sent the command
// uint quale = 0;
// for (; quale < obj->_devices.size(); quale++)
// if (p.first.second == &(*obj->_devices[quale]))
// break;
//
// 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 on the mode configured with SetMode (default=continuous).\n\n"
// "The output of RUN is one or more rows each of which represents the state of the "
// "schedulable entities. It can be RUNNING, READY, BLOCKED, FUTURE or TERMINATED."
// "\nThe row begins with the number of the instant described by the following lists of states. "
// "The instant 0 represents the INITIAL STATE during which no process is running. The scheduler "
// "activity begins at instant 1. Each schedulable entity is represented by its name followed "
// "by its priority enclosed between round parenthesis."));
// return;
// }
//
// try
// {
// obj->run();
// }
// catch(UserInterruptException e)
// {
// obj->_devices[quale]->write_buffer(_("\nERROR: "));
// obj->_devices[quale]->write_buffer(_(e.what()));
// obj->_devices[quale]->write_buffer(_("\nSimulation is now stopped"));
//
// }
// }
// 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;
// }
// obj->pause();
// }
// 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;
// }
// obj->stop();
// }
// 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;
// }
// obj->reset();
// }
// 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(_(
// "\n-- Do you really want me to explain what HELP means? --"
// "\n ************** YOU ARE JOKING ME !!! ************\n\n"));
// 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] == "SETPOLICY")
// {
// if(show_help)
// {
// obj->_devices[quale]->write_buffer(_(
// "\n-- SetPolicy COMMAND --\nSelects the current applied policy."
// "Syntax: SetPolicy <name>"));
// return;
// }
//
//
// //FIXME assuming only one policy manager is present, but who cares, this
// //is only temporary code...
// PolicyManager* manager = PoliciesGatekeeper::get_instance().get_registered()[0];
//
// vector<Policy*> available = manager->get_avail_policies();
//
//
// obj->_devices[quale]->write_buffer(arguments[1] + "\n");
//
// for(vector<Policy*>::iterator it = available.begin(); it != available.end(); ++it)
// {
// if((*it)->get_name().casefold() == arguments[1].casefold())
// {
// obj->stop();
// PoliciesGatekeeper::get_instance().activate_policy(&History::get_instance(), *it);
// return;
// }
// }
//
//
// obj->_devices[quale]->write_buffer(_(
// "\nERROR: no policy found with that name."
// "\nType HELP SETPOLICY for the description of the sintax"));
//
// }
// else if(arguments[param] == "LISTPOLICIES")
// {
// if(show_help)
// {
// obj->_devices[quale]->write_buffer(_(
// "\n-- ListPolicies COMMAND --\nShows the name of available policies."));
// return;
// }
//
// //FIXME assuming only one policy manager is present, but who cares, this
// //is only temporary code...
// PolicyManager* manager = PoliciesGatekeeper::get_instance().get_registered()[0];
//
// vector<Policy*> available = manager->get_avail_policies();
//
// for(vector<Policy*>::iterator it = available.begin(); it != available.end(); ++it)
// {
//
//// Glib::ustring str;
//// int_to_string((int)*it, str);
//// obj->_devices[quale]->write_buffer(str + "\n");
// obj->_devices[quale]->write_buffer("\n" + (*it)->get_name());
// }
// }
// 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);
// obj->_devices[quale]->write_buffer("\t\tlower=" + temp);
// int_to_string(i_i->second.get_upper_bound(), temp);
// obj->_devices[quale]->write_buffer("\t\tupper=" + temp);
// if (i_i->second.is_required())
// obj->_devices[quale]->write_buffer("\t\trequired=true");
// else
// 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");
// }
//
// 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");
// }
//
// }
// else
// {
// obj->_devices[quale]->write_buffer(_("\nCommand not recognized: "));
// obj->_devices[quale]->write_buffer(arguments[param]);
// obj->_devices[quale]->write_buffer(_("\nTyper HELP for a list of avaiable commands."));
// return;
// }
//}
void
TextSimulation::update()
{
// History& h = History::get_instance();
// int when, arr;
// ustring temp;
//
// when = h.get_current_time();
// smart_ptr<ReadyQueue> ll = h.get_simulation_status_at(when);
//
// for (uint dev = 0; dev < _devices.size(); dev++)
// {
// int_to_string(when, temp);
// if (when < 10)
// _devices[dev]->write_buffer("\n ");
// else
// _devices[dev]->write_buffer("\n");
// _devices[dev]->write_buffer(temp + ") [RUNS]");
//
// //insert the RUNNING ONE
// smart_ptr<DynamicSchedulable> running = h.get_scheduled_at(when);
// if (running)
// {
// arr = running->get_schedulable()->get_arrival_time();
// int_to_string(arr, temp);
// _devices[dev]->write_buffer(" " + running->get_schedulable()->get_name() + "_(" + temp + ")");
// }
//
// _devices[dev]->write_buffer(" --[READY]");
// //insert the READY ones
// for (uint i = 0; i < ll->size(); i++)
// if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_ready)
// {
// arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
// int_to_string(arr, temp);
// _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
// }
//
// _devices[dev]->write_buffer(" --[BLOCKED]");
// //insert the BLOCKED ones
// for (uint i = 0; i < ll->size(); i++)
// if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_blocked)
// {
// arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
// int_to_string(arr, temp);
// _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
// }
//
// _devices[dev]->write_buffer(" --[FUTURE]");
// //insert the FUTURE ones
// for (uint i = 0; i < ll->size(); i++)
// if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_future)
// {
// arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
// int_to_string(arr, temp);
// _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
// }
//
// _devices[dev]->write_buffer(" --[TERM]");
// //insert the TERMINATED ones
// for (uint i = 0; i < ll->size(); i++)
// if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_terminated)
// {
// arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
// int_to_string(arr, temp);
// _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
// }
//
// }
}
void
TextSimulation::_io_loop(pair<TextSimulation* , int > pun)
{
while(true)
{
//reads the command
ustring str;
//the sgpem cursor appears only in the console
//if (!pun.first->_devices[pun.second]->is_full_duplex())
pun.first->_devices[pun.second]->write_buffer("\nSGPEM=> ");
str = pun.first->_devices[pun.second]->read_command();
pair< pair<TextSimulation*, IOManager*>, const ustring > p
(pair<TextSimulation*, IOManager*>(pun.first, &(*pun.first->_devices[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);
}
}