- Added still more error checking to PythonCPUPolicy. But the code which calls its methods should be updated to handle the new exceptions...

- Added a base class for cpu policy exceptions to make simpler their catching
- Implemented all numeric fields in dialogs with spinboxes, with bounds checking

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@838 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
elvez 2006-08-10 00:42:17 +00:00
parent d3c7b46853
commit 48fc2f5a00
18 changed files with 298 additions and 177 deletions

View File

@ -153,6 +153,7 @@ src_backend_libbackend_la_SOURCES = \
src/backend/concrete_simulation.cc \ src/backend/concrete_simulation.cc \
src/backend/cpu_policies_gatekeeper.cc \ src/backend/cpu_policies_gatekeeper.cc \
src/backend/cpu_policy.cc \ src/backend/cpu_policy.cc \
src/backend/cpu_policy_exception.cc \
src/backend/cpu_policy_manager.cc \ src/backend/cpu_policy_manager.cc \
src/backend/dynamic_process.cc \ src/backend/dynamic_process.cc \
src/backend/dynamic_request.cc \ src/backend/dynamic_request.cc \
@ -203,6 +204,7 @@ pkginclude_HEADERS += \
config.h \ config.h \
src/backend/cpu_policies_gatekeeper.hh \ src/backend/cpu_policies_gatekeeper.hh \
src/backend/cpu_policy.hh \ src/backend/cpu_policy.hh \
src/backend/cpu_policy_exception.hh \
src/backend/cpu_policy_manager.hh \ src/backend/cpu_policy_manager.hh \
src/backend/environment.hh \ src/backend/environment.hh \
src/backend/global_preferences.hh \ src/backend/global_preferences.hh \

View File

@ -75,50 +75,6 @@
<property name="row_spacing">11</property> <property name="row_spacing">11</property>
<property name="column_spacing">9</property> <property name="column_spacing">9</property>
<child>
<widget class="GtkEntry" id="ArrivalTime.Entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
<property name="width_chars">17</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="BasePriority.Entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
<property name="width_chars">17</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="Name.Label"> <widget class="GtkLabel" id="Name.Label">
<property name="visible">True</property> <property name="visible">True</property>
@ -224,6 +180,48 @@
<property name="y_options"></property> <property name="y_options"></property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkSpinButton" id="ArrivalTime.Spin">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="climb_rate">1</property>
<property name="digits">0</property>
<property name="numeric">True</property>
<property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property>
<property name="wrap">False</property>
<property name="adjustment">1 1 inf 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="BasePriority.Spin">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="climb_rate">1</property>
<property name="digits">0</property>
<property name="numeric">True</property>
<property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property>
<property name="wrap">False</property>
<property name="adjustment">0 0 inf 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>

View File

@ -105,16 +105,16 @@
</child> </child>
<child> <child>
<widget class="GtkEntry" id="Instant.Entry"> <widget class="GtkSpinButton" id="Instant.Spin">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="editable">True</property> <property name="climb_rate">1</property>
<property name="visibility">True</property> <property name="digits">0</property>
<property name="max_length">0</property> <property name="numeric">True</property>
<property name="text" translatable="yes"></property> <property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="has_frame">True</property> <property name="snap_to_ticks">False</property>
<property name="invisible_char">●</property> <property name="wrap">False</property>
<property name="activates_default">False</property> <property name="adjustment">0 0 inf 1 10 10</property>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>
@ -225,27 +225,6 @@
</packing> </packing>
</child> </child>
<child>
<widget class="GtkEntry" id="Duration.Entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child> <child>
<widget class="GtkComboBoxEntry" id="Resource.Combo"> <widget class="GtkComboBoxEntry" id="Resource.Combo">
<property name="visible">True</property> <property name="visible">True</property>
@ -261,6 +240,27 @@
<property name="y_options">fill</property> <property name="y_options">fill</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkSpinButton" id="Duration.Spin">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="climb_rate">1</property>
<property name="digits">0</property>
<property name="numeric">True</property>
<property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property>
<property name="wrap">False</property>
<property name="adjustment">1 1 inf 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>

View File

