- All policy-related errors should now be handled. I hope this is the last time I say this...

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@850 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
elvez 2006-08-13 14:20:04 +00:00
parent cb4f0e878d
commit 1be6a9ca58
7 changed files with 102 additions and 36 deletions

View File

@ -155,11 +155,39 @@ ConcreteSimulation::get_history()
} }
void void
ConcreteSimulation::set_policy(CPUPolicy* p) ConcreteSimulation::set_policy(CPUPolicy* p) throw(CPUPolicyException)
{ {
_policy = p; // NOTE: restoring of the previous policy is done here because I
// couldn't think of a clean way to do it
// inside activate_policy()
try
{
CPUPoliciesGatekeeper::get_instance().activate_policy(&_history, p); CPUPoliciesGatekeeper::get_instance().activate_policy(&_history, p);
_policy = p;
}
catch(const CPUPolicyException& e1)
{
try
{
// this is a no-op if _policy is NULL
CPUPoliciesGatekeeper::get_instance().activate_policy(&_history, _policy);
}
catch(const CPUPolicyException& e2)
{
_policy = NULL;
string msg = _("unable to change policy and to restore the previous: ");
msg += e2.what();
throw CPUPolicyException(msg);
}
string msg = _("unable to change policy: ");
msg+= e1.what();
throw CPUPolicyException(msg);
}
} }

View File

@ -49,7 +49,10 @@ namespace sgpem
state get_state() const; state get_state() const;
void set_policy(CPUPolicy*); /**
\throw An instance of CPUPolicyException, \b not a derived class!!!
*/
void set_policy(CPUPolicy*) throw(CPUPolicyException);
ConcreteHistory& get_history(); ConcreteHistory& get_history();

View File

@ -90,24 +90,32 @@ CPUPoliciesGatekeeper::get_current_policy(History* history) throw(runtime_error)
} }
void void
CPUPoliciesGatekeeper::activate_policy(History *history, CPUPolicy* policy) CPUPoliciesGatekeeper::activate_policy(History *history, CPUPolicy* policy) throw(UserInterruptException, MalformedPolicyException)
{ {
assert(history != NULL); assert(history != NULL);
ActiveIterator end = _active_policies.end(); ActiveIterator end = _active_policies.end();
ActiveIterator pos = _active_policies.find(history); ActiveIterator pos = _active_policies.find(history);
if (pos != end && pos->second != policy) // deactivate the policy, if necessary
_active_policies[history]->deactivate(); if (pos != end)
{
// nothing to do in this case
if(pos->second == policy)
return;
pos->second->deactivate();
}
// if policy is NULL, simply erase the entry and return, since we are sure the policy is
// not active due to the previous lines
if(policy == NULL) if(policy == NULL)
{ {
_active_policies.erase(pos); // this is a no-op if history is not a key used in the map
_active_policies.erase(history);
return; return;
} }
if (pos == end || pos->second != policy)
{
try try
{ {
// policy->activate() needs already an active policy, because: // policy->activate() needs already an active policy, because:
@ -124,12 +132,15 @@ CPUPoliciesGatekeeper::activate_policy(History *history, CPUPolicy* policy)
} }
catch(const CPUPolicyException& e) catch(const CPUPolicyException& e)
{ {
std::cerr << e.what() << std::endl; //std::cerr << e.what() << std::endl;
// See the comment above to understand why we do this // See the comment above to understand why we do this
// in this way // in this way
_active_policies.erase(_active_policies.find(history)); _active_policies.erase(_active_policies.find(history));
// the caller need to know if it failed
throw;
} }
}
} }
CPUPoliciesGatekeeper::CPUPoliciesGatekeeper() CPUPoliciesGatekeeper::CPUPoliciesGatekeeper()

View File

@ -35,6 +35,8 @@ namespace sgpem
#include <stdexcept> #include <stdexcept>
#include "singleton.hh" #include "singleton.hh"
#include "malformed_policy_exception.hh"
#include "user_interrupt_exception.hh"
namespace sgpem namespace sgpem
{ {
@ -58,7 +60,11 @@ namespace sgpem
CPUPolicy* get_current_policy(History* history) throw(std::runtime_error); CPUPolicy* get_current_policy(History* history) throw(std::runtime_error);
void activate_policy(History* history, CPUPolicy* policy); /**
Associates policy with history. If an exception is thrown, the current associated
policy with this history (if there are any), is \b no more active, \b nor associated
*/
void activate_policy(History* history, CPUPolicy* policy) throw(UserInterruptException, MalformedPolicyException);
private: private:
CPUPoliciesGatekeeper(); //private constructor. CPUPoliciesGatekeeper(); //private constructor.

View File

@ -640,7 +640,7 @@ try_to_run(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapshot)
bool bool
Scheduler::step_forward(ConcreteHistory& concrete_history, CPUPolicy& cpu_policy) Scheduler::step_forward(ConcreteHistory& concrete_history, CPUPolicy& cpu_policy)
throw(UserInterruptException) throw(UserInterruptException, MalformedPolicyException)
{ {
// Preconditions: // Preconditions:
assert (concrete_history.get_size() > 0); assert (concrete_history.get_size() > 0);

View File

@ -32,6 +32,7 @@ namespace sgpem
#include "cpu_policy.hh" #include "cpu_policy.hh"
#include "ready_queue.hh" #include "ready_queue.hh"
#include "user_interrupt_exception.hh" #include "user_interrupt_exception.hh"
#include "malformed_policy_exception.hh"
// Do not include full template definition here // Do not include full template definition here
#include "singleton.hh" #include "singleton.hh"
@ -78,7 +79,7 @@ namespace sgpem
\return false If the simulation has ended, true otherwise \return false If the simulation has ended, true otherwise
*/ */
bool step_forward(ConcreteHistory& history, CPUPolicy& cpu_policy) throw(UserInterruptException); bool step_forward(ConcreteHistory& history, CPUPolicy& cpu_policy) throw(UserInterruptException, MalformedPolicyException);
/** /**
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.

View File

@ -374,8 +374,18 @@ TextSimulation::on_run(const Tokens& arguments)
p_stderr(e.what()); p_stderr(e.what());
p_stderr(_("\nSimulation is now stopped, and " p_stderr(_("\nSimulation is now stopped, and "
"the current policy will be deactivated\n")); "the current policy will be deactivated\n"));
try
{
Simulation::get_instance().set_policy(NULL); 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) catch (const NullPolicyException& e)
{ {
p_stderr(_("ERROR: ")); p_stderr(_("ERROR: "));
@ -680,6 +690,13 @@ TextSimulation::on_set(const Tokens& arguments)
{ {
p_stderr(_("ERROR: invalid unsigned integer or not a valid policy index\n")); p_stderr(_("ERROR: invalid unsigned integer or not a valid policy index\n"));
} }
catch (const CPUPolicyException& e)
{
p_stderr(_("ERROR: "));
p_stderr(e.what());
p_stderr("\n");
}
} }
else if (attr == "CONTINUOUS") else if (attr == "CONTINUOUS")
{ {