- 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()
CPUPoliciesGatekeeper::get_instance().activate_policy(&_history, p); try
{
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,46 +90,57 @@ 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:
{ // * it calls the configure() method on the
// policy->activate() needs already an active policy, because: // insert-your-favourite-scripting-language-here-policy
// * it calls the configure() method on the // * which in turn calls the configure() method in the
// insert-your-favourite-scripting-language-here-policy // code written by the user
// * which in turn calls the configure() method in the // * which probably uses Simulation to get the _active_ C++ policy,
// code written by the user // so it can get its policy_parameters()
// * which probably uses Simulation to get the _active_ C++ policy, // ... so **DON'T** play Mr. Clever Dick and swap the following two
// so it can get its policy_parameters() // lines in an optimization frenzy! Or the user policy WILL fail.
// ... so **DON'T** play Mr. Clever Dick and swap the following two _active_policies[history] = policy;
// lines in an optimization frenzy! Or the user policy WILL fail. policy->activate();
_active_policies[history] = policy;
policy->activate();
}
catch(const CPUPolicyException& e)
{
std::cerr << e.what() << std::endl;
// See the comment above to understand why we do this
// in this way
_active_policies.erase(_active_policies.find(history));
}
} }
catch(const CPUPolicyException& e)
{
//std::cerr << e.what() << std::endl;
// See the comment above to understand why we do this
// in this way
_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,7 +374,17 @@ 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"));
Simulation::get_instance().set_policy(NULL); 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) catch (const NullPolicyException& e)
{ {
@ -666,8 +676,8 @@ TextSimulation::on_set(const Tokens& arguments)
vector<CPUPolicy*> policies = (*it)->get_avail_policies(); vector<CPUPolicy*> policies = (*it)->get_avail_policies();
for (CPUPolicyIt it = policies.begin(); it != policies.end(); ++it) for (CPUPolicyIt it = policies.begin(); it != policies.end(); ++it)
{ {
if (policy == 0) if (policy == 0)
Simulation::get_instance().set_policy(*it); Simulation::get_instance().set_policy(*it);
--policy; --policy;
} }
@ -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")
{ {