@ -163,7 +163,7 @@
<property name="update_policy">GTK_UPDATE_ALWAYS</property> <property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property> <property name="snap_to_ticks">False</property>
<property name="wrap">False</property> <property name="wrap">False</property>
<property name="adjustment">1 1 100 1 10 10</property> <property name="adjustment">1 1 inf 1 10 10</property>
</widget> </widget>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -212,7 +212,7 @@
<property name="update_policy">GTK_UPDATE_ALWAYS</property> <property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property> <property name="snap_to_ticks">False</property>
<property name="wrap">False</property> <property name="wrap">False</property>
<property name="adjustment">1 0 100 1 10 10</property> <property name="adjustment">0 0 inf 1 10 10</property>
</widget> </widget>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>

View File

@ -153,28 +153,6 @@
</packing> </packing>
</child> </child>
<child>
<widget class="GtkEntry" id="BasePriority.Entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
<property name="width_chars">17</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="ArrivalTime.Label"> <widget class="GtkLabel" id="ArrivalTime.Label">
<property name="visible">True</property> <property name="visible">True</property>
@ -203,28 +181,6 @@
</packing> </packing>
</child> </child>
<child>
<widget class="GtkEntry" id="ArrivalTime.Entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
<property name="width_chars">17</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="CpuTime.Label"> <widget class="GtkLabel" id="CpuTime.Label">
<property name="visible">True</property> <property name="visible">True</property>
@ -254,16 +210,16 @@
</child> </child>
<child> <child>
<widget class="GtkEntry" id="CpuTime.Entry"> <widget class="GtkSpinButton" id="CpuTime.Spin">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="editable">True</property> <property name="climb_rate">1</property>
<property name="visibility">True</property> <property name="digits">0</property>
<property name="max_length">0</property> <property name="numeric">True</property>
<property name="text" translatable="yes"></property> <property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="has_frame">True</property> <property name="snap_to_ticks">False</property>
<property name="invisible_char">●</property> <property name="wrap">False</property>
<property name="activates_default">False</property> <property name="adjustment">1 1 inf 1 10 10</property>
</widget> </widget>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -273,6 +229,48 @@
<property name="y_options"></property> <property name="y_options"></property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkSpinButton" id="ArrivalTime.Spin">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="climb_rate">1</property>
<property name="digits">0</property>
<property name="numeric">True</property>
<property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property>
<property name="wrap">False</property>
<property name="adjustment">0 0 inf 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="BasePriority.Spin">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="climb_rate">1</property>
<property name="digits">0</property>
<property name="numeric">True</property>
<property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property>
<property name="wrap">False</property>
<property name="adjustment">0 0 inf 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>

View File

