- 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:
tchernobog 2006-08-01 09:19:26 +00:00
parent 6f8625d308
commit c6ebe792e4
6 changed files with 57 additions and 85 deletions

View File

@ -82,98 +82,64 @@ ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException)
case state_stopped:
_history.reset(true);
break;
default:
;
}
_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;
if(get_policy() == NULL)
{
stop();
throw NullPolicyException("no policy selected");
}
//******* 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
{
//step forward
bool yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy());
if(!yet_to_finish) stop();
//sleep
Glib::usleep(_timer_interval*1000);
}
catch(UserInterruptException e)
{
stop();
throw;
}
//check the state
if (_state == state_stopped || _state == state_paused)
return;
}
try
{
if(get_policy() == NULL)
{
stop();
throw NullPolicyException("no policy selected");
}
//step forward
Scheduler::get_instance().step_forward(_history, *get_policy());
//sleep
Glib::usleep(_timer_interval*1000);
}
catch(UserInterruptException e)
{
stop();
throw;
}
//check the state
if (_state == state_stopped || _state == state_paused)
return;
}
while(true);
}
//******* STEP by STEP
else
{
bool all_term = true;
for(ProcessesIt it = processes.begin(); it != processes.end(); ++it)
if((*it)->get_state() != Schedulable::state_terminated)
try
{
all_term = false;
break;
assert(get_policy() != NULL);
//step forward
bool yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy());
if(yet_to_finish)
pause();
else
stop();
}
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
catch(UserInterruptException e)
{
assert(get_policy() != NULL);
//step forward
Scheduler::get_instance().step_forward(_history, *get_policy());
}
catch(UserInterruptException e)
{
throw;
}
}
stop();
throw;
}
}
}
Simulation::state

View File

@ -161,7 +161,7 @@ Scheduler::get_policy()
}
void
bool
Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterruptException)
{
// 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 ----------------
// 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;
/* /
@ -329,6 +331,8 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
// - SimulationController that everything stopped
throw;
}
final_cleanup:
// append the new snapshot...
// ...and remember to release the auto_ptr!
@ -337,6 +341,9 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
// Reset values that the policy doesn't need anymore
_policy = NULL;
_ready_queue = NULL;
// If we got there, a step has been performed
return simulation_ended == false;
}

View File

@ -74,8 +74,10 @@ namespace sgpem
Generates a new ReadyQueue representing the status of the processes
at the simulation instant next to the current one, and extends the History by
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.

View File

@ -131,14 +131,11 @@ parse_options(int argc, char** argv)
// initialize the command line version
// of sgpemv2
TextSimulation sim;
while(1)
{
std::string str;
getline(std::cin, str);
TextSimulation::parse_command(sim, str);
}
std::string str;
while(getline(std::cin, str))
// Enter main loop
TextSimulation::parse_command(sim, str);
}
else
{

View File

@ -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 "
"cpu policies without modifying their source code.\n"));
else if(command == "HELP")
p_stdout(_("-- Do you really want me to explain what HELP means? --\n"
" ************** YOU ARE JOKING ME !!! ************\n"));
p_stdout(_("-- HELP COMMAND --\nThe help you're reading"));
else if(command == "GET")
p_stdout(_("-- GET COMMAND --\nSyntax: GET <attr_name>\n"
"\twhere <attr_name> may be simulation-tick or continuous.\n"));

View File

@ -171,6 +171,7 @@ namespace sgpem
std::vector<memory::smart_ptr<IOManager> > _devices;
static void _io_loop(std::pair<TextSimulation*, int>);
};
}