- Rename Policy to CPUPolicy where appropriate
git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@811 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
5b577c5979
commit
43b817aaed
31 changed files with 222 additions and 225 deletions
186
plugins/pyloader/src/CPUPolicy.py
Normal file
186
plugins/pyloader/src/CPUPolicy.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
from Abstract import *
|
||||
import sgpem
|
||||
|
||||
## @brief This is the abstract class a user-defined policy
|
||||
# should inherit from
|
||||
#
|
||||
# This class also exposes the method sort(), which can be
|
||||
# used to easily sort the queue of ready process with a
|
||||
# user-defined given compare function.
|
||||
class CPUPolicy:
|
||||
## @var Avoid instantiation of an abstract class.
|
||||
# @see Abstract.Metaclass
|
||||
__metaclass__ = Metaclass
|
||||
|
||||
## @brief Configure policy to initial values
|
||||
#
|
||||
# This is called just before a simulation starts, and is responsible
|
||||
# to define the parameters the policy wants to expose to the user.
|
||||
# For example, it may make the return value of is_preemptive configurable,
|
||||
# or register an integer value for a the time slice duration.
|
||||
#
|
||||
# Should be implemented with signature:
|
||||
# @code
|
||||
# def configure(self):
|
||||
# # function body
|
||||
# @endcode
|
||||
#
|
||||
# @see sgpem::Policy::get_parameters()
|
||||
configure = AbstractMethod('configure')
|
||||
|
||||
## @brief Sort ready processes queue
|
||||
#
|
||||
# This method is called by the scheduler at each
|
||||
# step of the simulation to sort the ready
|
||||
# processes queue.
|
||||
#
|
||||
# Should be implemented with signature:
|
||||
# @code
|
||||
# def sort_queue(self, queue):
|
||||
# # function body
|
||||
# @endcode
|
||||
#
|
||||
# @param queue The sgpem::ReadyQueue to be sorted.
|
||||
# Only some methods of it are implemented,
|
||||
# notably get_item_at(position),
|
||||
# swap(positionA, positionB) and size().
|
||||
#
|
||||
# @see Policy::Policy::sort()
|
||||
sort_queue = AbstractMethod('sort_queue')
|
||||
|
||||
## @brief Returns whether the policy wants to be preemptive,
|
||||
# other than by normal time slice termination
|
||||
#
|
||||
# See the return value for a complete explanation. Please
|
||||
# note how the word ``priority'' here has a general meaning:
|
||||
# it indicates every process than can bubble up the sorted
|
||||
# ready queue and come before another. So it's up to
|
||||
# Policy.sort_queue() to give it a precise meaning.
|
||||
#
|
||||
# Should be implemented with signature:
|
||||
# @code
|
||||
# def is_preemptive(self):
|
||||
# # function body
|
||||
# @endcode
|
||||
#
|
||||
# @return True If the policy declares it wants the running
|
||||
# process to be released if a process at higher priority
|
||||
# is put at the beginning of the ready processes queue
|
||||
# @return False If the policy always waits the end of the time
|
||||
# slice (or a process blocking/termination, of course) before
|
||||
# selecting a new running process, even if it has greater priority
|
||||
# than the current one
|
||||
is_preemptive = AbstractMethod('is_preemptive')
|
||||
|
||||
## @brief Returns how long is a time-slice for this policy
|
||||
#
|
||||
# A time sliced policy should return a positive integer value,
|
||||
# a policy which doesn't use slices should instead return -1.
|
||||
# You're encouraged to use a user-configurable parameter via
|
||||
# Policy.configure() if the policy is time-sliced, to ensure
|
||||
# greater flexibility.
|
||||
#
|
||||
# Should be implemented with signature:
|
||||
# @code
|
||||
# def get_time_slice(self):
|
||||
# # function body
|
||||
# @endcode
|
||||
#
|
||||
# FIXME: what happens for ``return 0''? The same as ``return 1''?
|
||||
#
|
||||
# @return -1 If the policy doesn't want to use time slices
|
||||
# @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()
|
||||
#
|
||||
# @return A sgpem::PolicyParameters instance
|
||||
def get_parameters(self):
|
||||
return sgpem.Scheduler.get_instance().get_policy().get_parameters()
|
||||
|
||||
|
||||
## @brief This function implements an in-place stable sort
|
||||
# using directly ReadyQueue methods
|
||||
#
|
||||
# The compare parameter should be a user defined binary
|
||||
# function returning either True or False, defined in one
|
||||
# of the following ways:
|
||||
# @code
|
||||
# # As a lambda anonymous function (preferred)
|
||||
# # (x and y are two DynamicSchedulable objects)
|
||||
# cmpf = lambda x,y: x.someProperty() < y.someProperty()
|
||||
#
|
||||
# # As a normal *global* function
|
||||
# def compare(a,b):
|
||||
# return a.someProperty < b.someProperty()
|
||||
# cmpf = compare
|
||||
# @endcode
|
||||
#
|
||||
# The call is then simply:
|
||||
# @code
|
||||
# def sort_queue() :
|
||||
# # ...
|
||||
# self.sort(queue, cmpf)
|
||||
# @endcode
|
||||
#
|
||||
# @param self The object caller
|
||||
# @param queue The ReadyQueue to be sorted in place
|
||||
# @param cmpf The binary function to use to compare elements
|
||||
# @returns None
|
||||
def sort(self, queue, cmpf):
|
||||
self.__recursive_qsort(queue, 0, queue.size()-1, cmpf)
|
||||
|
||||
|
||||
## @brief Recursive (private) call to perform quicksort on a
|
||||
# queue
|
||||
#
|
||||
# @param queue The queue to sort
|
||||
# @param a The initial element position of the slice
|
||||
# @param b The final element position of the slice
|
||||
# @param cmpf The user-defined compare function to employ
|
||||
# @returns None
|
||||
def __recursive_qsort(self, queue, a, b, cmpf):
|
||||
if(b>a):
|
||||
pivot = self.__partition(queue, a, b, cmpf)
|
||||
self.__recursive_qsort(queue, a, pivot-1, cmpf)
|
||||
self.__recursive_qsort(queue, pivot+1, b, cmpf)
|
||||
|
||||
|
||||
## @brief Recursive (private) call to partition a slice of the queue
|
||||
#
|
||||
# This private function (the name mangling should work)
|
||||
# naively sorts a partition of queue in place using just
|
||||
# its methods.
|
||||
#
|
||||
# Feel the love.
|
||||
#
|
||||
# @param queue The ReadyQueue to sort
|
||||
# @param a The partition starting element position in the queue
|
||||
# @param b The partition ending element position in the queue
|
||||
# @param cmpf The binary function to use for comparing two elements
|
||||
# @return The new pivot index
|
||||
def __partition(self, queue, a, b, cmpf):
|
||||
# takes pivot element:
|
||||
right = queue.get_item_at(b)
|
||||
i = a
|
||||
for j in range(a,b): # goes from a to b-1
|
||||
if cmpf(queue.get_item_at(j), right):
|
||||
# the C++ code should do nothing if i == j:
|
||||
queue.swap(i,j)
|
||||
i = i+1
|
||||
# puts pivot in place
|
||||
queue.swap(i,b)
|
||||
return i
|
Loading…
Add table
Add a link
Reference in a new issue