@ -1,4 +1,4 @@
import mutex, thread import sys, mutex, thread
import sgpem import sgpem
## @brief This is an adapter class which acts as a proxy ## @brief This is an adapter class which acts as a proxy
@ -26,6 +26,8 @@ class ScriptAdapter :
## Var Testable syncronization object ## Var Testable syncronization object
_g_mutex = mutex.mutex() _g_mutex = mutex.mutex()
_g_last_exception = None
## @brief Constructor of ScriptAdapter ## @brief Constructor of ScriptAdapter
# #
# @param self The caller object # @param self The caller object
@ -38,15 +40,19 @@ class ScriptAdapter :
# #
# @param self The caller object # @param self The caller object
def async_configure(self): def async_configure(self):
self._g_mutex.lock(ScriptAdapter._wrap_configure, self ) self._g_last_exception = None
self._g_mutex.lock(ScriptAdapter._wrap_configure, self )
def _wrap_configure(self): def _wrap_configure(self):
thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,)) thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,))
def _wrap_configure_callback(self): def _wrap_configure_callback(self):
# call configure method # call configure method
self._policy.configure() try:
self._g_mutex.unlock() self._policy.configure()
except:
self._g_last_exception = sys.exc_value
self._g_mutex.unlock()
## @brief Asynchronously call Policy.sort_queue() ## @brief Asynchronously call Policy.sort_queue()
@ -56,6 +62,7 @@ class ScriptAdapter :
# #
# @param self The caller object # @param self The caller object
def async_sort_queue(self): def async_sort_queue(self):
self._g_last_exception = None
self._g_mutex.lock(ScriptAdapter._wrap_sort_queue, self) self._g_mutex.lock(ScriptAdapter._wrap_sort_queue, self)
def _wrap_sort_queue(self): def _wrap_sort_queue(self):
@ -64,7 +71,11 @@ class ScriptAdapter :
def _wrap_sort_queue_callback(self): def _wrap_sort_queue_callback(self):
# here we retrieve and pass the ready queue # here we retrieve and pass the ready queue
queue = sgpem.Scheduler.get_instance().get_ready_queue() queue = sgpem.Scheduler.get_instance().get_ready_queue()
self._policy.sort_queue(queue)
try:
self._policy.sort_queue(queue)
except:
self._g_last_exception = sys.exc_value
self._g_mutex.unlock() self._g_mutex.unlock()
@ -72,26 +83,34 @@ class ScriptAdapter :
# #
# @param self The caller object # @param self The caller object
def async_is_preemptive(self): def async_is_preemptive(self):
self._g_last_exception = None
self._g_mutex.lock(ScriptAdapter._wrap_is_preemptive, self) self._g_mutex.lock(ScriptAdapter._wrap_is_preemptive, self)
def _wrap_is_preemptive(self): def _wrap_is_preemptive(self):
thread.start_new_thread(ScriptAdapter._wrap_is_preemptive_callback, (self,)) thread.start_new_thread(ScriptAdapter._wrap_is_preemptive_callback, (self,))
def _wrap_is_preemptive_callback(self): def _wrap_is_preemptive_callback(self):
self._ret_val = self._policy.is_preemptive() try:
self._ret_val = self._policy.is_preemptive()
except:
self._g_last_exception = sys.exc_value
self._g_mutex.unlock() self._g_mutex.unlock()
## @brief Asynchronously call Policy.get_time_slice() ## @brief Asynchronously call Policy.get_time_slice()
# #
# @param self The caller object # @param self The caller object
def async_get_time_slice(self): def async_get_time_slice(self):
self._g_last_exception = None
self._g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self) self._g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self)
def _wrap_get_time_slice(self): def _wrap_get_time_slice(self):
thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,)) thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,))
def _wrap_get_time_slice_callback(self): def _wrap_get_time_slice_callback(self):
self._ret_val = self._policy.get_time_slice() try:
self._ret_val = self._policy.get_time_slice()
except:
self._g_last_exception = sys.exc_value
self._g_mutex.unlock() self._g_mutex.unlock()
## @brief Return the global shared variable with the methods' last return value ## @brief Return the global shared variable with the methods' last return value
@ -100,3 +119,7 @@ class ScriptAdapter :
def mutex_test_lock(self): def mutex_test_lock(self):
return self._g_mutex.test() return self._g_mutex.test()
def get_last_exception(self):
return self._g_last_exception

View File

