- Make Scheduler::step_forward return a bool representing if
the step went okay or otherwise if the simulation ended - Fix simulation states in concrete_simulation.cc - Manage end of input (now CTRL+D exits the program, and you can redirect a file in input knowing that at EOF sgpemv2 will terminate) - Fix a bug in Scheduler that didn't add the newly created environment to History when the simulation ended, thus leading both to a memory leak and an inconsistency in representing the simulation git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@807 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
6f8625d308
commit
c6ebe792e4
|
@ -82,53 +82,31 @@ ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException)
|
||||||
case state_stopped:
|
case state_stopped:
|
||||||
_history.reset(true);
|
_history.reset(true);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
_state = state_running;
|
_state = state_running;
|
||||||
|
|
||||||
|
|
||||||
// chech for termination
|
|
||||||
const Environment &env = _history.get_last_environment();
|
|
||||||
const Environment::Processes& processes = env.get_processes();
|
|
||||||
typedef Environment::Processes::const_iterator ProcessesIt;
|
|
||||||
|
|
||||||
//******* CONTINUOUS TIME
|
|
||||||
|
|
||||||
if (_mode)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
|
|
||||||
bool all_term = true;
|
|
||||||
for(ProcessesIt it = processes.begin(); it != processes.end(); ++it)
|
|
||||||
if((*it)->get_state() != Schedulable::state_terminated)
|
|
||||||
{
|
|
||||||
all_term = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if there are no processes left the termination message has already been notified
|
|
||||||
//by the last execution of upadate()
|
|
||||||
if (all_term)
|
|
||||||
{
|
|
||||||
_state = state_stopped;
|
|
||||||
return; // Exit from loop
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(get_policy() == NULL)
|
if(get_policy() == NULL)
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
throw NullPolicyException("no policy selected");
|
throw NullPolicyException("no policy selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//******* CONTINUOUS TIME
|
||||||
|
if (_mode)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
//step forward
|
//step forward
|
||||||
Scheduler::get_instance().step_forward(_history, *get_policy());
|
bool yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy());
|
||||||
|
if(!yet_to_finish) stop();
|
||||||
|
|
||||||
//sleep
|
//sleep
|
||||||
Glib::usleep(_timer_interval*1000);
|
Glib::usleep(_timer_interval*1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(UserInterruptException e)
|
catch(UserInterruptException e)
|
||||||
{
|
{
|
||||||
|
@ -139,41 +117,29 @@ ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException)
|
||||||
//check the state
|
//check the state
|
||||||
if (_state == state_stopped || _state == state_paused)
|
if (_state == state_stopped || _state == state_paused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
while(true);
|
while(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//******* STEP by STEP
|
//******* STEP by STEP
|
||||||
else
|
else
|
||||||
{
|
|
||||||
bool all_term = true;
|
|
||||||
for(ProcessesIt it = processes.begin(); it != processes.end(); ++it)
|
|
||||||
if((*it)->get_state() != Schedulable::state_terminated)
|
|
||||||
{
|
|
||||||
all_term = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all_term)
|
|
||||||
//if there are no processes left the termination message has already been notified
|
|
||||||
//by the last execution of upadate()
|
|
||||||
_state = state_paused;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
assert(get_policy() != NULL);
|
assert(get_policy() != NULL);
|
||||||
//step forward
|
//step forward
|
||||||
Scheduler::get_instance().step_forward(_history, *get_policy());
|
bool yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy());
|
||||||
|
if(yet_to_finish)
|
||||||
|
pause();
|
||||||
|
else
|
||||||
|
stop();
|
||||||
}
|
}
|
||||||
catch(UserInterruptException e)
|
catch(UserInterruptException e)
|
||||||
{
|
{
|
||||||
|
stop();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Simulation::state
|
Simulation::state
|
||||||
|
|
|
@ -161,7 +161,7 @@ Scheduler::get_policy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
bool
|
||||||
Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterruptException)
|
Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterruptException)
|
||||||
{
|
{
|
||||||
// This very method should be exclusive: no concurrent behaviour, from when we
|
// This very method should be exclusive: no concurrent behaviour, from when we
|
||||||
|
@ -233,7 +233,9 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
|
||||||
|
|
||||||
|
|
||||||
// ---------- FIXME ----------------
|
// ---------- FIXME ----------------
|
||||||
// What to do now if the simulation ended?
|
// Check correctness: Now if the simulation ended we
|
||||||
|
// append the newly created environment and return false
|
||||||
|
if(simulation_ended) goto final_cleanup;
|
||||||
|
|
||||||
|
|
||||||
/* /
|
/* /
|
||||||
|
@ -330,6 +332,8 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final_cleanup:
|
||||||
|
|
||||||
// append the new snapshot...
|
// append the new snapshot...
|
||||||
// ...and remember to release the auto_ptr!
|
// ...and remember to release the auto_ptr!
|
||||||
concrete_history.append_new_environment(new_snapshot.release());
|
concrete_history.append_new_environment(new_snapshot.release());
|
||||||
|
@ -337,6 +341,9 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
|
||||||
// Reset values that the policy doesn't need anymore
|
// Reset values that the policy doesn't need anymore
|
||||||
_policy = NULL;
|
_policy = NULL;
|
||||||
_ready_queue = NULL;
|
_ready_queue = NULL;
|
||||||
|
|
||||||
|
// If we got there, a step has been performed
|
||||||
|
return simulation_ended == false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,10 @@ namespace sgpem
|
||||||
Generates a new ReadyQueue representing the status of the processes
|
Generates a new ReadyQueue representing the status of the processes
|
||||||
at the simulation instant next to the current one, and extends the History by
|
at the simulation instant next to the current one, and extends the History by
|
||||||
one instant with it.
|
one instant with it.
|
||||||
|
|
||||||
|
\return false If the simulation has ended, true otherwise
|
||||||
*/
|
*/
|
||||||
void step_forward(History& history, Policy& cpu_policy) throw(UserInterruptException);
|
bool step_forward(History& history, Policy& cpu_policy) throw(UserInterruptException);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the policy that will be used to generate the simulation at the next instant.
|
Returns the policy that will be used to generate the simulation at the next instant.
|
||||||
|
|
|
@ -131,15 +131,12 @@ parse_options(int argc, char** argv)
|
||||||
// initialize the command line version
|
// initialize the command line version
|
||||||
// of sgpemv2
|
// of sgpemv2
|
||||||
TextSimulation sim;
|
TextSimulation sim;
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
std::string str;
|
std::string str;
|
||||||
getline(std::cin, str);
|
|
||||||
|
|
||||||
|
while(getline(std::cin, str))
|
||||||
|
// Enter main loop
|
||||||
TextSimulation::parse_command(sim, str);
|
TextSimulation::parse_command(sim, str);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GuiBuilder* gui = new GuiBuilder();
|
GuiBuilder* gui = new GuiBuilder();
|
||||||
|
|
|
@ -494,8 +494,7 @@ TextSimulation::on_help(const Tokens& arguments)
|
||||||
"the cpu policy.\n\nThis is currently the only way to control the behaviour of "
|
"the cpu policy.\n\nThis is currently the only way to control the behaviour of "
|
||||||
"cpu policies without modifying their source code.\n"));
|
"cpu policies without modifying their source code.\n"));
|
||||||
else if(command == "HELP")
|
else if(command == "HELP")
|
||||||
p_stdout(_("-- Do you really want me to explain what HELP means? --\n"
|
p_stdout(_("-- HELP COMMAND --\nThe help you're reading"));
|
||||||
" ************** YOU ARE JOKING ME !!! ************\n"));
|
|
||||||
else if(command == "GET")
|
else if(command == "GET")
|
||||||
p_stdout(_("-- GET COMMAND --\nSyntax: GET <attr_name>\n"
|
p_stdout(_("-- GET COMMAND --\nSyntax: GET <attr_name>\n"
|
||||||
"\twhere <attr_name> may be simulation-tick or continuous.\n"));
|
"\twhere <attr_name> may be simulation-tick or continuous.\n"));
|
||||||
|
|
|
@ -171,6 +171,7 @@ namespace sgpem
|
||||||
|
|
||||||
std::vector<memory::smart_ptr<IOManager> > _devices;
|
std::vector<memory::smart_ptr<IOManager> > _devices;
|
||||||
static void _io_loop(std::pair<TextSimulation*, int>);
|
static void _io_loop(std::pair<TextSimulation*, int>);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue