diff --git a/plugins/pyloader/src/Policy.py b/plugins/pyloader/src/Policy.py index 8b7e304..ac10e56 100644 --- a/plugins/pyloader/src/Policy.py +++ b/plugins/pyloader/src/Policy.py @@ -92,7 +92,18 @@ class Policy: # @return 0+ To specify a time slice duration for this policy get_time_slice = AbstractMethod('get_time_slice') - + ## @brief Returns wether this policy sorts processes or threads + # + # Should be implemented with signature: + # @code + # def wants(self): + # # function body + # @endcode + # + # @return sgpem.policy_sorts_processes If the policy sorts processes + # @return sgpem.policy_sorts_threads If the policy sorts threads + wants = AbstractMethod('wants') + ## @brief Returns the PolicyParameters instance you can use in # Policy::Policy::configure() # diff --git a/plugins/pyloader/src/ScriptAdapter.py b/plugins/pyloader/src/ScriptAdapter.py index 5ae3d53..1eb5583 100644 --- a/plugins/pyloader/src/ScriptAdapter.py +++ b/plugins/pyloader/src/ScriptAdapter.py @@ -95,6 +95,19 @@ class ScriptAdapter : self._ret_val = self._policy.get_time_slice() self._g_mutex.unlock() + ## @brief Asynchronously call Policy.wants() + # + # @param self The caller object + def async_wants(self): + self._g_mutex.lock(ScriptAdapter._wrap_wants, self) + + def _wrap_wants(self): + thread.start_new_thread(ScriptAdapter._wrap_wants_callback, (self,)) + + def _wrap_wants_callback(self): + self._ret_val = self._policy.wants() + self._g_mutex.unlock() + ## @brief Return the global shared variable with the methods' last return value def get_return_value(self): return self._ret_val diff --git a/plugins/pyloader/src/builtin-policies/fcfs.py b/plugins/pyloader/src/builtin-policies/fcfs.py index 023c5b1..5c43b9d 100644 --- a/plugins/pyloader/src/builtin-policies/fcfs.py +++ b/plugins/pyloader/src/builtin-policies/fcfs.py @@ -21,6 +21,7 @@ from Policy import Policy import sys +from sgpem import policy_sorts_processes class fcfs(Policy) : def __init__(self): @@ -35,6 +36,9 @@ class fcfs(Policy) : def get_time_slice(self): return -2 + def wants(self): + return policy_sorts_processes + def sort_queue(self, queue): cmpf = lambda a, b: \ a.get_schedulable().get_arrival_time() < \ diff --git a/plugins/pyloader/src/builtin-policies/sjf.py b/plugins/pyloader/src/builtin-policies/sjf.py index d894f19..8ee8281 100644 --- a/plugins/pyloader/src/builtin-policies/sjf.py +++ b/plugins/pyloader/src/builtin-policies/sjf.py @@ -21,6 +21,7 @@ from Policy import Policy import sys +from sgpem import policy_sorts_processes class sjf(Policy) : def __init__(self): @@ -35,6 +36,9 @@ class sjf(Policy) : def get_time_slice(self): return -1 + def wants(self): + return policy_sorts_processes + def sort_queue(self, queue): cmpf = lambda a, b: \ a.get_cpu_time_left() < \ diff --git a/plugins/pyloader/src/python_policy.cc b/plugins/pyloader/src/python_policy.cc index 4086718..44d3738 100644 --- a/plugins/pyloader/src/python_policy.cc +++ b/plugins/pyloader/src/python_policy.cc @@ -138,7 +138,8 @@ PythonPolicy::is_pre_emptive() const throw(UserInterruptException) int -PythonPolicy::get_time_slice() const throw(UserInterruptException) { +PythonPolicy::get_time_slice() const throw(UserInterruptException) +{ PyObject* retval = PyObject_CallMethod(_adapter, "async_get_time_slice", NULL); Py_DECREF(retval); @@ -153,6 +154,27 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException) { return tmp < 0 ? numeric_limits::max() : static_cast(tmp); } +policy_sorts_type +PythonPolicy::wants() const throw(UserInterruptException) +{ + PyObject* retval = PyObject_CallMethod(_adapter, "async_wants", NULL); + Py_DECREF(retval); + + wait_unlock(); + + // Parse return value stored in global Python object + retval = PyObject_CallMethod(_adapter, "get_return_value", NULL); + assert(retval); + long tmp = PyInt_AsLong(retval); + Py_DECREF(retval); + + //FIXME add the MalformedPolicyException class and throw it the else + // branch instead + if(tmp == policy_sorts_threads || tmp == policy_sorts_processes) + return static_cast(tmp); + else + return policy_sorts_processes; +} void PythonPolicy::wait_unlock() const throw(UserInterruptException) diff --git a/plugins/pyloader/src/python_policy.hh b/plugins/pyloader/src/python_policy.hh index ab67e98..cb7dcb5 100644 --- a/plugins/pyloader/src/python_policy.hh +++ b/plugins/pyloader/src/python_policy.hh @@ -72,7 +72,9 @@ namespace sgpem /** \returns The integer value of its time-slice. */ - int get_time_slice() const throw(UserInterruptException); + int get_time_slice() const throw(UserInterruptException); + + policy_sorts_type wants() const throw(UserInterruptException); private: PythonPolicy(const PythonPolicy&); diff --git a/plugins/pyloader/src/sgpem.i b/plugins/pyloader/src/sgpem.i index cacbd7a..7c2d203 100644 --- a/plugins/pyloader/src/sgpem.i +++ b/plugins/pyloader/src/sgpem.i @@ -38,6 +38,9 @@ namespace std { namespace sgpem { + /** Don't get worried, order is not important! */ + enum policy_sorts_type { policy_sorts_threads, policy_sorts_processes }; + class Policy { public: virtual ~Policy() = 0; diff --git a/src/backend/policy.hh b/src/backend/policy.hh index edad362..60a4aca 100644 --- a/src/backend/policy.hh +++ b/src/backend/policy.hh @@ -33,6 +33,12 @@ namespace sgpem { + enum policy_sorts_type + { + policy_sorts_threads, + policy_sorts_processes + }; + class Policy; /** \brief @@ -44,6 +50,7 @@ namespace sgpem class SG_DLLEXPORT Policy { public: + virtual ~Policy(); /** @@ -95,7 +102,17 @@ namespace sgpem \return Time quantum for the policy. */ virtual int get_time_slice() const throw(UserInterruptException) = 0; - + + /** + Tell what kind of entities are scheduled by this policy. + + Because it's a pure virtual method, must be re-implemented + in concrete derived classes. + \return A SortsType value identifying the desired type for the objects + composing the queue passed to the sort_queue method. + */ + virtual policy_sorts_type wants() const throw(UserInterruptException) = 0; + /** Gets the parameters related with this policy. diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index 5c2c114..d2d1c41 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -49,6 +49,7 @@ Scheduler::get_instance() SchedulableQueue* Scheduler::get_ready_queue() { + // FIXME return the correct queue accordingly to the value returned by Policy::wants() return &_ready_queue; }