@ -40,7 +40,7 @@ PythonCPUPolicy::PythonCPUPolicy(const char* name) throw(MalformedPolicyExceptio
Py_DECREF(pLoadmeStr); Py_DECREF(pLoadmeStr);
if (pUserCPUPolicyModule == NULL) if (pUserCPUPolicyModule == NULL)
throw MalformedPolicyException(get_exception_information().c_str()); throw MalformedPolicyException(get_exception_information());
// Dictionary with defined ``symbols'' for .pyc file // Dictionary with defined ``symbols'' for .pyc file
_upolicy_dict = PyModule_GetDict(pUserCPUPolicyModule); _upolicy_dict = PyModule_GetDict(pUserCPUPolicyModule);
@ -70,7 +70,7 @@ PythonCPUPolicy::PythonCPUPolicy(const char* name) throw(MalformedPolicyExceptio
Py_DECREF(pScriptAdapterModule); Py_DECREF(pScriptAdapterModule);
if (_adapter == NULL) if (_adapter == NULL)
throw MalformedPolicyException(get_exception_information().c_str()); throw MalformedPolicyException(get_exception_information());
// And now, who's your daddy, huh? // And now, who's your daddy, huh?
} }
@ -87,7 +87,7 @@ PythonCPUPolicy::~PythonCPUPolicy()
} }
void void
PythonCPUPolicy::activate() PythonCPUPolicy::activate() throw(UserInterruptException, MalformedPolicyException)
{ {
// FIXME write the rest, taking away code from constructor // FIXME write the rest, taking away code from constructor
@ -107,7 +107,7 @@ PythonCPUPolicy::deactivate()
void void
PythonCPUPolicy::configure() throw(UserInterruptException) PythonCPUPolicy::configure() throw(UserInterruptException, MalformedPolicyException)
{ {
PyObject* retval = PyObject_CallMethod(_adapter, "async_configure", NULL); PyObject* retval = PyObject_CallMethod(_adapter, "async_configure", NULL);
Py_DECREF(retval); Py_DECREF(retval);
@ -117,7 +117,7 @@ PythonCPUPolicy::configure() throw(UserInterruptException)
void void
PythonCPUPolicy::sort_queue() const throw(UserInterruptException) PythonCPUPolicy::sort_queue() const throw(UserInterruptException, MalformedPolicyException)
{ {
PyObject* retval = PyObject_CallMethod(_adapter, "async_sort_queue", NULL); PyObject* retval = PyObject_CallMethod(_adapter, "async_sort_queue", NULL);
@ -143,7 +143,7 @@ PythonCPUPolicy::get_name() const
} }
bool bool
PythonCPUPolicy::is_pre_emptive() const throw(UserInterruptException) PythonCPUPolicy::is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException)
{ {
PyObject* retval = PyObject_CallMethod(_adapter, "async_is_preemptive", NULL); PyObject* retval = PyObject_CallMethod(_adapter, "async_is_preemptive", NULL);
Py_DECREF(retval); Py_DECREF(retval);
@ -160,7 +160,7 @@ PythonCPUPolicy::is_pre_emptive() const throw(UserInterruptException)
int int
PythonCPUPolicy::get_time_slice() const throw(UserInterruptException) PythonCPUPolicy::get_time_slice() const throw(UserInterruptException, MalformedPolicyException)
{ {
PyObject* retval = PyObject_CallMethod(_adapter, "async_get_time_slice", NULL); PyObject* retval = PyObject_CallMethod(_adapter, "async_get_time_slice", NULL);
@ -181,7 +181,7 @@ PythonCPUPolicy::get_time_slice() const throw(UserInterruptException)
void void
PythonCPUPolicy::wait_unlock() const throw(UserInterruptException) PythonCPUPolicy::wait_unlock() const throw(UserInterruptException, MalformedPolicyException)
{ {
PyThreadState* _save; PyThreadState* _save;
int i = 0; // We give the sort_queue() three seconds max time, then... int i = 0; // We give the sort_queue() three seconds max time, then...
@ -198,7 +198,7 @@ PythonCPUPolicy::wait_unlock() const throw(UserInterruptException)
assert(retval); assert(retval);
still_locked = PyObject_IsTrue(retval); still_locked = PyObject_IsTrue(retval);
Py_DECREF(retval); Py_DECREF(retval);
if (i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */ if (i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
{ {
PyThreadState_Clear(_save); PyThreadState_Clear(_save);
@ -207,13 +207,37 @@ PythonCPUPolicy::wait_unlock() const throw(UserInterruptException)
Py_UNBLOCK_THREADS; Py_UNBLOCK_THREADS;
PyEval_RestoreThread(_save); PyEval_RestoreThread(_save);
if(PyErr_Occurred() != NULL)
abort();
throw UserInterruptException(_("User-defined policy is " throw UserInterruptException(_("User-defined policy is "
"taking too long to terminate.")); "taking too long to terminate."));
} }
} }
while (still_locked); while (still_locked);
// check if there were unhandled exception in the user-defined code
PyObject* pException = PyObject_CallMethod(_adapter, "get_last_exception", NULL);
if(pException != NULL)
{
if(pException != Py_None)
{
PyObject* pExceptStr = PyObject_Str(pException);
string msg = _("unhandled exception in user policy: ");
msg += PyString_AsString(pExceptStr);
Py_DECREF(pExceptStr);
Py_DECREF(pException);
throw MalformedPolicyException(msg);
}
else
Py_DECREF(pException);
}
// What we should really do here: // What we should really do here:
/* do { /* do {
enable python threads enable python threads
@ -260,6 +284,8 @@ PythonCPUPolicy::get_exception_information()
if (pValue != NULL) Py_DECREF(pValue); if (pValue != NULL) Py_DECREF(pValue);
if (pTraceback != NULL) Py_DECREF(pTraceback); if (pTraceback != NULL) Py_DECREF(pTraceback);
PyErr_Clear();
return msg; return msg;
} }

View File

@ -51,12 +51,12 @@ namespace sgpem
/** /**
Calls the method \c async_configure Calls the method \c async_configure
*/ */
void configure() throw(UserInterruptException); void configure() throw(UserInterruptException, MalformedPolicyException);
/** /**
Calls the method \c async_sort_queue Calls the method \c async_sort_queue
*/ */
void sort_queue() const throw(UserInterruptException); void sort_queue() const throw(UserInterruptException, MalformedPolicyException);
/** /**
\returns A textual description of this policy. \returns A textual description of this policy.
@ -69,14 +69,14 @@ namespace sgpem
\returns \c TRUE if the policy is preemptive. \returns \c TRUE if the policy is preemptive.
\returns \c FALSE if the policy is not preemptive. \returns \c FALSE if the policy is not preemptive.
*/ */
bool is_pre_emptive() const throw(UserInterruptException); bool is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException);
/** /**
\returns The integer value of its time-slice. \returns The integer value of its time-slice.
*/ */
int get_time_slice() const throw(UserInterruptException); int get_time_slice() const throw(UserInterruptException, MalformedPolicyException);
void activate(); void activate() throw(UserInterruptException, MalformedPolicyException);
void deactivate(); void deactivate();
@ -84,7 +84,7 @@ namespace sgpem
PythonCPUPolicy(const PythonCPUPolicy&); PythonCPUPolicy(const PythonCPUPolicy&);
PythonCPUPolicy& operator=(const PythonCPUPolicy&); PythonCPUPolicy& operator=(const PythonCPUPolicy&);
void wait_unlock() const throw(UserInterruptException); void wait_unlock() const throw(UserInterruptException, MalformedPolicyException);
static std::string get_exception_information(); static std::string get_exception_information();
PyObject* _upolicy_dict; PyObject* _upolicy_dict;

View File

@ -101,8 +101,18 @@ CPUPoliciesGatekeeper::activate_policy(History *history, CPUPolicy* policy)
if (pos == end || pos->second != policy) if (pos == end || pos->second != policy)
{ {
_active_policies[history] = policy; try
_active_policies[history]->activate(); {
policy->activate();
_active_policies[history] = policy;
}
catch(UserInterruptException e)
{
//FIXME what to do here???
//probably throwing again a MalformedPolicyException
//maybe the best idea. or can we just fallback
//to the previous policy?
}
} }
} }

View File

@ -28,6 +28,7 @@
#include "policy_parameters.hh" #include "policy_parameters.hh"
#include "user_interrupt_exception.hh" #include "user_interrupt_exception.hh"
#include "malformed_policy_exception.hh"
namespace sgpem namespace sgpem
{ {
@ -50,7 +51,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented Because it's a pure virtual method, must be re-implemented
in concrete derived classes. in concrete derived classes.
*/ */
virtual void configure() throw(UserInterruptException) = 0; virtual void configure() throw(UserInterruptException, MalformedPolicyException) = 0;
/** /**
Sort the \ref ReadyQueue object that contain all the Schedulable objects Sort the \ref ReadyQueue object that contain all the Schedulable objects
@ -59,7 +60,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented Because it's a pure virtual method, must be re-implemented
in concrete derived classes. in concrete derived classes.
*/ */
virtual void sort_queue() const throw(UserInterruptException) = 0; virtual void sort_queue() const throw(UserInterruptException, MalformedPolicyException) = 0;
/** /**
Gets a string description of the policy. Gets a string description of the policy.
@ -79,7 +80,7 @@ namespace sgpem
in concrete derived classes. in concrete derived classes.
\return True if this policy is preemptible. \return True if this policy is preemptible.
*/ */
virtual bool is_pre_emptive() const throw(UserInterruptException) = 0; virtual bool is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException) = 0;
/** /**
Gets the time quantum for the policy. Gets the time quantum for the policy.
@ -88,9 +89,9 @@ namespace sgpem
in concrete derived classes. in concrete derived classes.
\return Time quantum for the policy. \return Time quantum for the policy.
*/ */
virtual int get_time_slice() const throw(UserInterruptException) = 0; virtual int get_time_slice() const throw(UserInterruptException, MalformedPolicyException) = 0;
virtual void activate() = 0; virtual void activate() throw(UserInterruptException, MalformedPolicyException) = 0;
virtual void deactivate() = 0; virtual void deactivate() = 0;

View File

@ -0,0 +1,31 @@
// src/backend/cpu_policy_exception.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
// Warning! This exception will be thrown across different libraries.
// It could be necessary to do dynamic type-checking when
// catching it (with typeinfo).
#include "malformed_policy_exception.hh"
using namespace sgpem;
CPUPolicyException::CPUPolicyException(const std::string& msg)
: std::runtime_error(msg)
{}

View File

@ -0,0 +1,43 @@
// src/backend/cpu_policy_exception.hh - 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
// Warning! This exception will be thrown across different libraries.
// It could be necessary to do dynamic type-checking when
// catching it (with typeinfo).
#ifndef CPU_POLICY_EXCEPTION
#define CPU_POLICY_EXCEPTION 1
#include "config.h"
#include <stdexcept>
namespace sgpem
{
class CPUPolicyException;
class SG_DLLEXPORT CPUPolicyException : public std::runtime_error
{
public:
explicit CPUPolicyException(const std::string& msg = "");
};
} //~ namespace sgpem
#endif

View File

@ -25,8 +25,7 @@
#include "malformed_policy_exception.hh" #include "malformed_policy_exception.hh"
using namespace sgpem; using namespace sgpem;
MalformedPolicyException::MalformedPolicyException(const char* msg) MalformedPolicyException::MalformedPolicyException(const std::string& msg)
: std::runtime_error(msg) : CPUPolicyException(msg)
{} {}
MalformedPolicyException::~MalformedPolicyException() throw() {}

View File

@ -27,19 +27,16 @@
#include "config.h" #include "config.h"
#include <stdexcept> #include "cpu_policy_exception.hh"
namespace sgpem namespace sgpem
{ {
class MalformedPolicyException; class MalformedPolicyException;
class SG_DLLEXPORT MalformedPolicyException : public std::runtime_error class SG_DLLEXPORT MalformedPolicyException : public CPUPolicyException
{ {
public: public:
MalformedPolicyException(const char* msg = ""); explicit MalformedPolicyException(const std::string& msg = "");
virtual ~MalformedPolicyException() throw ();
private:
}; };
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -29,4 +29,3 @@ NullPolicyException::NullPolicyException(const char* msg)
: std::runtime_error(msg) : std::runtime_error(msg)
{} {}
NullPolicyException::~NullPolicyException() throw() {}

View File

@ -37,9 +37,6 @@ namespace sgpem
{ {
public: public:
NullPolicyException(const char* msg = ""); NullPolicyException(const char* msg = "");
virtual ~NullPolicyException() throw ();
private:
}; };
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -26,7 +26,6 @@
using namespace sgpem; using namespace sgpem;
UserInterruptException::UserInterruptException(const char* msg) UserInterruptException::UserInterruptException(const char* msg)
: std::runtime_error(msg) : CPUPolicyException(msg)
{} {}
UserInterruptException::~UserInterruptException() throw() {}

View File

@ -26,6 +26,7 @@
#define USER_INTERRUPT_EXCEPTION 1 #define USER_INTERRUPT_EXCEPTION 1
#include "config.h" #include "config.h"
#include "cpu_policy_exception.hh"
#include <stdexcept> #include <stdexcept>
@ -33,13 +34,10 @@ namespace sgpem
{ {
class UserInterruptException; class UserInterruptException;
class SG_DLLEXPORT UserInterruptException : public std::runtime_error class SG_DLLEXPORT UserInterruptException : public CPUPolicyException
{ {
public: public:
UserInterruptException(const char* msg = ""); explicit UserInterruptException(const char* msg = "");
virtual ~UserInterruptException() throw ();
private:
}; };
} //~ namespace sgpem } //~ namespace sgpem