From ad774067e1cdc42ea714eb74c0a9dc9fcc0ac5d4 Mon Sep 17 00:00:00 2001 From: tchernobog Date: Fri, 1 Sep 2006 17:03:34 +0000 Subject: [PATCH] - Add lottery and plain round robin cpu policies. I didn't test them extensively, mind you. Closes task #14. - Added documentation for each cpu policy - Manage extra-exception into PythonCPUPolicy (when the .py file doesn't contain a similarly named class) - Update exception output in GuiBuilder to make it slightly more descriptive git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@983 3ecf2c5c-341e-0410-92b4-d18e462d057c --- plugins/pyloader/Makefile.am | 2 + plugins/pyloader/src/builtin-policies/fcfs.py | 10 ++-- .../pyloader/src/builtin-policies/lottery.py | 48 ++++++++++++++++++ plugins/pyloader/src/builtin-policies/rr.py | 50 +++++++++++++++++++ .../src/builtin-policies/rr_priority.py | 10 +++- plugins/pyloader/src/builtin-policies/sjf.py | 20 ++++++-- plugins/pyloader/src/python_cpu_policy.cc | 4 +- src/gui_builder.cc | 4 +- 8 files changed, 135 insertions(+), 13 deletions(-) create mode 100644 plugins/pyloader/src/builtin-policies/lottery.py create mode 100644 plugins/pyloader/src/builtin-policies/rr.py diff --git a/plugins/pyloader/Makefile.am b/plugins/pyloader/Makefile.am index 6cd6dda..b039648 100644 --- a/plugins/pyloader/Makefile.am +++ b/plugins/pyloader/Makefile.am @@ -146,6 +146,8 @@ MOSTLYCLEANFILES += $(proxies) $(wrappers) # built-in policies policies_PYTHON = \ src/builtin-policies/fcfs.py \ + src/builtin-policies/lottery.py \ + src/builtin-policies/rr.py \ src/builtin-policies/rr_priority.py \ src/builtin-policies/sjf.py diff --git a/plugins/pyloader/src/builtin-policies/fcfs.py b/plugins/pyloader/src/builtin-policies/fcfs.py index 0e58f0b..04ed582 100644 --- a/plugins/pyloader/src/builtin-policies/fcfs.py +++ b/plugins/pyloader/src/builtin-policies/fcfs.py @@ -20,17 +20,19 @@ from CPUPolicy import CPUPolicy -import sys -#from sgpem import policy_sorts_processes class fcfs(CPUPolicy) : - """First Come First Served""" + """First Come First Served scheduling policy. + +The first thread to arrive to the CPU will run until +it ends. This policy never pre-empts; it is probably +the simplest of them all.""" def __init__(self): pass; def configure(self): - print 'No options to configure for fcfs' + pass; def is_preemptive(self): return False diff --git a/plugins/pyloader/src/builtin-policies/lottery.py b/plugins/pyloader/src/builtin-policies/lottery.py new file mode 100644 index 0000000..b9ed3ef --- /dev/null +++ b/plugins/pyloader/src/builtin-policies/lottery.py @@ -0,0 +1,48 @@ +# src/builtin-policies/lottery.py - 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 + + +from CPUPolicy import CPUPolicy +from random import randint + +class lottery(CPUPolicy) : + """Lottery scheduling + +Every time slice, a thread will be selected from the ready +queue by random. This policy does not pre-empt before the +end of the time slice.""" + + def __init__(self): + pass; + + def configure(self): + param = self.get_parameters() + param.register_int("Time slice", 1, 10000, True, 2) + + def is_preemptive(self): + return False + + def get_time_slice(self): + return self.get_parameters().get_int("Time slice") + + def sort_queue(self, queue): + sz = queue.size() + if(sz > 0): + queue.swap(0, randint(0, sz - 1)) diff --git a/plugins/pyloader/src/builtin-policies/rr.py b/plugins/pyloader/src/builtin-policies/rr.py new file mode 100644 index 0000000..a4523cc --- /dev/null +++ b/plugins/pyloader/src/builtin-policies/rr.py @@ -0,0 +1,50 @@ +# src/builtin-policies/rr_priority.py - 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 + + +from CPUPolicy import CPUPolicy + +class rr(CPUPolicy) : + """Round Robin scheduling policy + +This policy executes a thread for a given amount +of time (the time-slice value), and then puts it +at the end of the queue. Does not pre-empt before +the end of the time slice, since it doesn't take +priority in account. Use rr_priority for that.""" + + def __init__(self): + pass; + + def configure(self): + param = self.get_parameters() + param.register_int("Time slice", 1, 10000, True, 2) + + def is_preemptive(self): + return False + + def get_time_slice(self): + return self.get_parameters().get_int("Time slice") + + def sort_queue(self, queue): + by_ltime = lambda a, b: \ + a.get_last_acquisition() > \ + b.get_last_acquisition() + self.sort(queue,by_ltime) diff --git a/plugins/pyloader/src/builtin-policies/rr_priority.py b/plugins/pyloader/src/builtin-policies/rr_priority.py index e1d11ac..ab1413b 100644 --- a/plugins/pyloader/src/builtin-policies/rr_priority.py +++ b/plugins/pyloader/src/builtin-policies/rr_priority.py @@ -20,9 +20,16 @@ from CPUPolicy import CPUPolicy -import sys class rr_priority(CPUPolicy) : + """Round Robin scheduling policy that takes priority in account. + +No lower priority thread can run if a higher +priority thread exists. If pre-emptive by priority, a +higher-priority thread becoming ready even in the middle +of a time slice will pre-empt the running thread. Else, +the time slice will have to end before the former can run.""" + def __init__(self): pass; @@ -38,7 +45,6 @@ class rr_priority(CPUPolicy) : else: return True - # FIXME pass to a configurable amount def get_time_slice(self): return self.get_parameters().get_int("Time slice") diff --git a/plugins/pyloader/src/builtin-policies/sjf.py b/plugins/pyloader/src/builtin-policies/sjf.py index d26991b..b9e8a68 100644 --- a/plugins/pyloader/src/builtin-policies/sjf.py +++ b/plugins/pyloader/src/builtin-policies/sjf.py @@ -20,18 +20,30 @@ from CPUPolicy import CPUPolicy -import sys -#from sgpem import policy_sorts_processes class sjf(CPUPolicy) : + """Shortest Job First scheduling policy + +The thread with the shortest required CPU time +will run until it ends. If pre-emptive is set +to true, if a shorter thread arrives at the CPU +at a given moment, it will pre-empt the running +one. The policy is also called Shortest Remaining +Time Next in this case.""" + def __init__(self): pass; def configure(self): - print 'No options to configure for fcfs' + params = self.get_parameters() + params.register_int("Is preemptive?", 0, 1, True, 0) def is_preemptive(self): - return False + value = self.get_parameters().get_int("Is preemptive?") + if value == 0: + return False + else: + return True def get_time_slice(self): return -1 diff --git a/plugins/pyloader/src/python_cpu_policy.cc b/plugins/pyloader/src/python_cpu_policy.cc index 2608920..40e9d5f 100644 --- a/plugins/pyloader/src/python_cpu_policy.cc +++ b/plugins/pyloader/src/python_cpu_policy.cc @@ -61,7 +61,9 @@ PythonCPUPolicy::PythonCPUPolicy(const char* name) throw(MalformedPolicyExceptio // Now takes the user-defined policy class from pUserCPUPolicyDict PyObject* pCPUPolicyClass = PyDict_GetItemString(_upolicy_dict, name); - assert(pCPUPolicyClass); // FIXME needs stricter checking and exception throwing + if (pCPUPolicyClass == NULL) + throw MalformedPolicyException(Glib::ustring(_("Cannot find a class named ")) + + name + _(" into the corresponding .py file.")); // Retrieve a description for the policy using the __doc__ attribute PyObject* pDescriptionString = PyObject_GetAttrString(pCPUPolicyClass, "__doc__"); diff --git a/src/gui_builder.cc b/src/gui_builder.cc index 0961b27..f0ed047 100644 --- a/src/gui_builder.cc +++ b/src/gui_builder.cc @@ -610,8 +610,8 @@ SimulationController::run_simulation_adaptor() catch(const MalformedPolicyException& mpe) { // Show user a dialog - MessageDialog diag(_("The selected user CPU policy was malformed and didn't run:\n") + Markup::escape_text(mpe.what()), - true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + MessageDialog diag(_("The selected user CPU policy was malformed and failed to sort the queue:\n") + + Markup::escape_text(mpe.what()), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); diag.run(); try