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
|
|
|
|
|
2006-08-27 16:36:23 +02:00
|
|
|
#include "backend/global_preferences.hh"
|
2006-02-21 12:30:19 +01:00
|
|
|
#include "backend/string_utils.hh"
|
2006-08-02 23:57:36 +02:00
|
|
|
#include "backend/cpu_policies_gatekeeper.hh"
|
|
|
|
#include "backend/cpu_policy_manager.hh"
|
2006-07-09 18:27:16 +02:00
|
|
|
#include "backend/policy_parameters.hh"
|
2006-06-15 22:07:03 +02:00
|
|
|
#include "backend/history.hh"
|
2006-08-18 02:46:38 +02:00
|
|
|
#include "backend/simulation.hh"
|
2006-08-07 02:54:43 +02:00
|
|
|
#include "backend/serializers_gatekeeper.hh"
|
|
|
|
#include "backend/serializer.hh"
|
2006-08-27 16:36:23 +02:00
|
|
|
#include "backend/process.hh"
|
|
|
|
#include "backend/resource.hh"
|
2006-08-29 00:40:08 +02:00
|
|
|
// FIXME: remove the following and use the gatekeeper
|
|
|
|
#include "backend/resource_policy_lifo.hh"
|
2006-08-27 16:36:23 +02:00
|
|
|
#include "backend/thread.hh"
|
|
|
|
#include "backend/request.hh"
|
|
|
|
#include "backend/sub_request.hh"
|
|
|
|
#include "backend/ready_queue.hh"
|
2006-07-11 00:28:51 +02:00
|
|
|
|
2006-02-17 23:19:25 +01:00
|
|
|
#include "text_simulation.hh"
|
2006-06-23 15:06:39 +02:00
|
|
|
|
2006-08-27 16:36:23 +02:00
|
|
|
#include <glibmm/timer.h>
|
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
#include <cassert>
|
|
|
|
#include <ios>
|
|
|
|
#include <iomanip>
|
2006-07-09 18:27:16 +02:00
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
2006-02-17 23:19:25 +01:00
|
|
|
using namespace std;
|
|
|
|
using namespace sgpem;
|
|
|
|
using namespace memory;
|
|
|
|
using Glib::Thread;
|
|
|
|
using Glib::ustring;
|
|
|
|
|
2006-06-23 15:06:39 +02:00
|
|
|
#include "smartp.tcc"
|
2006-02-17 23:19:25 +01:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
namespace sgpem
|
|
|
|
{
|
2006-07-13 23:09:27 +02:00
|
|
|
//TODO move this class to another file... (?)
|
2006-07-13 01:52:09 +02:00
|
|
|
template <typename T>
|
|
|
|
class CommandParameter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CommandParameter(const ustring& _description,
|
|
|
|
const T& _low_bound,
|
|
|
|
const T& _up_bound,
|
|
|
|
bool _required,
|
|
|
|
const T& _preset);
|
|
|
|
|
|
|
|
CommandParameter(const PolicyParameters::Parameter<T>& pparam);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
ustring description;
|
|
|
|
T low_bound;
|
|
|
|
T up_bound;
|
|
|
|
bool required;
|
|
|
|
T preset;
|
|
|
|
T value;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
CommandParameter<T>::CommandParameter(const ustring& _description,
|
2006-08-09 16:38:45 +02:00
|
|
|
const T& _low_bound,
|
|
|
|
const T& _up_bound,
|
|
|
|
bool _required,
|
|
|
|
const T& _preset) :
|
|
|
|
description(_description), low_bound(_low_bound),
|
|
|
|
up_bound(_up_bound), required(_required), preset(_preset),
|
|
|
|
value(_preset)
|
|
|
|
{}
|
2006-07-13 01:52:09 +02:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
CommandParameter<T>::CommandParameter(const PolicyParameters::Parameter<T>& pparam) :
|
2006-08-09 16:38:45 +02:00
|
|
|
description(pparam.get_name()),
|
|
|
|
low_bound(pparam.get_lower_bound()),
|
|
|
|
up_bound(pparam.get_upper_bound()), required(pparam.is_required()),
|
|
|
|
preset(pparam.get_default()), value(pparam.get_value())
|
|
|
|
{}
|
2006-07-13 01:52:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-08 02:20:56 +02:00
|
|
|
TextSimulation::TextSimulation() :
|
2006-08-09 16:38:45 +02:00
|
|
|
_saved(true)
|
|
|
|
{}
|
2006-07-13 01:52:09 +02:00
|
|
|
|
2006-02-17 23:19:25 +01:00
|
|
|
TextSimulation::~TextSimulation()
|
2006-08-09 16:38:45 +02:00
|
|
|
{}
|
2006-02-17 23:19:25 +01:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
bool
|
|
|
|
TextSimulation::check_arguments_num(const Tokens& arguments, unsigned int num)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (arguments.size() < num)
|
2006-07-12 00:50:41 +02:00
|
|
|
{
|
|
|
|
ostringstream oss;
|
2006-08-01 01:18:51 +02:00
|
|
|
oss << _("ERROR: this command requires at least ") << num << _(" arguments\n");
|
2006-07-12 00:50:41 +02:00
|
|
|
p_stderr(oss.str());
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (arguments.size() > num)
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("WARNING: some arguments will be ignored\n"));
|
2006-07-12 00:50:41 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-08-08 02:20:56 +02:00
|
|
|
bool
|
|
|
|
TextSimulation::unsaved_ask_confirm() const
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!_saved)
|
2006-08-08 02:20:56 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("WARNING: Simulation was not recently saved. "
|
2006-08-09 16:38:45 +02:00
|
|
|
"If you continue some changes to the simulation might be lost.\n"));
|
2006-08-08 02:20:56 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (bool bad_arg = true; bad_arg;)
|
2006-08-08 02:20:56 +02:00
|
|
|
{
|
|
|
|
p_stdout(_("Continue? [y/n] "));
|
|
|
|
|
|
|
|
ustring buf = readline();
|
|
|
|
|
|
|
|
Tokens tokens = tokenize(buf);
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (tokens.size() == 1 && tokens[0].size() == 1)
|
2006-08-08 02:20:56 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (tokens[0].lowercase() == _("n"))
|
|
|
|
return false;
|
|
|
|
else if (tokens[0].lowercase() == _("y"))
|
|
|
|
bad_arg = false;
|
2006-08-08 02:20:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
template <typename Container>
|
2006-07-12 00:50:41 +02:00
|
|
|
void
|
2006-07-16 23:43:54 +02:00
|
|
|
TextSimulation::show(const Container& entities)
|
2006-07-12 00:50:41 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
for (unsigned int i = 0; i < entities.size(); ++i)
|
|
|
|
{
|
2006-07-16 23:43:54 +02:00
|
|
|
ostringstream oss;
|
|
|
|
oss << i + 1 << ". " << entities[i]->get_name() << endl;
|
2006-07-12 00:50:41 +02:00
|
|
|
p_stdout(oss.str());
|
|
|
|
}
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
// Specializations need to go explicitly inside the namespace. why?
|
2006-07-13 00:46:55 +02:00
|
|
|
namespace sgpem
|
|
|
|
{
|
|
|
|
template <>
|
|
|
|
void
|
2006-08-09 16:38:45 +02:00
|
|
|
TextSimulation::show<vector<Request*> > (const vector<Request*>& entities)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
for (unsigned int i = 0; i < entities.size(); ++i)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
2006-07-16 23:43:54 +02:00
|
|
|
ostringstream oss;
|
|
|
|
oss << i + 1 << ". instant: " << entities[i]->get_instant() << endl;
|
2006-07-13 00:46:55 +02:00
|
|
|
p_stdout(oss.str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
void
|
2006-08-09 16:38:45 +02:00
|
|
|
TextSimulation::show<vector<SubRequest*> > (const vector<SubRequest*>& entities)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
for (unsigned int i = 0; i < entities.size(); ++i)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
ostringstream oss;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
oss << i + 1 << ". resource: " << entities[i]->get_resource_key() << endl;
|
|
|
|
p_stdout(oss.str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
void
|
2006-08-09 16:38:45 +02:00
|
|
|
TextSimulation::show<map<int, Resource*> > (const map<int, Resource*>& entities)
|
2006-07-16 23:43:54 +02:00
|
|
|
{
|
|
|
|
typedef map<int, Resource*>::const_iterator ResourceIt;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
for (ResourceIt it = entities.begin(); it != entities.end(); ++it)
|
2006-07-16 23:43:54 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
ostringstream oss;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
oss << it->first << ". " << it->second->get_name();
|
|
|
|
oss << "[" << it->second->get_places() << "]" << endl;
|
2006-07-13 00:46:55 +02:00
|
|
|
p_stdout(oss.str());
|
|
|
|
}
|
|
|
|
}
|
2006-07-16 23:43:54 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
} //~ namespace sgpem
|
2006-07-13 00:46:55 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
template <typename T>
|
|
|
|
void
|
|
|
|
TextSimulation::get_parameter(CommandParameter<T>& parameter)
|
|
|
|
{
|
2006-07-24 00:27:33 +02:00
|
|
|
bool correct;
|
2006-07-13 01:52:09 +02:00
|
|
|
|
|
|
|
do
|
2006-08-09 16:38:45 +02:00
|
|
|
{
|
2006-07-24 00:27:33 +02:00
|
|
|
correct = true;
|
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
ostringstream buf;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (parameter.required)
|
2006-07-13 01:52:09 +02:00
|
|
|
buf << "*";
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
buf << parameter.description << " (range: [" << parameter.low_bound << ", " <<
|
|
|
|
parameter.up_bound << "] current: " << parameter.value << ") : ";
|
2006-07-13 01:52:09 +02:00
|
|
|
|
|
|
|
p_stdout(buf.str());
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
ustring input = readline();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
T value;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (tokenize(input).size() > 0)
|
2006-07-13 01:52:09 +02:00
|
|
|
{
|
|
|
|
try
|
2006-08-09 16:38:45 +02:00
|
|
|
{
|
|
|
|
value = string_to<T>(input);
|
|
|
|
|
|
|
|
if (value > parameter.up_bound || value < parameter.low_bound)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: Provided value is out of range\n"));
|
|
|
|
correct = false;
|
|
|
|
}
|
2006-07-13 01:52:09 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-13 01:52:09 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
p_stderr(_("ERROR: Please provide a valid numeric value\n"));
|
|
|
|
correct = false;
|
2006-07-13 01:52:09 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (correct)
|
|
|
|
parameter.value = value;
|
2006-07-13 01:52:09 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (parameter.required)
|
2006-07-13 01:52:09 +02:00
|
|
|
{
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: This is a mandatory attribute; you MUST provide a valid value!\n"));
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
correct = false;
|
|
|
|
}
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
while (!correct);
|
2006-07-13 01:52:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Specializations need to go explicitly inside the namespace. why?
|
|
|
|
namespace sgpem
|
|
|
|
{
|
|
|
|
template <>
|
|
|
|
void
|
|
|
|
TextSimulation::get_parameter<ustring>(CommandParameter<ustring>& parameter)
|
|
|
|
{
|
|
|
|
bool loop = true;
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
while (loop)
|
2006-07-13 01:52:09 +02:00
|
|
|
{
|
|
|
|
ustring buf;
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (parameter.required)
|
|
|
|
buf += "*";
|
|
|
|
|
|
|
|
p_stdout(buf + parameter.description +
|
|
|
|
" (current: \"" + parameter.value + "\") : ");
|
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
buf = readline();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
Tokens tokens = tokenize(buf);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (tokens.size() == 0 && parameter.required)
|
|
|
|
p_stderr(_("ERROR: This is a mandatory atribute; you MUST provide a valid value!\n"));
|
2006-07-13 01:52:09 +02:00
|
|
|
else
|
2006-08-09 16:38:45 +02:00
|
|
|
{
|
|
|
|
parameter.value = buf;
|
|
|
|
loop = false;
|
2006-07-13 01:52:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-13 17:07:15 +02:00
|
|
|
|
|
|
|
template <>
|
|
|
|
void
|
|
|
|
TextSimulation::get_parameter<bool>(CommandParameter<bool>& parameter)
|
|
|
|
{
|
2006-07-29 02:24:48 +02:00
|
|
|
bool correct;
|
2006-07-13 17:07:15 +02:00
|
|
|
|
2006-07-29 02:24:48 +02:00
|
|
|
do
|
2006-07-13 17:07:15 +02:00
|
|
|
{
|
2006-07-29 02:24:48 +02:00
|
|
|
correct = true;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 17:07:15 +02:00
|
|
|
ostringstream buf;
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (parameter.required)
|
|
|
|
buf << "*";
|
|
|
|
|
|
|
|
buf << parameter.description <<
|
|
|
|
" (current: " << boolalpha << parameter.value << ") : ";
|
|
|
|
|
2006-07-13 17:07:15 +02:00
|
|
|
p_stdout(buf.str());
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 17:07:15 +02:00
|
|
|
ustring str = readline();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 17:07:15 +02:00
|
|
|
Tokens tokens = tokenize(str);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (tokens.size() != 0)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
parameter.value = string_to<bool>(str);
|
|
|
|
}
|
|
|
|
catch (domain_error e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: Please provide a valid boolean value ('true' or 'false')\n"));
|
|
|
|
correct = false;
|
|
|
|
}
|
2006-07-13 17:07:15 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (parameter.required)
|
2006-07-29 02:24:48 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
p_stderr(_("ERROR: This is a mandatory atribute; you MUST provide a valid value!\n"));
|
|
|
|
correct = false;
|
2006-07-29 02:24:48 +02:00
|
|
|
}
|
2006-07-13 17:07:15 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
while (!correct);
|
2006-07-13 17:07:15 +02:00
|
|
|
}
|
2006-07-13 01:52:09 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
void
|
|
|
|
TextSimulation::on_run(const Tokens& arguments)
|
|
|
|
{
|
2006-07-12 00:50:41 +02:00
|
|
|
check_arguments_num(arguments, 0);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-24 00:27:33 +02:00
|
|
|
// Listen for updates only during scheduling
|
2006-08-18 02:46:38 +02:00
|
|
|
Simulation::get_instance().attach(*this);
|
2006-07-24 00:27:33 +02:00
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
try
|
|
|
|
{
|
2006-08-27 16:36:23 +02:00
|
|
|
Simulation& sim = Simulation::get_instance();
|
|
|
|
switch(sim.get_mode())
|
|
|
|
{
|
|
|
|
case Simulation::mode_step_by_step:
|
|
|
|
sim.run();
|
|
|
|
break;
|
|
|
|
case Simulation::mode_continuous:
|
|
|
|
int interval = GlobalPreferences::get_instance().get_speed() * 1000;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
sim.run();
|
|
|
|
Glib::usleep(interval);
|
|
|
|
}
|
|
|
|
while(sim.get_state() != Simulation::state_stopped);
|
|
|
|
break;
|
|
|
|
}
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
2006-08-11 00:59:00 +02:00
|
|
|
catch (const UserInterruptException& e)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: "));
|
2006-07-09 18:27:16 +02:00
|
|
|
p_stderr(e.what());
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("\nSimulation is now stopped\n"));
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
2006-08-11 00:59:00 +02:00
|
|
|
catch (const MalformedPolicyException& e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: "));
|
|
|
|
p_stderr(e.what());
|
|
|
|
p_stderr(_("\nSimulation is now stopped, and "
|
|
|
|
"the current policy will be deactivated\n"));
|
2006-08-13 16:20:04 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
Simulation::get_instance().set_policy(NULL);
|
|
|
|
}
|
|
|
|
catch(const CPUPolicyException& f)
|
|
|
|
{
|
|
|
|
// should never happen
|
|
|
|
p_stderr(_("FATAL ERROR: unable to deactivate the policy: "));
|
|
|
|
p_stderr(f.what());
|
|
|
|
abort();
|
|
|
|
}
|
2006-08-11 00:59:00 +02:00
|
|
|
}
|
|
|
|
catch (const NullPolicyException& e)
|
2006-07-24 00:27:33 +02:00
|
|
|
{
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: "));
|
2006-07-24 00:27:33 +02:00
|
|
|
p_stderr(e.what());
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("\nSimulation is now stopped\n"));
|
2006-07-24 00:27:33 +02:00
|
|
|
}
|
2006-08-30 17:31:25 +02:00
|
|
|
catch (const CPUPolicyException& e)
|
|
|
|
{
|
|
|
|
p_stderr(_("UNKNOWN ERROR: "));
|
|
|
|
p_stderr(e.what());
|
|
|
|
p_stderr("\n");
|
|
|
|
}
|
2006-07-24 00:27:33 +02:00
|
|
|
|
2006-08-18 02:46:38 +02:00
|
|
|
Simulation::get_instance().detach(*this);
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
|
|
|
TextSimulation::on_pause(const Tokens& arguments)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-07-12 00:50:41 +02:00
|
|
|
check_arguments_num(arguments, 0);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-15 19:35:24 +02:00
|
|
|
Simulation::get_instance().pause();
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-18 02:46:38 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_jumpto(const Tokens& arguments)
|
|
|
|
{
|
|
|
|
if (!check_arguments_num(arguments, 1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Listen for updates only during scheduling
|
|
|
|
|
|
|
|
ustring _position = arguments[0];
|
|
|
|
|
|
|
|
History::position p;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
int pos = string_to<int>(_position) + 1;
|
|
|
|
if (pos < 0)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided instant is out of range.\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
p = static_cast<unsigned int>(pos);
|
|
|
|
}
|
|
|
|
catch (domain_error e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided instant is not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
catch (out_of_range e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the instant is not within range.\n")); // does this make sense?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Simulation::get_instance().attach(*this);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Simulation::get_instance().jump_to(p);
|
|
|
|
}
|
|
|
|
catch (const UserInterruptException& e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: "));
|
|
|
|
p_stderr(e.what());
|
|
|
|
p_stderr(_("\nSimulation is now stopped\n"));
|
|
|
|
}
|
|
|
|
catch (const MalformedPolicyException& e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: "));
|
|
|
|
p_stderr(e.what());
|
|
|
|
p_stderr(_("\nSimulation is now stopped, and "
|
|
|
|
"the current policy will be deactivated\n"));
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Simulation::get_instance().set_policy(NULL);
|
|
|
|
}
|
|
|
|
catch(const CPUPolicyException& f)
|
|
|
|
{
|
|
|
|
// should never happen
|
|
|
|
p_stderr(_("FATAL ERROR: unable to deactivate the policy: "));
|
|
|
|
p_stderr(f.what());
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (const NullPolicyException& e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: "));
|
|
|
|
p_stderr(e.what());
|
|
|
|
p_stderr(_("\nSimulation is now stopped\n"));
|
|
|
|
}
|
2006-08-30 17:31:25 +02:00
|
|
|
catch (const CPUPolicyException& e)
|
|
|
|
{
|
|
|
|
p_stderr(_("UNKNOWN ERROR: "));
|
|
|
|
p_stderr(e.what());
|
|
|
|
p_stderr("\n");
|
|
|
|
}
|
2006-08-18 02:46:38 +02:00
|
|
|
|
|
|
|
Simulation::get_instance().detach(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
void
|
2006-08-09 16:38:45 +02:00
|
|
|
TextSimulation::on_stop(const Tokens& arguments)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-07-12 00:50:41 +02:00
|
|
|
check_arguments_num(arguments, 0);
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-07-15 19:35:24 +02:00
|
|
|
Simulation::get_instance().stop();
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
|
|
|
TextSimulation::on_configure_cpu_policy(const Tokens& arguments)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-07-12 00:50:41 +02:00
|
|
|
check_arguments_num(arguments, 0);
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-08-02 23:57:36 +02:00
|
|
|
CPUPolicy* policy = Simulation::get_instance().get_policy();
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (policy == NULL)
|
2006-07-16 23:43:54 +02:00
|
|
|
{
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: No policy actually selected for the simulation\n"));
|
2006-07-16 23:43:54 +02:00
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
PolicyParameters& parameters = policy->get_parameters();
|
2006-07-11 00:28:51 +02:00
|
|
|
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("Please provide a value for each attribute:\n"));
|
|
|
|
p_stdout(_("Mandatory arguments are marked with an asterisk (*)\n\n"));
|
2006-07-11 00:28:51 +02:00
|
|
|
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("Integer arguments:\n"));
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
typedef map<ustring, PolicyParameters::Parameter<int> > IntParams;
|
|
|
|
typedef map<ustring, PolicyParameters::Parameter<float> > FloatParams;
|
|
|
|
typedef map<ustring, PolicyParameters::Parameter<ustring> > StringParams;
|
|
|
|
|
|
|
|
IntParams int_params = parameters.get_registered_int_parameters();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (IntParams::iterator it = int_params.begin(); it != int_params.end();)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
|
|
|
PolicyParameters::Parameter<int> &p = it->second;
|
2006-07-13 01:52:09 +02:00
|
|
|
CommandParameter<int> cmd_p(p);
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
get_parameter(cmd_p);
|
2006-07-11 00:28:51 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
parameters.set_int(p.get_name(), cmd_p.value);
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
++it;
|
2006-07-11 00:28:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
p_stdout(_("\nFloating-point arguments:\n"));
|
|
|
|
|
|
|
|
// NOTE this piece code is a verbatim copy of the one above.
|
|
|
|
// I tried solving this issue by using templates, but to make
|
|
|
|
// it work will require adding to PolicyParameters a member template
|
|
|
|
// method with 2 specializations...
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-11 00:28:51 +02:00
|
|
|
FloatParams float_params = parameters.get_registered_float_parameters();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (FloatParams::iterator it = float_params.begin(); it != float_params.end();)
|
2006-07-11 00:28:51 +02:00
|
|
|
{
|
|
|
|
PolicyParameters::Parameter<float> &p = it->second;
|
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
CommandParameter<float> cmd_p(p);
|
2006-07-11 00:28:51 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
get_parameter(cmd_p);
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
parameters.set_float(p.get_name(), cmd_p.value);
|
|
|
|
|
|
|
|
++it;
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-07-11 00:28:51 +02:00
|
|
|
p_stdout(_("\nString arguments:\n"));
|
|
|
|
|
|
|
|
StringParams string_params = parameters.get_registered_string_parameters();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (StringParams::iterator it = string_params.begin(); it != string_params.end();)
|
2006-07-11 00:28:51 +02:00
|
|
|
{
|
|
|
|
PolicyParameters::Parameter<ustring> &p = it->second;
|
|
|
|
|
2006-07-13 01:52:09 +02:00
|
|
|
CommandParameter<ustring> cmd_p(p);
|
|
|
|
|
|
|
|
get_parameter(cmd_p);
|
|
|
|
|
|
|
|
parameters.set_string(p.get_name(), cmd_p.value);
|
|
|
|
|
|
|
|
++it;
|
2006-07-11 00:28:51 +02:00
|
|
|
}
|
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_help(const Tokens& arguments)
|
|
|
|
{
|
|
|
|
ustring command;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (arguments.size() > 0)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-07-12 00:50:41 +02:00
|
|
|
command = arguments[0].uppercase();
|
|
|
|
// print warning if necessary
|
|
|
|
check_arguments_num(arguments, 1);
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (command.size() == 0)
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("Avaiable commands:\nRUN\nSTOP\nPAUSE\n"
|
2006-08-09 16:38:45 +02:00
|
|
|
"CONFIGURE-CPU-POLICY\nHELP\nGET\nSET\nSHOW\nADD\n"
|
|
|
|
"REMOVE\nSAVE\nLOAD\nQUIT\n\n"
|
|
|
|
"HELP followed by a command name shows help about it.\n"
|
|
|
|
"ex. `HELP RUN` shows help about the command RUN\n"));
|
|
|
|
else if (command == "RUN")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("-- RUN COMMAND --\nStarts the simulation. It can be "
|
2006-08-09 16:38:45 +02:00
|
|
|
"continuous or step-by-step depending on the mode configured with "
|
|
|
|
"SET CONTINUOUS (default=true).\n\n"
|
|
|
|
"The output of RUN is a snapshot of the state of the simulation at each "
|
|
|
|
"instant.\n"
|
|
|
|
"The instant 0 represents the initial state, "
|
|
|
|
"during which no process is running. The scheduler "
|
|
|
|
"activity begins at instant 1.\n"));
|
|
|
|
else if (command == "STOP")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("-- STOP COMMAND --\nStops the simulation. The next call to RUN will "
|
2006-08-09 16:38:45 +02:00
|
|
|
"bring the simulation to the first instant and start it.\n"));
|
|
|
|
else if (command == "PAUSE")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will "
|
2006-08-09 16:38:45 +02:00
|
|
|
"continue it.\n"));
|
2006-08-18 02:46:38 +02:00
|
|
|
else if (command == "JUMPTO")
|
|
|
|
p_stdout(_("-- JUMPTO COMMAND --\nPauses the simulation and jumps to the specified instant.\n"));
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (command == "CONFIGURE-CPU-POLICY")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("-- CONFIGURE-CPU-POLICY COMMAND --\nConfigure parameters exposed by "
|
2006-08-09 16:38:45 +02:00
|
|
|
"the cpu policy.\n\nThis is currently the only way to control the behaviour of "
|
|
|
|
"cpu policies without modifying their source code.\n"));
|
|
|
|
else if (command == "HELP")
|
2006-08-02 00:57:40 +02:00
|
|
|
p_stdout(_("-- HELP COMMAND --\nThe help you're reading.\n"));
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (command == "GET")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("-- GET COMMAND --\nSyntax: GET <attr_name>\n"
|
2006-08-09 16:38:45 +02:00
|
|
|
"\twhere <attr_name> may be simulation-tick or continuous.\n"));
|
|
|
|
else if (command == "SET")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(_("-- SET COMMAND --\nSyntax: SET <attr_name> [=] <value>\n"
|
2006-08-09 16:38:45 +02:00
|
|
|
"\twhere <attr_name> may be simulation-tick, continuous or cpu-policy.\n"));
|
|
|
|
else if (command == "SHOW")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("-- SHOW COMMAND --\nDisplays the name of the entities (if available) "
|
2006-08-09 16:38:45 +02:00
|
|
|
"and other informations prefixed by its numeric identifier.\n\n"
|
|
|
|
"Syntax depends from entities being displayed:\n"
|
|
|
|
"`SHOW processes|resources|cpu-policies|resource-policies`\n"
|
|
|
|
"`SHOW threads <process_id>` with <process_id> being the numeric identifier of "
|
|
|
|
"the parent process\n"
|
|
|
|
"`SHOW requests <process_id> <thread_id>` with <thread_id> being the numeric "
|
|
|
|
"identifier of the thread child of process identified by <process_id>\n"
|
|
|
|
"`SHOW subrequests <process_id> <thread_id> <request_id>` where the numeric ids "
|
|
|
|
"follow the same logic of the previous commands\n"));
|
|
|
|
else if (command == "ADD")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("-- ADD COMMAND --\nAdds an entity by using a questionary-like approach.\n\n"
|
2006-08-09 16:38:45 +02:00
|
|
|
"Syntax depends from entity being added:\n"
|
|
|
|
"`ADD process|resource`\n"
|
|
|
|
"`ADD thread <process_id>` with <process_id> being the numeric identifier of "
|
|
|
|
"the parent process\n"
|
|
|
|
"`ADD request <process_id> <thread_id>` with <thread_id> being the numeric "
|
|
|
|
"identifier of the thread child of process identified by <process_id>\n"
|
|
|
|
"`ADD subrequest <process_id> <thread_id> <request_id>` where the numeric ids "
|
|
|
|
"follow the same logic of the previous commands\n"));
|
|
|
|
else if (command == "REMOVE")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("-- REMOVE COMMAND --\nRemoves an entity.\n\n"
|
2006-08-09 16:38:45 +02:00
|
|
|
"Syntax depends from entity being removed:\n"
|
|
|
|
"`REMOVE process|resource <id>` where <id> is the process or resource identifier\n"
|
|
|
|
"`REMOVE thread <process_id> <thread_id>` with <process_id> being the identifier of "
|
|
|
|
"the parent process, and <thread_id> the id of the thread to be removed\n"
|
|
|
|
"`REMOVE request <process_id> <thread_id> <request_id>` where the "
|
|
|
|
"numeric ids follow the same logic of the previous commands\n"
|
|
|
|
"`REMOVE subrequest <process_id> <thread_id> <request_id> <subrequest_id>` where the "
|
|
|
|
"numeric ids follow the same logic of the previous commands\n"));
|
|
|
|
else if (command == "SAVE")
|
2006-08-08 02:20:56 +02:00
|
|
|
p_stderr(_("-- SAVE COMMAND --\nSaves the simulation.\n\n"
|
2006-08-09 16:38:45 +02:00
|
|
|
"Syntax: SAVE <filename>\n"));
|
|
|
|
else if (command == "LOAD")
|
2006-08-08 02:20:56 +02:00
|
|
|
p_stderr(_("-- LOAD COMMAND --\nLoads the simulation.\n\n"
|
2006-08-09 16:38:45 +02:00
|
|
|
"Syntax: LOAD <filename>\n"));
|
|
|
|
else if (command == "QUIT")
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("-- QUIT COMMAND --\nGently closes the program.\n"));
|
2006-07-09 18:27:16 +02:00
|
|
|
else
|
2006-08-09 16:38:45 +02:00
|
|
|
p_stderr(_("ERROR: Sorry, no help available for this command.\n"));
|
|
|
|
}
|
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
void
|
2006-08-09 16:38:45 +02:00
|
|
|
TextSimulation::on_quit(const Tokens& arguments)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-07-12 00:50:41 +02:00
|
|
|
check_arguments_num(arguments, 0);
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!unsaved_ask_confirm())
|
2006-08-08 02:20:56 +02:00
|
|
|
return;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
p_stdout(_("\nBye.\n\n"));
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
// Exit the program with a correct return code.
|
|
|
|
exit(0);
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-09 18:27:16 +02:00
|
|
|
TextSimulation::on_get(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 1))
|
2006-07-11 17:46:46 +02:00
|
|
|
return;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
ustring attr = arguments[0].uppercase();
|
2006-07-11 17:46:46 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (attr == "SIMULATION-TICK")
|
2006-08-01 01:18:51 +02:00
|
|
|
{
|
|
|
|
ostringstream oss;
|
2006-08-27 16:36:23 +02:00
|
|
|
oss << "simulation-tick = " << GlobalPreferences::get_instance().get_speed() << "ms" << endl;
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stdout(oss.str());
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (attr == "CONTINUOUS")
|
2006-07-11 17:46:46 +02:00
|
|
|
{
|
|
|
|
ostringstream oss;
|
2006-08-01 01:18:51 +02:00
|
|
|
oss << "continuous = " << boolalpha << Simulation::get_instance().get_mode() << endl;
|
2006-07-11 17:46:46 +02:00
|
|
|
p_stdout(oss.str());
|
|
|
|
}
|
|
|
|
else
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: invalid attribute name. Accepted are: simulation-tick, continuous\n"));
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-09 18:27:16 +02:00
|
|
|
TextSimulation::on_set(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
// handle the optional "=' (I knew that I was buying myself a problem when I
|
2006-07-12 00:50:41 +02:00
|
|
|
// decided to support the assigment operator!)
|
2006-08-09 16:38:45 +02:00
|
|
|
if (arguments.size() >= 3)
|
2006-07-12 00:50:41 +02:00
|
|
|
check_arguments_num(arguments, 3);
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (!check_arguments_num(arguments, 2))
|
2006-07-11 17:46:46 +02:00
|
|
|
return;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
ustring attr = arguments[0].uppercase();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
ustring value;
|
2006-07-11 17:46:46 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (arguments[1] == "=")
|
2006-07-12 00:50:41 +02:00
|
|
|
value = arguments[2];
|
|
|
|
else
|
|
|
|
value = arguments[1];
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (attr == "SIMULATION-TICK")
|
2006-07-11 17:46:46 +02:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2006-07-21 15:10:31 +02:00
|
|
|
int timer = string_to<int>(value);
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (timer < 0)
|
|
|
|
throw domain_error("");
|
|
|
|
|
2006-08-27 16:36:23 +02:00
|
|
|
GlobalPreferences::get_instance().set_speed(timer);
|
2006-07-11 17:46:46 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-11 17:46:46 +02:00
|
|
|
{
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: you must provide a valid unsigned integer value\n"));
|
2006-07-11 17:46:46 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-11 17:46:46 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (attr == "CPU-POLICY")
|
2006-07-21 15:10:31 +02:00
|
|
|
{
|
|
|
|
int policy;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-21 15:10:31 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
policy = string_to<int>(value) - 1;
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (policy < 0)
|
|
|
|
throw domain_error("");
|
2006-07-21 15:10:31 +02:00
|
|
|
|
2006-08-02 23:57:36 +02:00
|
|
|
typedef vector<CPUPolicyManager*> ManagerVec;
|
|
|
|
typedef vector<CPUPolicy*>::iterator CPUPolicyIt;
|
2006-07-21 15:10:31 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
CPUPoliciesGatekeeper& gatekeeper = CPUPoliciesGatekeeper::get_instance();
|
2006-07-21 15:10:31 +02:00
|
|
|
|
|
|
|
ManagerVec managers = gatekeeper.get_registered();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (ManagerVec::iterator it = managers.begin(); it != managers.end(); ++it)
|
2006-07-21 15:10:31 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
vector<CPUPolicy*> policies = (*it)->get_avail_policies();
|
|
|
|
for (CPUPolicyIt it = policies.begin(); it != policies.end(); ++it)
|
|
|
|
{
|
2006-08-29 00:40:08 +02:00
|
|
|
if (policy == 0)
|
|
|
|
{
|
|
|
|
Simulation::get_instance().set_policy(*it);
|
|
|
|
// FIXME: dedicate a function to set resource policy
|
|
|
|
Simulation::get_instance().set_resource_policy(new ResourcePolicyLiFo()); // leak leak leak
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
--policy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (policy >= 0)
|
|
|
|
throw domain_error("");
|
2006-07-21 15:10:31 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-21 15:10:31 +02:00
|
|
|
{
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: invalid unsigned integer or not a valid policy index\n"));
|
|
|
|
}
|
2006-08-13 16:20:04 +02:00
|
|
|
catch (const CPUPolicyException& e)
|
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: "));
|
|
|
|
p_stderr(e.what());
|
|
|
|
p_stderr("\n");
|
|
|
|
}
|
|
|
|
|
2006-08-01 01:18:51 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
else if (attr == "CONTINUOUS")
|
2006-08-01 01:18:51 +02:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2006-08-27 16:36:23 +02:00
|
|
|
if(string_to<bool>(value) == true)
|
|
|
|
Simulation::get_instance().set_mode(Simulation::mode_continuous);
|
|
|
|
else
|
|
|
|
Simulation::get_instance().set_mode(Simulation::mode_step_by_step);
|
2006-08-01 01:18:51 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-08-01 01:18:51 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: you must provide a valid boolean value ('true' or 'false')\n"));
|
2006-07-21 15:10:31 +02:00
|
|
|
}
|
|
|
|
}
|
2006-07-11 17:46:46 +02:00
|
|
|
else
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: invalid attribute name. Accepted are: simulation-tick, cpu-policy, continuous\n"));
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-09 18:27:16 +02:00
|
|
|
TextSimulation::on_show(const Tokens& arguments)
|
2006-07-12 00:50:41 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (arguments.size() < 1)
|
2006-07-13 17:07:15 +02:00
|
|
|
{
|
|
|
|
//print error
|
|
|
|
check_arguments_num(arguments, 1);
|
2006-07-12 00:50:41 +02:00
|
|
|
return;
|
2006-07-13 17:07:15 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
//make a local copy which we'll probably modify
|
|
|
|
Tokens args = arguments;
|
|
|
|
|
|
|
|
ustring entities = args[0].uppercase();
|
|
|
|
args.erase(args.begin());
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
typedef void (TextSimulation::*f_ptr)(const Tokens&);
|
|
|
|
map<ustring, f_ptr> entities_handlers;
|
|
|
|
|
|
|
|
entities_handlers["PROCESSES"] = &TextSimulation::on_show_processes;
|
|
|
|
entities_handlers["RESOURCES"] = &TextSimulation::on_show_resources;
|
|
|
|
entities_handlers["THREADS"] = &TextSimulation::on_show_threads;
|
|
|
|
entities_handlers["REQUESTS"] = &TextSimulation::on_show_requests;
|
|
|
|
entities_handlers["SUBREQUESTS"] = &TextSimulation::on_show_subrequests;
|
|
|
|
entities_handlers["CPU-POLICIES"] = &TextSimulation::on_show_cpu_policies;
|
|
|
|
entities_handlers["RESOURCE-POLICIES"] = &TextSimulation::on_show_resource_policies;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (entities_handlers.find(entities) == entities_handlers.end())
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: invalid argument\n"));
|
2006-07-12 00:50:41 +02:00
|
|
|
else
|
2006-08-09 16:38:45 +02:00
|
|
|
(this->*(entities_handlers[entities]))(args);
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_show_processes(const Tokens& arguments)
|
|
|
|
{
|
|
|
|
check_arguments_num(arguments, 0);
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
2006-07-12 00:50:41 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
show(processes);
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_show_resources(const Tokens& arguments)
|
|
|
|
{
|
|
|
|
check_arguments_num(arguments, 0);
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Resources& resources = env.get_resources();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
show(resources);
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_show_threads(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 1))
|
2006-07-12 00:50:41 +02:00
|
|
|
return;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
ustring process = arguments[0];
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
try
|
|
|
|
{
|
2006-07-13 00:46:55 +02:00
|
|
|
int pid = string_to<int>(process) - 1;
|
2006-07-16 23:43:54 +02:00
|
|
|
threads = processes.at(pid)->get_threads();
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-12 00:50:41 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided process identifier is not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-12 00:50:41 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: this process identifier does not belong to an existing process\n"));
|
2006-07-13 23:09:27 +02:00
|
|
|
return;
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
show(threads);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
|
2006-07-12 00:50:41 +02:00
|
|
|
void
|
|
|
|
TextSimulation::on_show_requests(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 2))
|
2006-07-13 00:46:55 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
ustring thread = arguments[1];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
|
|
|
vector<Request*> requests;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 00:46:55 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int pid = string_to<int>(process) - 1;
|
|
|
|
int tid = string_to<int>(thread) - 1;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads = processes.at(pid)->get_threads();
|
|
|
|
requests = threads.at(tid)->get_requests();
|
2006-07-13 00:46:55 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
2006-07-13 23:09:27 +02:00
|
|
|
return;
|
2006-07-13 00:46:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
show(requests);
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_show_subrequests(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 3))
|
2006-07-13 00:46:55 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
ustring thread = arguments[1];
|
|
|
|
ustring request = arguments[2];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
|
|
|
vector<SubRequest*> subrequests;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 00:46:55 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int pid = string_to<int>(process) - 1;
|
|
|
|
int tid = string_to<int>(thread) - 1;
|
|
|
|
int rid = string_to<int>(request) - 1;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads = processes.at(pid)->get_threads();
|
|
|
|
vector<Request*> requests = threads.at(tid)->get_requests();
|
|
|
|
subrequests = requests.at(rid)->get_subrequests();
|
2006-07-13 00:46:55 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
2006-07-13 23:09:27 +02:00
|
|
|
return;
|
2006-07-13 00:46:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
show(subrequests);
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_show_cpu_policies(const Tokens& arguments)
|
|
|
|
{
|
2006-08-02 23:57:36 +02:00
|
|
|
typedef vector<CPUPolicyManager*> ManagerVec;
|
|
|
|
typedef vector<CPUPolicy*>::iterator CPUPolicyIt;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 00:46:55 +02:00
|
|
|
check_arguments_num(arguments, 0);
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
CPUPoliciesGatekeeper& gatekeeper = CPUPoliciesGatekeeper::get_instance();
|
|
|
|
|
2006-07-13 00:46:55 +02:00
|
|
|
ManagerVec managers = gatekeeper.get_registered();
|
|
|
|
|
|
|
|
unsigned int index = 1;
|
2006-08-09 16:38:45 +02:00
|
|
|
for (ManagerVec::iterator it = managers.begin(); it != managers.end(); ++it)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
2006-08-02 23:57:36 +02:00
|
|
|
vector<CPUPolicy*> policies = (*it)->get_avail_policies();
|
2006-08-09 16:38:45 +02:00
|
|
|
for (CPUPolicyIt it = policies.begin(); it != policies.end(); ++it)
|
2006-07-13 00:46:55 +02:00
|
|
|
{
|
|
|
|
ostringstream oss;
|
|
|
|
oss << index << ". " << (*it)->get_name() << endl;
|
|
|
|
oss << "\t" << (*it)->get_description() << endl;
|
|
|
|
|
|
|
|
p_stdout(oss.str());
|
2006-07-24 00:27:33 +02:00
|
|
|
++index;
|
2006-07-13 00:46:55 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
}
|
2006-07-12 00:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::on_show_resource_policies(const Tokens& arguments)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-07-13 00:46:55 +02:00
|
|
|
// Waiting for the coder to implementat resource policies
|
|
|
|
// But wait a moment, the coder is me!!!
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("FIXME: Not implemented\n"));
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-09 18:27:16 +02:00
|
|
|
TextSimulation::on_add(const Tokens& arguments)
|
2006-07-13 17:07:15 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (arguments.size() < 1)
|
2006-07-13 17:07:15 +02:00
|
|
|
{
|
|
|
|
//print error
|
|
|
|
check_arguments_num(arguments, 1);
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (Simulation::get_instance().get_state() != Simulation::state_stopped)
|
2006-07-24 00:27:33 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("WARNING: Simulation is not stopped, it will be automatically stopped\n"));
|
|
|
|
Simulation::get_instance().stop();
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 17:07:15 +02:00
|
|
|
//make a local copy which we'll probably modify
|
|
|
|
Tokens args = arguments;
|
|
|
|
|
|
|
|
ustring entity = args[0].uppercase();
|
|
|
|
args.erase(args.begin());
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 17:07:15 +02:00
|
|
|
typedef void (TextSimulation::*f_ptr)(const Tokens&);
|
|
|
|
map<ustring, f_ptr> entity_handlers;
|
|
|
|
|
|
|
|
entity_handlers["PROCESS"] = &TextSimulation::on_add_process;
|
|
|
|
entity_handlers["RESOURCE"] = &TextSimulation::on_add_resource;
|
|
|
|
entity_handlers["THREAD"] = &TextSimulation::on_add_thread;
|
|
|
|
entity_handlers["REQUEST"] = &TextSimulation::on_add_request;
|
|
|
|
entity_handlers["SUBREQUEST"] = &TextSimulation::on_add_subrequest;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (entity_handlers.find(entity) == entity_handlers.end())
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: invalid argument\n"));
|
2006-07-13 17:07:15 +02:00
|
|
|
else
|
2006-08-09 16:38:45 +02:00
|
|
|
(this->*(entity_handlers[entity]))(args);
|
2006-07-13 17:07:15 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-13 17:07:15 +02:00
|
|
|
TextSimulation::on_add_process(const Tokens& arguments)
|
|
|
|
{
|
|
|
|
check_arguments_num(arguments, 0);
|
|
|
|
|
|
|
|
CommandParameter<ustring> name(_("name"), "", "", false, "");
|
|
|
|
CommandParameter<int> arrival_time(_("arrival time"), 0, INT_MAX, false, 0);
|
|
|
|
CommandParameter<int> base_priority(_("priority"), 0, INT_MAX, false, 0);
|
|
|
|
|
|
|
|
get_parameter(name);
|
|
|
|
get_parameter(arrival_time);
|
|
|
|
get_parameter(base_priority);
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-13 17:07:15 +02:00
|
|
|
|
|
|
|
h.add_process(name.value, arrival_time.value, base_priority.value);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
void
|
2006-07-13 17:07:15 +02:00
|
|
|
TextSimulation::on_add_resource(const Tokens& arguments)
|
|
|
|
{
|
|
|
|
check_arguments_num(arguments, 0);
|
|
|
|
|
|
|
|
CommandParameter<ustring> name(_("name"), "", "", false, "");
|
|
|
|
CommandParameter<int> places(_("places"), 0, INT_MAX, false, 1);
|
|
|
|
|
|
|
|
get_parameter(name);
|
|
|
|
get_parameter(places);
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-13 17:07:15 +02:00
|
|
|
|
2006-08-25 00:10:31 +02:00
|
|
|
h.add_resource(name.value, false, places.value);
|
2006-07-13 17:07:15 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-13 17:07:15 +02:00
|
|
|
TextSimulation::on_add_thread(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 1))
|
2006-07-13 23:09:27 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
Process* p;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 23:09:27 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
p = processes.at(string_to<int>(process) - 1);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-13 23:09:27 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-13 23:09:27 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-07-13 17:07:15 +02:00
|
|
|
|
2006-07-13 23:09:27 +02:00
|
|
|
CommandParameter<ustring> name(_("name"), "", "", false, "");
|
2006-07-24 00:27:33 +02:00
|
|
|
CommandParameter<int> cpu_time(_("cpu time"), 1, INT_MAX, true, 0);
|
2006-07-13 23:09:27 +02:00
|
|
|
CommandParameter<int> arrival_time(_("arrival time"), 0, INT_MAX, false, 0);
|
|
|
|
CommandParameter<int> base_priority(_("base priority"), 0, INT_MAX, false, 0);
|
|
|
|
|
|
|
|
get_parameter(name);
|
|
|
|
get_parameter(cpu_time);
|
|
|
|
get_parameter(arrival_time);
|
|
|
|
get_parameter(base_priority);
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-13 23:09:27 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
h.add_thread(name.value, *p, cpu_time.value, arrival_time.value,
|
2006-07-13 23:09:27 +02:00
|
|
|
base_priority.value);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
void
|
2006-07-13 17:07:15 +02:00
|
|
|
TextSimulation::on_add_request(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 2))
|
2006-07-13 23:09:27 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
ustring thread = arguments[1];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
|
|
|
|
|
|
|
Thread* t;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-13 23:09:27 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int pid = string_to<int>(process) - 1;
|
|
|
|
int tid = string_to<int>(thread) - 1;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads = processes.at(pid)->get_threads();
|
2006-07-13 23:09:27 +02:00
|
|
|
t = threads.at(tid);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-13 23:09:27 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-13 23:09:27 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CommandParameter<int> instant(_("instant"), 0, INT_MAX, true, 0);
|
|
|
|
|
|
|
|
get_parameter(instant);
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-13 23:09:27 +02:00
|
|
|
|
|
|
|
h.add_request(*t, instant.value);
|
2006-07-13 17:07:15 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-13 17:07:15 +02:00
|
|
|
TextSimulation::on_add_subrequest(const Tokens& arguments)
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 3))
|
2006-07-13 23:09:27 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
ustring thread = arguments[1];
|
|
|
|
ustring request = arguments[2];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
Request* r;
|
|
|
|
|
2006-07-13 23:09:27 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int pid = string_to<int>(process) - 1;
|
|
|
|
int tid = string_to<int>(thread) - 1;
|
|
|
|
int rid = string_to<int>(request) - 1;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads = processes.at(pid)->get_threads();
|
|
|
|
vector<Request*> requests = threads.at(tid)->get_requests();
|
2006-07-13 23:09:27 +02:00
|
|
|
r = requests.at(rid);
|
2006-08-01 01:18:51 +02:00
|
|
|
|
2006-07-13 23:09:27 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-13 23:09:27 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-13 23:09:27 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CommandParameter<int> resource_key(_("resource key"), 0, INT_MAX, true, 0);
|
|
|
|
CommandParameter<int> duration(_("duration"), 0, INT_MAX, true, 0);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-01 01:18:51 +02:00
|
|
|
const Environment::Resources& resources = env.get_resources();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-01 01:18:51 +02:00
|
|
|
do
|
|
|
|
{
|
|
|
|
get_parameter(resource_key);
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (resources.find(resource_key.value) == resources.end())
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: invalid resource identifier\n"));
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
while (resources.find(resource_key.value) == resources.end());
|
2006-08-01 01:18:51 +02:00
|
|
|
|
2006-07-29 02:24:48 +02:00
|
|
|
get_parameter(duration);
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-13 23:09:27 +02:00
|
|
|
|
2006-07-18 17:52:55 +02:00
|
|
|
h.add_subrequest(*r, resource_key.value, duration.value);
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-09 18:27:16 +02:00
|
|
|
TextSimulation::on_remove(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (arguments.size() < 1)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
//print error
|
|
|
|
check_arguments_num(arguments, 1);
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (Simulation::get_instance().get_state() != Simulation::state_stopped)
|
2006-07-16 23:43:54 +02:00
|
|
|
p_stderr(_("WARNING: Simulation is not stopped, it will be automatically stopped"));
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-15 17:46:13 +02:00
|
|
|
//make a local copy which we'll probably modify
|
|
|
|
Tokens args = arguments;
|
|
|
|
|
|
|
|
ustring entity = args[0].uppercase();
|
|
|
|
args.erase(args.begin());
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-15 17:46:13 +02:00
|
|
|
typedef void (TextSimulation::*f_ptr)(const Tokens&);
|
|
|
|
map<ustring, f_ptr> entity_handlers;
|
|
|
|
|
|
|
|
entity_handlers["PROCESS"] = &TextSimulation::on_remove_process;
|
|
|
|
entity_handlers["RESOURCE"] = &TextSimulation::on_remove_resource;
|
|
|
|
entity_handlers["THREAD"] = &TextSimulation::on_remove_thread;
|
|
|
|
entity_handlers["REQUEST"] = &TextSimulation::on_remove_request;
|
|
|
|
entity_handlers["SUBREQUEST"] = &TextSimulation::on_remove_subrequest;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
if (entity_handlers.find(entity) == entity_handlers.end())
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: invalid argument\n"));
|
2006-07-15 17:46:13 +02:00
|
|
|
else
|
2006-08-09 16:38:45 +02:00
|
|
|
(this->*(entity_handlers[entity]))(args);
|
2006-07-15 17:46:13 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-15 17:46:13 +02:00
|
|
|
TextSimulation::on_remove_process(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 1))
|
2006-07-15 17:46:13 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
Process* p;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-15 17:46:13 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
p = processes.at(string_to<int>(process) - 1);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-15 17:46:13 +02:00
|
|
|
h.remove(*p);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
void
|
2006-07-15 17:46:13 +02:00
|
|
|
TextSimulation::on_remove_resource(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 1))
|
2006-07-15 17:46:13 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring resource = arguments[0];
|
|
|
|
|
2006-08-01 01:18:51 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-24 00:27:33 +02:00
|
|
|
History::resource_key_t rid;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-15 17:46:13 +02:00
|
|
|
try
|
|
|
|
{
|
2006-07-16 23:43:54 +02:00
|
|
|
rid = string_to<int>(resource);
|
2006-08-01 01:18:51 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
const Environment::Resources& resources =
|
2006-08-01 01:18:51 +02:00
|
|
|
h.get_environment_at(0).get_resources();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (resources.find(rid) == resources.end())
|
2006-08-01 01:18:51 +02:00
|
|
|
throw out_of_range(_("invalid resource id"));
|
2006-07-15 17:46:13 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
h.remove(rid);
|
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-15 17:46:13 +02:00
|
|
|
TextSimulation::on_remove_thread(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 2))
|
2006-07-15 17:46:13 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
ustring thread = arguments[1];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
|
|
|
|
|
|
|
Thread* t;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-15 17:46:13 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int pid = string_to<int>(process) - 1;
|
|
|
|
int tid = string_to<int>(thread) - 1;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads = processes.at(pid)->get_threads();
|
2006-07-15 17:46:13 +02:00
|
|
|
t = threads.at(tid);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-15 17:46:13 +02:00
|
|
|
h.remove(*t);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
void
|
2006-07-15 17:46:13 +02:00
|
|
|
TextSimulation::on_remove_request(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 3))
|
2006-07-15 17:46:13 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
ustring thread = arguments[1];
|
|
|
|
ustring request = arguments[2];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
Request* r;
|
|
|
|
|
2006-07-15 17:46:13 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int pid = string_to<int>(process) - 1;
|
|
|
|
int tid = string_to<int>(thread) - 1;
|
|
|
|
int rid = string_to<int>(request) - 1;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads = processes.at(pid)->get_threads();
|
|
|
|
vector<Request*> requests = threads.at(tid)->get_requests();
|
2006-07-15 17:46:13 +02:00
|
|
|
r = requests.at(rid);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-15 17:46:13 +02:00
|
|
|
h.remove(*r);
|
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-15 17:46:13 +02:00
|
|
|
TextSimulation::on_remove_subrequest(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 4))
|
2006-07-15 17:46:13 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring process = arguments[0];
|
|
|
|
ustring thread = arguments[1];
|
|
|
|
ustring request = arguments[2];
|
|
|
|
ustring subrequest = arguments[3];
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
const Environment& env = Simulation::get_instance().get_history().get_environment_at(0);
|
|
|
|
const Environment::Processes& processes = env.get_processes();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
SubRequest* r;
|
|
|
|
|
2006-07-15 17:46:13 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int pid = string_to<int>(process) - 1;
|
|
|
|
int tid = string_to<int>(thread) - 1;
|
|
|
|
int rid = string_to<int>(request) - 1;
|
|
|
|
int srid = string_to<int>(subrequest) - 1;
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
vector<Thread*> threads = processes.at(pid)->get_threads();
|
|
|
|
vector<Request*> requests = threads.at(tid)->get_requests();
|
|
|
|
vector<SubRequest*> subrequests = requests.at(rid)->get_subrequests();
|
2006-07-15 17:46:13 +02:00
|
|
|
r = subrequests.at(srid);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (domain_error e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: provided identifier(s) not a valid integer\n"));
|
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-07-15 17:46:13 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: the identifier(s) do not belong to an existing entity\n"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-07-16 23:43:54 +02:00
|
|
|
History& h = Simulation::get_instance().get_history();
|
2006-07-15 17:46:13 +02:00
|
|
|
h.remove(*r);
|
2006-07-09 18:27:16 +02:00
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-08-07 02:54:43 +02:00
|
|
|
TextSimulation::on_save(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 1))
|
2006-08-07 02:54:43 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring filename = arguments[0];
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
vector<Serializer*> serializers =
|
2006-08-07 02:54:43 +02:00
|
|
|
SerializersGatekeeper::get_instance().get_registered();
|
|
|
|
|
2006-08-08 02:20:56 +02:00
|
|
|
// FIXME using the first serializer available, this
|
|
|
|
// will need to be changed when multiple serializers will
|
|
|
|
// be made available
|
2006-08-07 02:54:43 +02:00
|
|
|
Serializer& serializer = *serializers.at(0);
|
|
|
|
|
|
|
|
const History& history = Simulation::get_instance().get_history();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-07 02:54:43 +02:00
|
|
|
serializer.save_snapshot(filename, history);
|
2006-08-08 02:20:56 +02:00
|
|
|
|
|
|
|
_saved = true;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-08-08 02:20:56 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: No registered serializer available\n"));
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (SerializerError e)
|
2006-08-08 02:20:56 +02:00
|
|
|
{
|
|
|
|
string msg = _("ERROR: ");
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-08 02:20:56 +02:00
|
|
|
p_stderr(msg + e.what() + "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-08-08 02:20:56 +02:00
|
|
|
TextSimulation::on_load(const Tokens& arguments)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!check_arguments_num(arguments, 1))
|
2006-08-08 02:20:56 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
ustring filename = arguments[0];
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (!unsaved_ask_confirm())
|
2006-08-08 02:20:56 +02:00
|
|
|
return;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-08 02:20:56 +02:00
|
|
|
try
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
vector<Serializer*> serializers =
|
2006-08-08 02:20:56 +02:00
|
|
|
SerializersGatekeeper::get_instance().get_registered();
|
|
|
|
|
|
|
|
// FIXME using the first serializer available, this
|
|
|
|
// will need to be changed when multiple serializers will
|
|
|
|
// be made available
|
|
|
|
Serializer& serializer = *serializers.at(0);
|
|
|
|
|
|
|
|
History& history = Simulation::get_instance().get_history();
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-08 02:20:56 +02:00
|
|
|
serializer.restore_snapshot(filename, history);
|
2006-08-07 02:54:43 +02:00
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (out_of_range e)
|
2006-08-07 02:54:43 +02:00
|
|
|
{
|
|
|
|
p_stderr(_("ERROR: No registered serializer available\n"));
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
catch (SerializerError e)
|
2006-08-07 02:54:43 +02:00
|
|
|
{
|
|
|
|
string msg = _("ERROR: ");
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-07 02:54:43 +02:00
|
|
|
p_stderr(msg + e.what() + "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
void
|
|
|
|
TextSimulation::p_stdout(const ustring& str)
|
|
|
|
{
|
|
|
|
cout << str;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TextSimulation::p_stderr(const ustring& str)
|
|
|
|
{
|
|
|
|
cerr << str;
|
|
|
|
}
|
|
|
|
|
|
|
|
ustring
|
|
|
|
TextSimulation::readline()
|
|
|
|
{
|
2006-08-03 01:38:52 +02:00
|
|
|
// TODO throw an exception when the stream returned by
|
|
|
|
// getline() has the fail, bad or eof bit set, because
|
|
|
|
// in this case the application should quit
|
2006-07-09 18:27:16 +02:00
|
|
|
string str;
|
|
|
|
getline(cin, str);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2006-06-29 10:44:30 +02:00
|
|
|
void
|
2006-07-11 00:28:51 +02:00
|
|
|
TextSimulation::parse_command(TextSimulation& sim, const ustring& str)
|
2006-02-17 23:19:25 +01:00
|
|
|
{
|
2006-07-09 18:27:16 +02:00
|
|
|
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;
|
2006-08-18 02:46:38 +02:00
|
|
|
command_handlers["JUMPTO"] = &TextSimulation::on_jumpto;
|
2006-07-09 18:27:16 +02:00
|
|
|
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;
|
2006-08-07 02:54:43 +02:00
|
|
|
command_handlers["SAVE"] = &TextSimulation::on_save;
|
2006-08-08 02:20:56 +02:00
|
|
|
command_handlers["LOAD"] = &TextSimulation::on_load;
|
2006-07-09 18:27:16 +02:00
|
|
|
command_handlers["QUIT"] = &TextSimulation::on_quit;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
Tokens arguments = tokenize(str);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-18 01:30:49 +02:00
|
|
|
// Ignore empty lines
|
2006-08-09 16:38:45 +02:00
|
|
|
if (arguments.size() == 0)
|
2006-07-09 18:27:16 +02:00
|
|
|
return;
|
2006-08-18 01:30:49 +02:00
|
|
|
|
|
|
|
// Allow also comments into batch scripts (w/ echo):
|
|
|
|
if(arguments[0].at(0) == '#')
|
|
|
|
{
|
|
|
|
cout << str;
|
|
|
|
return;
|
|
|
|
}
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-07-11 00:28:51 +02:00
|
|
|
ustring key = arguments[0].uppercase();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
if (command_handlers.find(key) == command_handlers.end())
|
2006-07-09 18:27:16 +02:00
|
|
|
{
|
2006-08-01 01:18:51 +02:00
|
|
|
p_stderr(_("ERROR: command not supported\n"));
|
2006-07-09 18:27:16 +02:00
|
|
|
return;
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-09 18:27:16 +02:00
|
|
|
arguments.erase(arguments.begin());
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
(sim.*(command_handlers[key]))(arguments);
|
|
|
|
|
|
|
|
if (key == "ADD" || key == "REMOVE")
|
2006-08-08 02:20:56 +02:00
|
|
|
sim._saved = false;
|
2006-08-09 16:38:45 +02:00
|
|
|
}
|
2006-07-09 18:27:16 +02:00
|
|
|
|
2006-07-29 17:48:24 +02:00
|
|
|
static ostream&
|
|
|
|
operator<<(ostream& os, Schedulable::state state)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
switch (state)
|
2006-07-29 17:48:24 +02:00
|
|
|
{
|
|
|
|
case Schedulable::state_running:
|
2006-08-29 00:40:08 +02:00
|
|
|
os << _(">> RUNNING <<");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Schedulable::state_ready:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("READY");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Schedulable::state_blocked:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("BLOCKED");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Schedulable::state_future:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("FUTURE");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Schedulable::state_terminated:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("TERMINATED");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
os.setstate(ios_base::failbit);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-29 17:48:24 +02:00
|
|
|
return os;
|
|
|
|
}
|
2006-06-29 10:44:30 +02:00
|
|
|
|
2006-07-29 17:48:24 +02:00
|
|
|
static ostream&
|
|
|
|
operator<<(ostream& os, Request::state state)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
switch (state)
|
2006-07-29 17:48:24 +02:00
|
|
|
{
|
|
|
|
case Request::state_unallocable:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("UNALLOCABLE");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Request::state_allocated:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("ALLOCATED");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Request::state_future:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("FUTURE");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Request::state_exhausted:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("EXHAUSTED");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
case Request::state_allocable:
|
2006-08-12 15:33:28 +02:00
|
|
|
os << _("ALLOCABLE");
|
2006-07-29 17:48:24 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
os.setstate(ios_base::failbit);
|
|
|
|
}
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-07-29 17:48:24 +02:00
|
|
|
return os;
|
|
|
|
}
|
2006-06-29 10:44:30 +02:00
|
|
|
|
|
|
|
void
|
2006-08-18 02:46:38 +02:00
|
|
|
TextSimulation::update(const Simulation& changed_simulation)
|
2006-02-17 23:19:25 +01:00
|
|
|
{
|
2006-07-29 02:24:48 +02:00
|
|
|
ostringstream oss;
|
2006-08-03 03:34:49 +02:00
|
|
|
int printed_instant;
|
2006-08-12 15:33:28 +02:00
|
|
|
static const std::string tab = " ";
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
// Print header for each instant:
|
2006-08-18 02:46:38 +02:00
|
|
|
if (changed_simulation.get_front() > 1)
|
|
|
|
printed_instant = static_cast<int>(changed_simulation.get_front()) - 1;
|
2006-08-03 03:34:49 +02:00
|
|
|
else
|
2006-08-18 02:46:38 +02:00
|
|
|
printed_instant = 0;
|
2006-08-03 03:34:49 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << endl << ">>>> " << printed_instant;
|
2006-08-03 01:12:32 +02:00
|
|
|
|
2006-07-29 02:24:48 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
// Print ready queue
|
|
|
|
oss << endl << _("READY QUEUE: { ");
|
2006-07-24 00:27:33 +02:00
|
|
|
|
2006-08-18 02:46:38 +02:00
|
|
|
const Environment& env = changed_simulation.get_history().get_environment_at(changed_simulation.get_front());
|
2006-07-24 00:27:33 +02:00
|
|
|
const ReadyQueue& q = env.get_sorted_queue();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (unsigned int i = 0; i < q.size(); ++i)
|
2006-07-24 00:27:33 +02:00
|
|
|
{
|
|
|
|
const Thread& t = q.get_item_at(i);
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << t.get_name() + _(" ~ ");
|
2006-07-24 00:27:33 +02:00
|
|
|
}
|
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << _("}") << endl;
|
2006-07-29 02:24:48 +02:00
|
|
|
|
2006-08-12 01:01:25 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
// Flush buffer to screen
|
|
|
|
p_stdout(oss.str());
|
|
|
|
oss.str(string());
|
|
|
|
|
2006-07-29 02:24:48 +02:00
|
|
|
|
|
|
|
const Environment::Resources& resources = env.get_resources();
|
2006-08-12 01:01:25 +02:00
|
|
|
const Environment::Processes& processes = env.get_processes();
|
2006-07-29 02:24:48 +02:00
|
|
|
typedef Environment::Resources::const_iterator ResourceIt;
|
|
|
|
|
2006-08-12 01:01:25 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
// Write the queue of requests for each resource
|
|
|
|
oss << _("RESOURCES:") << endl;
|
2006-08-09 16:38:45 +02:00
|
|
|
for (ResourceIt it = resources.begin(); it != resources.end(); ++it)
|
2006-07-29 02:24:48 +02:00
|
|
|
{
|
|
|
|
const Resource& r = *it->second;
|
|
|
|
Environment::resource_key_t key = it->first;
|
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << right << setw(3) << key << left << ". " << r.get_name() << _(", with ");
|
|
|
|
oss << r.get_places() << _(" places") << endl;
|
2006-08-05 19:09:45 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
const Environment::SubRequestQueue& req_queue =
|
2006-08-05 19:09:45 +02:00
|
|
|
env.get_request_queue(it->first);
|
2006-08-09 16:38:45 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << setw(tab.size()*3) << ' ' << _("queue: { ");
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
for (unsigned int i = 0; i < req_queue.size(); ++i)
|
2006-08-05 19:09:45 +02:00
|
|
|
{
|
|
|
|
if (i == r.get_places())
|
|
|
|
oss << " || ";
|
|
|
|
else
|
|
|
|
if (i != 0)
|
|
|
|
oss << " ~ ";
|
|
|
|
|
|
|
|
if (req_queue[i]->get_state() == Request::state_allocated)
|
|
|
|
oss << "[" << req_queue[i]->get_request().get_thread().get_name() << "]";
|
|
|
|
else
|
|
|
|
oss << req_queue[i]->get_request().get_thread().get_name();
|
|
|
|
}
|
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << _(" }") << endl;
|
2006-07-29 02:24:48 +02:00
|
|
|
}
|
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
// Flush buffer to screen
|
|
|
|
p_stdout(oss.str());
|
|
|
|
oss.str(string());
|
2006-08-12 01:01:25 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
|
2006-08-15 20:29:06 +02:00
|
|
|
// Set new format fillers
|
2006-08-12 15:33:28 +02:00
|
|
|
static const unsigned int fill0 = 25;
|
|
|
|
static const unsigned int fill1 = 15;
|
|
|
|
|
|
|
|
// Minimum fill0 for the usage we make of it below:
|
|
|
|
assert(fill0 > tab.size()*2 + 6);
|
|
|
|
|
|
|
|
oss << endl;
|
|
|
|
|
|
|
|
oss << left;
|
|
|
|
oss << setw(fill0) << _("PROCESSES:");
|
|
|
|
oss << right;
|
|
|
|
oss << setw(fill1) << _("state")
|
|
|
|
<< setw(fill1) << _("arrival")
|
|
|
|
<< setw(fill1) << _("requiring")
|
|
|
|
<< setw(fill1) << _("elapsed")
|
|
|
|
<< setw(fill1) << _("priority")
|
|
|
|
<< setw(fill1) << _("resource_id")
|
|
|
|
<< endl;
|
2006-07-29 02:24:48 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (unsigned int pi = 0; pi < processes.size(); ++pi)
|
2006-07-29 02:24:48 +02:00
|
|
|
{
|
|
|
|
Process& p = *processes[pi];
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << setw(2) << right << (pi + 1) << left << ". "
|
|
|
|
<< setw(fill0 - 4) << p.get_name().substr(0, fill0 - 5);
|
|
|
|
oss << right;
|
|
|
|
oss << setw(fill1) << p.get_state();
|
|
|
|
oss << setw(fill1) << p.get_arrival_time();
|
|
|
|
oss << setw(fill1) << p.get_total_cpu_time();
|
|
|
|
oss << setw(fill1) << p.get_elapsed_time();
|
|
|
|
oss << setw(fill1) << p.get_current_priority();
|
|
|
|
oss << endl;
|
2006-07-29 02:24:48 +02:00
|
|
|
|
|
|
|
p_stdout(oss.str());
|
|
|
|
oss.str(string());
|
2006-07-29 17:48:24 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
vector<Thread*> threads = p.get_threads();
|
2006-07-29 17:48:24 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (unsigned int ti = 0; ti < threads.size(); ++ti)
|
2006-07-29 17:48:24 +02:00
|
|
|
{
|
|
|
|
Thread& t = *threads[ti];
|
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << right << setw(tab.size() + 2) << ti + 1 << left << ". "
|
|
|
|
<< setw(fill0 - 4 - tab.size()) << t.get_name().substr(0, fill0 - 5 - tab.size());
|
|
|
|
oss << right;
|
|
|
|
oss << setw(fill1) << t.get_state();
|
|
|
|
oss << setw(fill1) << t.get_arrival_time();
|
|
|
|
oss << setw(fill1) << t.get_total_cpu_time();
|
|
|
|
oss << setw(fill1) << t.get_elapsed_time();
|
|
|
|
oss << setw(fill1) << t.get_current_priority();
|
|
|
|
oss << endl;
|
2006-07-29 17:48:24 +02:00
|
|
|
|
|
|
|
p_stdout(oss.str());
|
|
|
|
oss.str(string());
|
|
|
|
|
|
|
|
vector<Request*> requests = t.get_requests();
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
for (unsigned int ri = 0; ri < requests.size(); ++ri)
|
2006-07-29 17:48:24 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
Request& r = *requests[ri];
|
|
|
|
|
|
|
|
vector<SubRequest*> subrequests = r.get_subrequests();
|
|
|
|
|
|
|
|
for (unsigned int sri = 0; sri < subrequests.size(); ++sri)
|
|
|
|
{
|
|
|
|
SubRequest& sr = *subrequests[sri];
|
|
|
|
ResourceIt point = resources.find(sr.get_resource_key());
|
2006-08-12 01:01:25 +02:00
|
|
|
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << setw(2 + tab.size()*2) << ri + 1 << left << "." << setw(2) << sri + 1
|
|
|
|
<< setw(fill0 - 5 - tab.size()*2) << (point->second)->get_name().substr(0, fill0 - 6 - tab.size()*2);
|
|
|
|
oss << right;
|
|
|
|
oss << setw(fill1) << sr.get_state();
|
|
|
|
oss << setw(fill1) << r.get_instant();
|
|
|
|
oss << setw(fill1) << sr.get_length();
|
|
|
|
oss << setw(fill1) << sr.get_length() - sr.get_remaining_time();
|
2006-08-18 01:30:49 +02:00
|
|
|
oss << setw(fill1*2) << sr.get_resource_key();
|
2006-08-12 15:33:28 +02:00
|
|
|
oss << endl;
|
2006-08-09 16:38:45 +02:00
|
|
|
|
|
|
|
p_stdout(oss.str());
|
|
|
|
oss.str(string());
|
|
|
|
}
|
2006-07-29 17:48:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2006-07-29 02:24:48 +02:00
|
|
|
}
|
2006-02-17 23:19:25 +01:00
|
|
|
}
|
|
|
|
|