- Merged branch 0.3-r556--SPLIT_PYLOADER_CONFIG back into trunk
git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@561 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
c6d4f5fd27
commit
51f0d7fbe7
36 changed files with 849 additions and 48 deletions
10
plugins/pyloader/AUTHORS
Normal file
10
plugins/pyloader/AUTHORS
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
Authors of SGPEMv2
|
||||
|
||||
Giovanni Giacobbi <ggiacobb@studenti.math.unipd.it>
|
||||
Filippo Paparella <ironpipp@gmail.com>
|
||||
Paolo Santi <psanti@studenti.math.unipd.it>
|
||||
Matteo Settenvini <matteo@member.fsf.org>
|
||||
Marco Trevisan <mtrevisa@studenti.math.unipd.it>
|
||||
Djina Verbanac <betalgez@yahoo.com>
|
||||
Luca Vezzaro <lvezzaro@studenti.math.unipd.it>
|
96
plugins/pyloader/Abstract.py
Normal file
96
plugins/pyloader/Abstract.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
## @brief Defines a class to create abstract methods
|
||||
#
|
||||
# @author Ivo Timmermans
|
||||
# @date 2004/01/23
|
||||
# @version 1.1
|
||||
#
|
||||
# Example:
|
||||
# @code
|
||||
# import Abstract;
|
||||
# class Foo:
|
||||
# __metaclass__ = Abstract.Metaclass
|
||||
# foo = Abstract.AbstractMethod('foo')
|
||||
# @endcode
|
||||
class AbstractMethod (object):
|
||||
## @brief Constructor
|
||||
#
|
||||
# @param func name of the function (used when raising an
|
||||
# exception). Its type is str.
|
||||
def __init__(self, func):
|
||||
self._function = func
|
||||
|
||||
## @brief Get callable object
|
||||
#
|
||||
# @return An instance of AbstractMethodHelper.
|
||||
# This trickery is needed to get the name of the class for which
|
||||
# an abstract method was requested, otherwise it would be
|
||||
# sufficient to include a __call__ method in the AbstractMethod
|
||||
# class itself.
|
||||
def __get__(self, obj, type):
|
||||
return self.AbstractMethodHelper(self._function, type)
|
||||
|
||||
## @brief Abstract method helper class
|
||||
#
|
||||
# An AbstractMethodHelper instance is a callable object that
|
||||
# represents an abstract method.
|
||||
class AbstractMethodHelper (object):
|
||||
def __init__(self, func, cls):
|
||||
self._function = func
|
||||
self._class = cls
|
||||
|
||||
## @brief Call abstract method
|
||||
#
|
||||
# Raises a TypeError, because abstract methods can not be
|
||||
# called.
|
||||
def __call__(self, *args, **kwargs):
|
||||
raise TypeError('Abstract method `' + self._class.__name__ \
|
||||
+ '.' + self._function + '\' called')
|
||||
|
||||
## @brief Configure a new class to be abstract
|
||||
#
|
||||
# @author Ivo Timmermans
|
||||
# @date 2004/01/23
|
||||
# @version 1.1
|
||||
class Metaclass (type):
|
||||
## Configure a new class
|
||||
#
|
||||
# @param cls Class object
|
||||
# @param name Name of the class
|
||||
# @param bases All base classes for cls
|
||||
def __init__(cls, name, bases, *args, **kwargs):
|
||||
super(Metaclass, cls).__init__(cls, name, bases, *args, **kwargs)
|
||||
|
||||
# Detach cls.new() from class Metaclass, and make it a method
|
||||
# of cls.
|
||||
cls.__new__ = staticmethod(cls.new)
|
||||
|
||||
# Find all abstract methods, and assign the resulting list to
|
||||
# cls.__abstractmethods__, so we can read that variable when a
|
||||
# request for allocation (__new__) is done.
|
||||
abstractmethods = []
|
||||
ancestors = list(cls.__mro__)
|
||||
ancestors.reverse() # Start with __builtin__.object
|
||||
for ancestor in ancestors:
|
||||
for clsname, clst in ancestor.__dict__.items():
|
||||
if isinstance(clst, AbstractMethod):
|
||||
abstractmethods.append(clsname)
|
||||
else:
|
||||
if clsname in abstractmethods:
|
||||
abstractmethods.remove(clsname)
|
||||
|
||||
abstractmethods.sort()
|
||||
setattr(cls, '__abstractmethods__', abstractmethods)
|
||||
|
||||
## @brief Allocator for class cls
|
||||
#
|
||||
# @param self Class object for which an instance should be
|
||||
# created.
|
||||
# @param cls Same as self.
|
||||
def new(self, cls):
|
||||
if len(cls.__abstractmethods__):
|
||||
raise NotImplementedError('Can\'t instantiate class `' + \
|
||||
cls.__name__ + '\';\n' + \
|
||||
'Abstract methods: ' + \
|
||||
", ".join(cls.__abstractmethods__))
|
||||
|
||||
return object.__new__(self)
|
196
plugins/pyloader/Makefile.am
Normal file
196
plugins/pyloader/Makefile.am
Normal file
|
@ -0,0 +1,196 @@
|
|||
# Makefile.am - 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
|
||||
|
||||
|
||||
# extra calls
|
||||
.PHONY : apidox
|
||||
|
||||
# this should be the only recursive call
|
||||
SUBDIRS = po
|
||||
|
||||
# directories definition
|
||||
localedir = @datadir@/locale
|
||||
plugindir = $(SGPEMV2_PLUGINS_DIR)
|
||||
sharedir = $(plugindir)/extras/pyloader
|
||||
policiesdir = $(SGPEMV2_POLICIES_DIR)
|
||||
|
||||
#define empty global variables
|
||||
plugin_LTLIBRARIES =
|
||||
noinst_HEADERS =
|
||||
noinst_PYTHON =
|
||||
EXTRA_DIST =
|
||||
MAINTAINERCLEANFILES =
|
||||
MOSTLYCLEANFILES =
|
||||
CLEANFILES =
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# extra dist, cleanup and automake/aclocal flags
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
macros = m4/compilerflags.m4 \
|
||||
m4/linkingflags.m4 \
|
||||
m4/sgpemv2-dirs.m4
|
||||
|
||||
EXTRA_DIST += \
|
||||
config/config.rpath \
|
||||
config/mkinstalldirs \
|
||||
configure.ac \
|
||||
gettext.h \
|
||||
$(macros)
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# source : libpyloader.la
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
plugin_LTLIBRARIES += libpyloader.la
|
||||
|
||||
libpyloader_la_CPPFLAGS = \
|
||||
-I@top_srcdir@ \
|
||||
-DSHAREDIR="\"$(sharedir)\"" \
|
||||
-DLOCALEDIR="\"$(localedir)\"" \
|
||||
$(PYTHON_CPPFLAGS) \
|
||||
$(GLIBMM_CFLAGS) \
|
||||
$(SGPEMV2_CFLAGS)
|
||||
libpyloader_la_CXXFLAGS = \
|
||||
$(VISIB_HIDDEN)
|
||||
libpyloader_la_LIBADD = \
|
||||
$(PYTHON_LDFLAGS) \
|
||||
$(PYTHON_EXTRA_LIBS) \
|
||||
$(GLIBMM_LIBS) \
|
||||
$(SGPEMV2_LIBS)
|
||||
libpyloader_la_LDFLAGS = \
|
||||
$(PYTHON_EXTRA_LDFLAGS) \
|
||||
$(LT_LDFLAGS) \
|
||||
-version-info 0:0:0 \
|
||||
-module
|
||||
|
||||
# Please keep this in sorted order:
|
||||
libpyloader_la_SOURCES = \
|
||||
python_policy.cc \
|
||||
python_policy_manager.cc \
|
||||
hook.cc
|
||||
|
||||
noinst_HEADERS += \
|
||||
python_policy.hh \
|
||||
python_policy_manager.hh
|
||||
|
||||
share_PYTHON = \
|
||||
Abstract.py \
|
||||
Policy.py \
|
||||
ScriptAdapter.py
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# C++ modules -> Python loadable modules
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
proxies = sgpem.py
|
||||
wrappers = sgpem_wrap.cc
|
||||
|
||||
share_LTLIBRARIES = _sgpem.la
|
||||
share_PYTHON += $(proxies)
|
||||
|
||||
# static pattern rule
|
||||
$(proxies) $(wrappers) : sgpem.i
|
||||
test -d "$(@D)" || mkdir -p -- "$(@D)"
|
||||
$(SWIG) $(SWIG_PYTHON_OPT) -o $@ $<
|
||||
|
||||
_sgpem_la_INTERFACES = sgpem.i
|
||||
|
||||
_sgpem_la_CPPFLAGS = \
|
||||
-I@top_srcdir@ \
|
||||
$(SWIG_PYTHON_CPPFLAGS) \
|
||||
$(GLIBMM_CFLAGS) \
|
||||
$(SGPEMV2_CFLAGS)
|
||||
_sgpem_la_LDFLAGS = -module -export-dynamic \
|
||||
$(GLIBMM_LDFLAGS)
|
||||
_sgpem_la_LIBADD = $(SGPEMV2_LIBS) \
|
||||
$(GLIBMM_LIBS)
|
||||
_sgpem_la_SOURCES = $(wrappers)
|
||||
|
||||
EXTRA_DIST += $(_sgpem_la_INTERFACES)
|
||||
MOSTLYCLEANFILES += $(proxies) $(wrappers)
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# source : builtin-policies
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
# built-in policies
|
||||
policies_PYTHON = \
|
||||
builtin-policies/fcfs.py \
|
||||
builtin-policies/sjf.py
|
||||
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# check : testsuite
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
if COND_TESTS
|
||||
|
||||
# DEJATOOL = src/testsuite/example-test.exp
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
testsuite/test-pyloader
|
||||
|
||||
testsuite_test_pyloader_CPPFLAGS = \
|
||||
-I@top_srcdir@ \
|
||||
-DSHAREDIR="\"$(sharedir)\"" \
|
||||
$(PYTHON_CPPFLAGS) \
|
||||
$(GLIBMM_CFLAGS) \
|
||||
$(GTHREAD_CFLAGS) \
|
||||
$(SGPEMV2_CFLAGS)
|
||||
testsuite_test_pyloader_DEPENDENCIES = \
|
||||
libpyloader.la
|
||||
testsuite_test_pyloader_LDFLAGS = \
|
||||
$(SGPEMV2_LIBS) \
|
||||
$(GLIBMM_LIBS) \
|
||||
$(GTHREAD_LIBS) \
|
||||
$(PYTHON_LDFLAGS) \
|
||||
$(PYTHON_EXTRA_LIBS) \
|
||||
$(PYTHON_EXTRA_LDFLAGS)
|
||||
testsuite_test_pyloader_SOURCES = \
|
||||
testsuite/test-python_loader.cc \
|
||||
python_policy.cc \
|
||||
python_policy_manager.cc
|
||||
|
||||
noinst_PYTHON += testsuite/python_loader_configure.py \
|
||||
testsuite/python_loader_sort_queue.py \
|
||||
testsuite/python_loader_is_preemptive.py \
|
||||
testsuite/python_loader_get_time_slice.py
|
||||
|
||||
|
||||
# Workaround an automake bug that leaves behind some files
|
||||
# while it's finishing the distcheck target
|
||||
CLEANFILES += \
|
||||
testsuite/.libs/test-pyloader
|
||||
|
||||
endif #~ if COND_TESTS
|
||||
|
0
plugins/pyloader/NEWS
Normal file
0
plugins/pyloader/NEWS
Normal file
178
plugins/pyloader/Policy.py
Normal file
178
plugins/pyloader/Policy.py
Normal file
|
@ -0,0 +1,178 @@
|
|||
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 Policy:
|
||||
## @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, event, queue):
|
||||
# # function body
|
||||
# @endcode
|
||||
#
|
||||
# @param event Enumeration value of type Scheduler::Event,
|
||||
# needed by some policies to know the reason of
|
||||
# the call
|
||||
# @param queue The sgpem::SchedulableQueue 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 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 SchedulableQueue 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 SchedulableStatus 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 SchedulableQueue 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 SchedulableQueue 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
|
0
plugins/pyloader/README
Normal file
0
plugins/pyloader/README
Normal file
109
plugins/pyloader/ScriptAdapter.py
Normal file
109
plugins/pyloader/ScriptAdapter.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
import mutex, thread
|
||||
import sgpem
|
||||
|
||||
## @brief This is an adapter class which acts as a proxy
|
||||
# for user-implemented policies
|
||||
#
|
||||
# At runtime, this class will be initialized with the
|
||||
# user-implemented policy, and then it will proxy the calls
|
||||
# the policy member functions on a different thread, so
|
||||
# to ensure asyncronous control.
|
||||
#
|
||||
# Instantiated in the C++ code, it is created like:
|
||||
# @code
|
||||
# adapter = ScriptAdapter(UserPolicyClass)
|
||||
# @endcode
|
||||
#
|
||||
# The user shouldn't care about this class at all.
|
||||
class ScriptAdapter :
|
||||
## @var The policy this ScriptAdapter will use for calls
|
||||
_policy = None
|
||||
|
||||
## @var The event to pass to Policy.sort_queue() after the asynchronous call
|
||||
_event = None
|
||||
|
||||
## @var Synchronized return value you can read from C++
|
||||
# when a threaded function returns
|
||||
_ret_val = None
|
||||
|
||||
## Var Testable syncronization object
|
||||
_g_mutex = mutex.mutex()
|
||||
|
||||
## @brief Constructor of ScriptAdapter
|
||||
#
|
||||
# @param self The caller object
|
||||
# @param policy A user-implemented class inheriting from Policy.Policy
|
||||
def __init__(self, policy):
|
||||
self._policy = policy()
|
||||
print 'ScriptAdapter for policy ', policy, ' loaded'
|
||||
|
||||
|
||||
## @brief Asynchronously call Policy.configure()
|
||||
#
|
||||
# @param self The caller object
|
||||
def async_configure(self):
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_configure, self )
|
||||
|
||||
def _wrap_configure(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,))
|
||||
|
||||
def _wrap_configure_callback(self):
|
||||
# call configure method
|
||||
self._policy.configure()
|
||||
self._g_mutex.unlock()
|
||||
|
||||
|
||||
## @brief Asynchronously call Policy.sort_queue()
|
||||
#
|
||||
# The queue is asked directly to the C++ sgpem::Scheduler
|
||||
# singleton, via SWIG
|
||||
#
|
||||
# @param self The caller object
|
||||
# @param event The event to pass to sort_queue
|
||||
def async_sort_queue(self, event):
|
||||
self._event = event
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_sort_queue, self)
|
||||
|
||||
def _wrap_sort_queue(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_sort_queue_callback,
|
||||
(self,self._event))
|
||||
|
||||
def _wrap_sort_queue_callback(self, event):
|
||||
# here we retrieve and pass the ready queue
|
||||
queue = sgpem.Scheduler.get_instance().get_ready_queue()
|
||||
self._policy.sort_queue(event, queue)
|
||||
self._g_mutex.unlock()
|
||||
|
||||
|
||||
## @brief Asynchronously call Policy.is_preemptive()
|
||||
#
|
||||
# @param self The caller object
|
||||
def async_is_preemptive(self):
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_is_preemptive, self)
|
||||
|
||||
def _wrap_is_preemptive(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_is_preemptive_callback, (self,))
|
||||
|
||||
def _wrap_is_preemptive_callback(self):
|
||||
self._ret_val = self._policy.is_preemptive()
|
||||
self._g_mutex.unlock()
|
||||
|
||||
## @brief Asynchronously call Policy.get_time_slice()
|
||||
#
|
||||
# @param self The caller object
|
||||
def async_get_time_slice(self):
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self)
|
||||
|
||||
def _wrap_get_time_slice(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,))
|
||||
|
||||
def _wrap_get_time_slice_callback(self):
|
||||
self._ret_val = self._policy.get_time_slice()
|
||||
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
|
||||
|
||||
def mutex_test_lock(self):
|
||||
return self._g_mutex.test()
|
42
plugins/pyloader/builtin-policies/fcfs.py
Normal file
42
plugins/pyloader/builtin-policies/fcfs.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
# src/builtin-policies/fcfs.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 Policy import Policy
|
||||
import sys
|
||||
|
||||
class fcfs(Policy) :
|
||||
def __init__(self):
|
||||
pass;
|
||||
|
||||
def configure(self):
|
||||
print 'No options to configure for fcfs'
|
||||
|
||||
def is_preemptive(self):
|
||||
return False
|
||||
|
||||
def get_time_slice(self):
|
||||
return -2
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
cmpf = lambda a, b: \
|
||||
a.get_schedulable().get_arrival_time() < \
|
||||
b.get_schedulable().get_arrival_time()
|
||||
self.sort(queue,cmpf)
|
42
plugins/pyloader/builtin-policies/sjf.py
Normal file
42
plugins/pyloader/builtin-policies/sjf.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
# src/builtin-policies/sjf.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 Policy import Policy
|
||||
import sys
|
||||
|
||||
class sjf(Policy) :
|
||||
def __init__(self):
|
||||
pass;
|
||||
|
||||
def configure(self):
|
||||
print 'No options to configure for fcfs'
|
||||
|
||||
def is_preemptive(self):
|
||||
return False
|
||||
|
||||
def get_time_slice(self):
|
||||
return -1
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
cmpf = lambda a, b: \
|
||||
a.get_cpu_time_left() < \
|
||||
b.get_cpu_time_left()
|
||||
self.sort(queue,cmpf)
|
160
plugins/pyloader/configure.ac
Normal file
160
plugins/pyloader/configure.ac
Normal file
|
@ -0,0 +1,160 @@
|
|||
# configure.ac - Copyright 2005, 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
|
||||
|
||||
dnl ----------------- CONFIGURE ---------------------
|
||||
|
||||
AC_INIT([sgpemv2-pyloader],[0.1],[matteo@member.fsf.org])
|
||||
|
||||
if test -f "`pwd`/configure.ac"; then
|
||||
AC_MSG_FAILURE([
|
||||
** This seems to be the pkg root directory.
|
||||
** Compiling here your sources is considered
|
||||
** as unpolite as exploring your nose with
|
||||
** your pinky whilst attending a wedding party.
|
||||
** Please create a new dir as described in
|
||||
** the README file, and then run configure
|
||||
** into it. If you think you've got it right,
|
||||
** please inform the mantainer of this error!
|
||||
** He'll thoroughfully bash his head on the wall.],
|
||||
-1 )
|
||||
fi
|
||||
|
||||
AC_GNU_SOURCE
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
dnl starting automake
|
||||
AM_INIT_AUTOMAKE([dejagnu dist-bzip2])
|
||||
|
||||
dnl gettext & libtool
|
||||
AC_ARG_VAR([LT_LDFLAGS],
|
||||
[You can use this variable to pass an option
|
||||
to libtool when it is in linking mode (for
|
||||
example, "-all-static")])
|
||||
AC_PROG_LIBTOOL
|
||||
AM_GNU_GETTEXT([external])
|
||||
AM_GNU_GETTEXT_VERSION([0.14.1])
|
||||
|
||||
dnl PYTHON_VERSION is declared precious by AC_PYTHON_DEVEL,
|
||||
dnl so don't use it here
|
||||
PY_VERSION=2.3
|
||||
GTKMM_VERSION=2.8.0
|
||||
SGPEMV2_VERSION=0.1
|
||||
|
||||
dnl c++ compiler and flags
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_CXXFLAG([CXXFLAGS], [Wall])
|
||||
AC_CHECK_CXXFLAG([CXXFLAGS], [pedantic])
|
||||
AC_CHECK_CXXFLAG([CXXFLAGS], [Wextra])
|
||||
AC_CHECK_CXXFLAG([CXXFLAGS], [Wno-long-long])
|
||||
AC_CHECK_LDFLAG([LDFLAGS], [--as-needed])
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
dnl make
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
dnl check for python and SWIG
|
||||
AC_PYTHON_DEVEL([>= '$PY_VERSION'])
|
||||
AC_PROG_SWIG
|
||||
SWIG_ENABLE_CXX
|
||||
SWIG_PYTHON
|
||||
|
||||
dnl add pkg-config search path for sgpemv2-uninstalled.pc
|
||||
dnl if we're building in a subdir of that pkg
|
||||
_old_pkg_path=$[]PKG@&t@_CONFIG_PATH
|
||||
if test -f "../../config/sgpemv2-uninstalled.pc"; then
|
||||
export PKG_@&t@CONFIG_PATH="../../config:$PKG_CONFIG_PATH"
|
||||
fi
|
||||
|
||||
dnl check for sgpemv2!
|
||||
AC_PROG_SGPEMV2([$SGPEMV2_VERSION])
|
||||
|
||||
dnl revert from old var
|
||||
if test "x$_old_pkg_path" = "x"; then
|
||||
unset -v PKG@&t@_CONFIG_PATH
|
||||
else
|
||||
export PKG@&t@_CONFIG_PATH="$_old_pkg_path"
|
||||
fi
|
||||
|
||||
dnl check for glib & cairo
|
||||
PKG_CHECK_MODULES([GTHREAD],
|
||||
[gthread-2.0 >= $GTKMM_VERSION],
|
||||
:, AC_MSG_ERROR([$GTHREAD_PKG_ERRORS]))
|
||||
PKG_CHECK_MODULES([GLIBMM],
|
||||
[glibmm-2.4 >= $GTKMM_VERSION],
|
||||
:, AC_MSG_ERROR([$GLIBMM_PKG_ERRORS]))
|
||||
|
||||
dnl use DSO visibility tags for systems that supports it correctly
|
||||
dnl (for example, GCC 4.0 and above)
|
||||
dnl see http://gcc.gnu.org/wiki/Visibility for more informations
|
||||
AH_TEMPLATE([SG_DLLEXPORT],[Attribute for objects to be exported from DSOs])
|
||||
AH_TEMPLATE([SG_DLLIMPORT],[Attribute for objects to be imported from DSOs])
|
||||
AH_TEMPLATE([SG_DLLLOCAL], [Attribute for objects local to current DSO])
|
||||
AH_TEMPLATE([SG_DLLPUBLIC],[Attribute for DSO public objects])
|
||||
|
||||
dnl for now it works only with GCC >= 4.0.0
|
||||
AC_MSG_CHECKING([whether GCC supports DSO visibility attributes])
|
||||
AC_LANG_PUSH([C++])
|
||||
AC_COMPILE_IFELSE(
|
||||
AC_LANG_PROGRAM([], [
|
||||
#if defined __GNUC__ && (__GNUC__) >= 4
|
||||
return 0;
|
||||
#else
|
||||
bails out with a compilation error.
|
||||
#endif
|
||||
]),[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([SG_DLLIMPORT],[/* intentionally left with no value */])
|
||||
AC_DEFINE([SG_DLLEXPORT],[__attribute__ ((visibility("default")))])
|
||||
AC_DEFINE([SG_DLLLOCAL],[__attribute__ ((visibility("hidden")))])
|
||||
AC_DEFINE([SG_DLLPUBLIC],[__attribute__ ((visibility("default")))])
|
||||
|
||||
AC_CHECK_CXXFLAG([VISIB_HIDDEN], [fvisibility=hidden])
|
||||
AC_SUBST([VISIB_HIDDEN])
|
||||
AC_CHECK_CXXFLAG([CXXFLAGS],[fvisibility-inlines-hidden])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([SG_DLLIMPORT],[/* unsupported */])
|
||||
AC_DEFINE([SG_DLLEXPORT],[/* unsupported */])
|
||||
AC_DEFINE([SG_DLLLOCAL],[/* unsupported */])
|
||||
AC_DEFINE([SG_DLLPUBLIC],[/* unsupported */])
|
||||
])
|
||||
AC_LANG_POP
|
||||
|
||||
dnl see if we've to compile tests
|
||||
AC_MSG_CHECKING([whether tests have to be built])
|
||||
AC_ARG_ENABLE([tests],
|
||||
AS_HELP_STRING([--disable-tests],
|
||||
[don't compile the tests provided with sgpemv2]),
|
||||
[compile_tests="$enableval"],
|
||||
[compile_tests="yes"])
|
||||
AC_MSG_RESULT([$compile_tests])
|
||||
AM_CONDITIONAL([COND_TESTS], [test "$compile_tests" = "yes"])
|
||||
|
||||
dnl output files
|
||||
AC_CONFIG_HEADERS([config.h:config.h.in])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
po/Makefile.in
|
||||
])
|
||||
AC_OUTPUT
|
83
plugins/pyloader/gettext.h
Normal file
83
plugins/pyloader/gettext.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||
Copyright (C) 1995-1998, 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
#ifndef _LIBGETTEXT_H
|
||||
#define _LIBGETTEXT_H 1
|
||||
|
||||
/* NLS can be disabled through the configure --disable-nls option. */
|
||||
#if ENABLE_NLS
|
||||
|
||||
/* Get declarations of GNU message catalog functions. */
|
||||
# include <libintl.h>
|
||||
|
||||
#else
|
||||
|
||||
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
||||
chokes if dcgettext is defined as a macro. So include it now, to make
|
||||
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
|
||||
as well because people using "gettext.h" will not include <libintl.h>,
|
||||
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
|
||||
is OK. */
|
||||
#if defined(__sun)
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
|
||||
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
|
||||
it now, to make later inclusions of <libintl.h> a NOP. */
|
||||
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
|
||||
# include <cstdlib>
|
||||
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Disabled NLS.
|
||||
The casts to 'const char *' serve the purpose of producing warnings
|
||||
for invalid uses of the value returned from these functions.
|
||||
On pre-ANSI systems without 'const', the config.h file is supposed to
|
||||
contain "#define const". */
|
||||
# define gettext(Msgid) ((const char *) (Msgid))
|
||||
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
|
||||
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
||||
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
|
||||
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
|
||||
|
||||
#endif
|
||||
|
||||
/* A pseudo function call that serves as a marker for the automated
|
||||
extraction of messages, but does not call gettext(). The run-time
|
||||
translation is done at a different place in the code.
|
||||
The argument, String, should be a literal string. Concatenated strings
|
||||
and other string expressions won't work.
|
||||
The macro's expansion is not parenthesized, so that it is suitable as
|
||||
initializer for static 'char[]' or 'const char[]' variables. */
|
||||
#define gettext_noop(String) String
|
||||
|
||||
/* Commodity macros -- added by Matteo Settenvini 2006-01-13 */
|
||||
#define _(x) (gettext(x))
|
||||
#define N_(x) (gettext_noop(x))
|
||||
|
||||
#endif /* _LIBGETTEXT_H */
|
55
plugins/pyloader/hook.cc
Normal file
55
plugins/pyloader/hook.cc
Normal file
|
@ -0,0 +1,55 @@
|
|||
// src/backend/pyloader/hook.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
|
||||
|
||||
// The idea of this file is to provide a static function to execute
|
||||
// when the plugin (this library) is loaded. Thus the name "hook".
|
||||
|
||||
// For the moment, instead of a function hook to be called by the
|
||||
// libbackend.so module, we have a static PythonPolicyManager object.
|
||||
// This is a risk.
|
||||
#warning FIXME : this code is quite a bad idea. Replace me with \
|
||||
a hookable structure, and execute a pointer to function stored \
|
||||
therein. See "info libtool": "dlopened modules"
|
||||
|
||||
#include "python_policy_manager.hh"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SG_CONSTRUCTOR __attribute__ ((constructor))
|
||||
#define SG_DESTRUCTOR __attribute__ ((destructor))
|
||||
#define _libpyloader_LTX__global_pm (_global_pm);
|
||||
|
||||
PolicyManager* _global_pm = NULL;
|
||||
|
||||
void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void)
|
||||
{
|
||||
_global_pm = PythonPolicyManager::get_instance();
|
||||
}
|
||||
|
||||
void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void)
|
||||
{
|
||||
delete _global_pm;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
155
plugins/pyloader/m4/ac_pkg_swig.m4
Normal file
155
plugins/pyloader/m4/ac_pkg_swig.m4
Normal file
|
@ -0,0 +1,155 @@
|
|||
dnl @synopsis AC_PROG_SWIG([major.minor.micro])
|
||||
dnl
|
||||
dnl This macro searches for a SWIG installation on your system. If
|
||||
dnl found you should call SWIG via $(SWIG). You can use the optional
|
||||
dnl first argument to check if the version of the available SWIG is
|
||||
dnl greater than or equal to the value of the argument. It should have
|
||||
dnl the format: N[.N[.N]] (N is a number between 0 and 999. Only the
|
||||
dnl first N is mandatory.)
|
||||
dnl
|
||||
dnl If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks
|
||||
dnl that the swig package is this version number or higher.
|
||||
dnl
|
||||
dnl In configure.in, use as:
|
||||
dnl
|
||||
dnl AC_PROG_SWIG(1.3.17)
|
||||
dnl SWIG_ENABLE_CXX
|
||||
dnl SWIG_MULTI_MODULE_SUPPORT
|
||||
dnl SWIG_PYTHON
|
||||
dnl
|
||||
dnl @category InstalledPackages
|
||||
dnl @author Sebastian Huber <sebastian-huber@web.de>
|
||||
dnl @author Alan W. Irwin <irwin@beluga.phys.uvic.ca>
|
||||
dnl @author Rafael Laboissiere <rafael@laboissiere.net>
|
||||
dnl @author Andrew Collier <abcollier@yahoo.com>
|
||||
dnl @version 2004-09-20
|
||||
dnl @license GPLWithACException
|
||||
|
||||
dnl Matteo Settenvini : changed warnings with errors
|
||||
|
||||
AC_DEFUN([AC_PROG_SWIG],[
|
||||
AC_PATH_PROG([SWIG],[swig])
|
||||
if test -z "$SWIG" ; then
|
||||
AC_MSG_ERROR([cannot find 'swig' program. You should look at http://www.swig.org])
|
||||
elif test -n "$1" ; then
|
||||
AC_MSG_CHECKING([for SWIG version])
|
||||
[swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
|
||||
AC_MSG_RESULT([$swig_version])
|
||||
if test -n "$swig_version" ; then
|
||||
# Calculate the required version number components
|
||||
[required=$1]
|
||||
[required_major=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_major" ; then
|
||||
[required_major=0]
|
||||
fi
|
||||
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
|
||||
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_minor" ; then
|
||||
[required_minor=0]
|
||||
fi
|
||||
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
|
||||
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_patch" ; then
|
||||
[required_patch=0]
|
||||
fi
|
||||
# Calculate the available version number components
|
||||
[available=$swig_version]
|
||||
[available_major=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_major" ; then
|
||||
[available_major=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_minor=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_minor" ; then
|
||||
[available_minor=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_patch=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_patch" ; then
|
||||
[available_patch=0]
|
||||
fi
|
||||
if test $available_major -ne $required_major \
|
||||
-o $available_minor -ne $required_minor \
|
||||
-o $available_patch -lt $required_patch ; then
|
||||
AC_MSG_ERROR([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
|
||||
else
|
||||
AC_MSG_NOTICE([SWIG executable is '$SWIG'])
|
||||
SWIG_LIB=`$SWIG -swiglib`
|
||||
AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB'])
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([cannot determine SWIG version])
|
||||
SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([SWIG_LIB])
|
||||
])
|
||||
|
||||
# SWIG_ENABLE_CXX()
|
||||
#
|
||||
# Enable SWIG C++ support. This affects all invocations of $(SWIG).
|
||||
AC_DEFUN([SWIG_ENABLE_CXX],[
|
||||
AC_REQUIRE([AC_PROG_SWIG])
|
||||
AC_REQUIRE([AC_PROG_CXX])
|
||||
SWIG="$SWIG -c++"
|
||||
])
|
||||
|
||||
# SWIG_MULTI_MODULE_SUPPORT()
|
||||
#
|
||||
# Enable support for multiple modules. This effects all invocations
|
||||
# of $(SWIG). You have to link all generated modules against the
|
||||
# appropriate SWIG runtime library. If you want to build Python
|
||||
# modules for example, use the SWIG_PYTHON() macro and link the
|
||||
# modules against $(SWIG_PYTHON_LIBS).
|
||||
#
|
||||
AC_DEFUN([SWIG_MULTI_MODULE_SUPPORT],[
|
||||
AC_REQUIRE([AC_PROG_SWIG])
|
||||
SWIG="$SWIG -noruntime"
|
||||
])
|
||||
|
||||
# SWIG_PYTHON([use-shadow-classes = {no, yes}])
|
||||
#
|
||||
# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS),
|
||||
# and $(SWIG_PYTHON_OPT) output variables.
|
||||
#
|
||||
# $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate
|
||||
# code for Python. Shadow classes are enabled unless the value of the
|
||||
# optional first argument is exactly 'no'. If you need multi module
|
||||
# support (provided by the SWIG_MULTI_MODULE_SUPPORT() macro) use
|
||||
# $(SWIG_PYTHON_LIBS) to link against the appropriate library. It
|
||||
# contains the SWIG Python runtime library that is needed by the type
|
||||
# check system for example.
|
||||
AC_DEFUN([SWIG_PYTHON],[
|
||||
AC_REQUIRE([AC_PROG_SWIG])
|
||||
AC_REQUIRE([AC_PYTHON_DEVEL])
|
||||
test "x$1" != "xno" || swig_shadow=" -noproxy"
|
||||
AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow])
|
||||
AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS])
|
||||
])
|
||||
|
||||
|
||||
dnl @synopsis AC_LIB_WAD
|
||||
dnl
|
||||
dnl This macro searches for installed WAD library.
|
||||
dnl
|
||||
AC_DEFUN([AC_LIB_WAD],
|
||||
[
|
||||
AC_REQUIRE([AC_PYTHON_DEVEL])
|
||||
AC_ARG_ENABLE(wad,
|
||||
AC_HELP_STRING([--enable-wad], [enable wad module]),
|
||||
[
|
||||
case "${enableval}" in
|
||||
no) ;;
|
||||
*) if test "x${enableval}" = xyes;
|
||||
then
|
||||
check_wad="yes"
|
||||
fi ;;
|
||||
esac
|
||||
], [])
|
||||
|
||||
if test -n "$check_wad";
|
||||
then
|
||||
AC_CHECK_LIB(wadpy, _init, [WADPY=-lwadpy], [], $PYTHON_LDFLAGS $PYTHON_EXTRA_LIBS)
|
||||
AC_SUBST(WADPY)
|
||||
fi
|
||||
])
|
224
plugins/pyloader/m4/ac_python_devel.m4
Normal file
224
plugins/pyloader/m4/ac_python_devel.m4
Normal file
|
@ -0,0 +1,224 @@
|
|||
dnl @synopsis AC_PYTHON_DEVEL([version])
|
||||
dnl
|
||||
dnl Checks for Python and tries to get the include path to 'Python.h'.
|
||||
dnl It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output
|
||||
dnl variables.
|
||||
dnl Also exports $(PYTHON_EXTRA_LIBS) and $(PYTHON_EXTRA_LDFLAGS)
|
||||
dnl for embedding Python in your code.
|
||||
dnl
|
||||
dnl You can search for some particular version of Python by passing a
|
||||
dnl parameter to this macro, for example ">= '2.3.1'", or "== '2.4'".
|
||||
dnl Please note that you *have* to pass also an operator along
|
||||
dnl with the version to match, and pay special attention to the
|
||||
dnl single quotes surrounding the version number.
|
||||
dnl
|
||||
dnl If the user wants to employ a particular version of Python, she can
|
||||
dnl now pass to configure the PYTHON_VERSION environment variable.
|
||||
dnl This is only limited by the macro parameter set by the packager.
|
||||
dnl
|
||||
dnl This macro should work for all versions of Python >= 2.1.0. You can
|
||||
dnl disable the check for the python version by setting the
|
||||
dnl PYTHON_NOVERSIONCHECK environment variable to something else
|
||||
dnl than the empty string.
|
||||
dnl
|
||||
dnl If you need to use this macro for an older Python version, please
|
||||
dnl contact the authors. We're always open for feedback.
|
||||
dnl
|
||||
dnl @category InstalledPackages
|
||||
dnl @author Sebastian Huber <sebastian-huber@web.de>
|
||||
dnl @author Alan W. Irwin <irwin@beluga.phys.uvic.ca>
|
||||
dnl @author Rafael Laboissiere <laboissiere@psy.mpg.de>
|
||||
dnl @author Andrew Collier <colliera@nu.ac.za>
|
||||
dnl @author Matteo Settenvini <matteo@member.fsf.org>
|
||||
dnl @author Horst Knorr <hk_classes@knoda.org>
|
||||
dnl @version 2006-02-05
|
||||
dnl @license GPLWithACException
|
||||
|
||||
AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
#
|
||||
# Allow the use of a (user set) custom python version
|
||||
#
|
||||
AC_ARG_VAR([PYTHON_VERSION],[The installed Python
|
||||
version to use, for example '2.3'. This string
|
||||
will be appended to the Python interpreter
|
||||
canonical name.])
|
||||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for a version of Python >= 2.1.0
|
||||
#
|
||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver >= '2.1.0'"`
|
||||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_FAILURE([
|
||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
|
||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
])dnl
|
||||
else
|
||||
AC_MSG_RESULT([skip at user request])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
#
|
||||
# if the macro parameter ``version'' is set, honour it
|
||||
#
|
||||
if test -n "$1"; then
|
||||
AC_MSG_CHECKING([for a version of Python $1])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver $1"`
|
||||
if test "$ac_supports_python_ver" = "True"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([this package requires Python $1.
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See ``configure --help'' for reference.
|
||||
])dnl
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test -z "$ac_distutils_result"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([cannot import Python module "distutils".
|
||||
Please check your Python installation. The error was:
|
||||
$ac_distutils_result])
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for Python include path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python include path])
|
||||
if test -z "$PYTHON_CPPFLAGS"; then
|
||||
python_path=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_inc();"`
|
||||
if test -n "${python_path}"; then
|
||||
python_path="-I$python_path"
|
||||
fi
|
||||
PYTHON_CPPFLAGS=$python_path
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
|
||||
AC_SUBST([PYTHON_CPPFLAGS])
|
||||
|
||||
#
|
||||
# Check for Python library path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
# (makes two attempts to ensure we've got a version number
|
||||
# from the interpreter)
|
||||
py_version=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print join(get_config_vars('VERSION'))"`
|
||||
if test "$py_version" == "[None]"; then
|
||||
if test -n "$PYTHON_VERSION"; then
|
||||
py_version=$PYTHON_VERSION
|
||||
else
|
||||
py_version=`$PYTHON -c "import sys; \
|
||||
print sys.version[[:3]]"`
|
||||
fi
|
||||
fi
|
||||
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print '-L' + get_python_lib(0,1), \
|
||||
'-lpython';"`$py_version
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_LDFLAGS])
|
||||
AC_SUBST([PYTHON_LDFLAGS])
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
AC_MSG_CHECKING([for Python site-packages path])
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_lib(0,0);"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_SITE_PKG])
|
||||
AC_SUBST([PYTHON_SITE_PKG])
|
||||
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra libraries)
|
||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LOCALMODLIBS'), conf('LIBS')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
|
||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
||||
|
||||
#
|
||||
# linking flags needed when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra linking flags)
|
||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LINKFORSHARED')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
|
||||
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
|
||||
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
AC_MSG_CHECKING([whether collected informations are consistent])
|
||||
AC_LANG_PUSH([C])
|
||||
# save current global flags
|
||||
LIBS="$ac_save_LIBS $PYTHON_LDFLAGS"
|
||||
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
AC_TRY_LINK([
|
||||
#include <Python.h>
|
||||
],[
|
||||
Py_Initialize();
|
||||
],[pythonexists=yes],[pythonexists=no])
|
||||
|
||||
AC_MSG_RESULT([$pythonexists])
|
||||
|
||||
if test ! "$pythonexists" = "yes"; then
|
||||
AC_MSG_ERROR([
|
||||
Could not link test program to Python. Maybe the main Python library has been
|
||||
installed in some non-standard library path. If so, pass it to configure,
|
||||
via the LDFLAGS environment variable.
|
||||
============================================================================
|
||||
ERROR!
|
||||
You probably have to install the development version of the Python package
|
||||
for your distribution. The exact name of this package varies among them.
|
||||
============================================================================
|
||||
])
|
||||
fi
|
||||
AC_LANG_POP
|
||||
# turn back to default flags
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
|
||||
#
|
||||
# all done!
|
||||
#
|
||||
])
|
30
plugins/pyloader/m4/ac_python_module.m4
Normal file
30
plugins/pyloader/m4/ac_python_module.m4
Normal file
|
@ -0,0 +1,30 @@
|
|||
dnl @synopsis AC_PYTHON_MODULE(modname[, fatal])
|
||||
dnl
|
||||
dnl Checks for Python module.
|
||||
dnl
|
||||
dnl If fatal is non-empty then absence of a module will trigger an
|
||||
dnl error.
|
||||
dnl
|
||||
dnl @category InstalledPackages
|
||||
dnl @author Andrew Collier <colliera@nu.ac.za>.
|
||||
dnl @version 2004-07-14
|
||||
dnl @license AllPermissive
|
||||
|
||||
AC_DEFUN([AC_PYTHON_MODULE],[
|
||||
AC_MSG_CHECKING(python module: $1)
|
||||
python -c "import $1" 2>/dev/null
|
||||
if test $? -eq 0;
|
||||
then
|
||||
AC_MSG_RESULT(yes)
|
||||
eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
eval AS_TR_CPP(HAVE_PYMOD_$1)=no
|
||||
#
|
||||
if test -n "$2"
|
||||
then
|
||||
AC_MSG_ERROR(failed to find required module $1)
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
])
|
60
plugins/pyloader/m4/compilerflags.m4
Normal file
60
plugins/pyloader/m4/compilerflags.m4
Normal file
|
@ -0,0 +1,60 @@
|
|||
dnl **************************************************
|
||||
dnl Copyright (C) 2004 Matteo Settenvini
|
||||
dnl **************************************************
|
||||
|
||||
dnl ---------- AC_CHECK_CXXFLAG ---------------------
|
||||
dnl This macro checks if a particular flag for the
|
||||
dnl C++ compiler works. If it is so, it puts the flag
|
||||
dnl into the first macro parameter.
|
||||
dnl Example of usage : AC_CHECK_CXXFLAG([CXXFLAGS],[Wall])
|
||||
dnl -------------------------------------------------
|
||||
AC_DEFUN([AC_CHECK_CXXFLAG],
|
||||
[ if test -z "$1" -o -z "$2"; then
|
||||
AC_MSG_FAILURE([Wrong parameters passed to the m4 macro.
|
||||
Please contact the package mantainer.])
|
||||
fi
|
||||
AC_REQUIRE([AC_PROG_CXX])dnl
|
||||
AC_MSG_CHECKING([whether $CXX supports the -$2 flag])
|
||||
ac_check_cxxflags=$CXXFLAGS
|
||||
CXXFLAGS="-$2"
|
||||
AC_LANG_PUSH([C++])
|
||||
AC_COMPILE_IFELSE(
|
||||
AC_LANG_PROGRAM([], [return 0;]),
|
||||
[AC_MSG_RESULT([yes])
|
||||
CXXFLAGS="$ac_check_cxxflags"
|
||||
$1="-$2 $[$1]" ],
|
||||
[AC_MSG_RESULT([no])
|
||||
CXXFLAGS=$ac_check_cxxflags ]
|
||||
)
|
||||
AC_LANG_POP
|
||||
])dnl ------- AC_CHECK_CXXFLAG ----------------------
|
||||
|
||||
|
||||
|
||||
dnl ---------- AC_CHECK_CFLAG ---------------------
|
||||
dnl This macro checks if a particular flag for the
|
||||
dnl C compiler works. If it is so, it adds the flag
|
||||
dnl into the first macro parameter.
|
||||
dnl Example of usage : AC_CHECK_CFLAG([CFLAGS],[Wall])
|
||||
dnl -------------------------------------------------
|
||||
AC_DEFUN([AC_CHECK_CFLAG],
|
||||
[ if test -z "$1" -o -z "$2"; then
|
||||
AC_MSG_FAILURE([Wrong parameters passed to the m4 macro.
|
||||
Please contact the package mantainer.])
|
||||
fi
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
AC_MSG_CHECKING([whether $CC supports the -$2 flag])
|
||||
ac_check_cflags=$CFLAGS
|
||||
CFLAGS="-$2"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_COMPILE_IFELSE(
|
||||
AC_LANG_PROGRAM([], [return 0;]),
|
||||
[AC_MSG_RESULT([yes])
|
||||
CFLAGS="$ac_check_cflags"
|
||||
$1="-$2 $[$1]" ],
|
||||
[AC_MSG_RESULT([no])
|
||||
CFLAGS=$ac_check_cflags ]
|
||||
)
|
||||
AC_LANG_POP
|
||||
])dnl ------- AC_CHECK_CFLAG ----------------------
|
||||
|
31
plugins/pyloader/m4/linkingflags.m4
Normal file
31
plugins/pyloader/m4/linkingflags.m4
Normal file
|
@ -0,0 +1,31 @@
|
|||
dnl **************************************************
|
||||
dnl Copyright (C) 2004 Matteo Settenvini
|
||||
dnl **************************************************
|
||||
|
||||
dnl ---------- AX_CHECK_LDFLAG ---------------------
|
||||
dnl This macro checks if a particular flag for the
|
||||
dnl C++ compiler works. If it is so, it adds the flag
|
||||
dnl to the end of the first parameter.
|
||||
dnl Example of usage : AC_CHECK_LDFLAG([LDFLAGS],[--as-needed])
|
||||
dnl -------------------------------------------------
|
||||
AC_DEFUN([AC_CHECK_LDFLAG],
|
||||
[ if test -z "$1" -o -z "$2"; then
|
||||
AC_MSG_FAILURE([Wrong parameters passed to the m4 macro.
|
||||
Please contact the package mantainer.])
|
||||
fi
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
AC_MSG_CHECKING([whether the linker supports the $2 flag])
|
||||
ac_check_ldflags=$LDFLAGS
|
||||
LDFLAGS="-Wl,$2"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_LINK_IFELSE(
|
||||
AC_LANG_PROGRAM([], [return 0;]),
|
||||
[AC_MSG_RESULT([yes])
|
||||
LDFLAGS=$ac_check_ldflags
|
||||
$1="-Wl,$2 $[$1]" ],
|
||||
[AC_MSG_RESULT([no])
|
||||
LDFLAGS=$ac_check_ldflags ]
|
||||
)
|
||||
AC_LANG_POP
|
||||
])dnl ------- AC_CHECK_LDFLAG ----------------------
|
||||
|
81
plugins/pyloader/m4/sgpemv2-dirs.m4
Normal file
81
plugins/pyloader/m4/sgpemv2-dirs.m4
Normal file
|
@ -0,0 +1,81 @@
|
|||
dnl m4/sgpemv2-dirs.m4 - Copyright 2005, 2006, University
|
||||
dnl of Padova, dept. of Pure and Applied
|
||||
dnl Mathematics
|
||||
dnl
|
||||
dnl This file is part of SGPEMv2.
|
||||
dnl
|
||||
dnl This is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl SGPEMv2 is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with SGPEMv2; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
dnl ---------- AC_PROG_SGPEMV2 ---------------------
|
||||
dnl
|
||||
dnl Synopsis: AC_PROG_SGPEMV2([min_version])
|
||||
dnl
|
||||
dnl This macro checks if sgpemv2 is installed, and
|
||||
dnl AC_SUBSTs the following variables:
|
||||
dnl
|
||||
dnl SGPEMV2_CFLAGS -> necessary includes for compiling
|
||||
dnl plugins
|
||||
dnl SGPEMV2_LIBS -> libraries to link against when
|
||||
dnl building a loadable plugin
|
||||
dnl SGPEMV2_POLICIES_DIR -> global policies directory
|
||||
dnl SGPEMV2_PLUGINS_DIR -> global plugins directory
|
||||
dnl
|
||||
dnl This is particularly useful for plugin installation.
|
||||
dnl It takes a parameter which is the minimal version
|
||||
dnl installed of sgpemv2 this macro checks for.
|
||||
dnl The parameter is mandatory.
|
||||
dnl
|
||||
dnl Example of usage: AC_PROG_SGPEMV2([0.1])
|
||||
dnl ------------------------------------------------
|
||||
AC_DEFUN([AC_PROG_SGPEMV2],
|
||||
[
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
if test "x$1" = "x"; then
|
||||
AC_MSG_FAILURE([Wrong number of parameters passed to macro AC@&t@_PROG_SGPEMV2. Please contact this package mantainer.])
|
||||
fi
|
||||
|
||||
_pkg_sgpemv2_module="sgpemv2 >= $1"
|
||||
|
||||
PKG_CHECK_MODULES([SGPEMV2], [$_pkg_sgpemv2_module],
|
||||
:, AC_MSG_ERROR([$SGPEMV2_PKG_ERRORS]))
|
||||
|
||||
AC_MSG_CHECKING([for sgpemv2 compiler flags])
|
||||
AC_MSG_RESULT([$SGPEMV2_CFLAGS])
|
||||
|
||||
AC_MSG_CHECKING([for sgpemv2 linking flags])
|
||||
AC_MSG_RESULT([$SGPEMV2_LIBS])
|
||||
|
||||
AC_MSG_CHECKING([for sgpemv2 policies default installation directory])
|
||||
SGPEMV2_POLICIES_DIR=`$PKG_CONFIG --variable=policies_dir "$_pkg_sgpemv2_module" 2>/dev/null`
|
||||
if test "x$SGPEMV2_POLICIES_DIR" = "x"; then
|
||||
AC_MSG_ERROR([Unable to retrieve value])
|
||||
else
|
||||
AC_MSG_RESULT([$SGPEMV2_POLICIES_DIR])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for sgpemv2 plugins default installation directory])
|
||||
SGPEMV2_PLUGINS_DIR=`$PKG_CONFIG --variable=plugins_dir "$_pkg_sgpemv2_module" 2>/dev/null`
|
||||
if test "x$SGPEMV2_PLUGINS_DIR" = "x"; then
|
||||
AC_MSG_ERROR([Unable to retrieve value])
|
||||
else
|
||||
AC_MSG_RESULT([$SGPEMV2_PLUGINS_DIR])
|
||||
fi
|
||||
|
||||
AC_SUBST([SGPEMV2_POLICIES_DIR])
|
||||
AC_SUBST([SGPEMV2_PLUGINS_DIR])
|
||||
|
||||
])dnl ------- AC_PROG_SGPEMV2 ----------------------
|
||||
|
41
plugins/pyloader/po/Makevars
Normal file
41
plugins/pyloader/po/Makevars
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Makefile variables for PO directory in any package using GNU gettext.
|
||||
|
||||
# Usually the message domain is the same as the package name.
|
||||
DOMAIN = $(PACKAGE)
|
||||
|
||||
# These two variables depend on the location of this directory.
|
||||
subdir = po
|
||||
top_builddir = ..
|
||||
|
||||
# These options get passed to xgettext.
|
||||
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
|
||||
|
||||
# This is the copyright holder that gets inserted into the header of the
|
||||
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
|
||||
# package. (Note that the msgstr strings, extracted from the package's
|
||||
# sources, belong to the copyright holder of the package.) Translators are
|
||||
# expected to transfer the copyright for their translations to this person
|
||||
# or entity, or to disclaim their copyright. The empty string stands for
|
||||
# the public domain; in this case the translators are expected to disclaim
|
||||
# their copyright.
|
||||
COPYRIGHT_HOLDER = Free Software Foundation, Inc.
|
||||
|
||||
# This is the email address or URL to which the translators shall report
|
||||
# bugs in the untranslated strings:
|
||||
# - Strings which are not entire sentences, see the maintainer guidelines
|
||||
# in the GNU gettext documentation, section 'Preparing Strings'.
|
||||
# - Strings which use unclear terms or require additional context to be
|
||||
# understood.
|
||||
# - Strings which make invalid assumptions about notation of date, time or
|
||||
# money.
|
||||
# - Pluralisation problems.
|
||||
# - Incorrect English spelling.
|
||||
# - Incorrect formatting.
|
||||
# It can be your email address, or a mailing list address where translators
|
||||
# can write to without being subscribed, or the URL of a web page through
|
||||
# which the translators can contact you.
|
||||
MSGID_BUGS_ADDRESS = matteo@member.fsf.org
|
||||
|
||||
# This is the list of locale categories, beyond LC_MESSAGES, for which the
|
||||
# message catalogs shall be used. It is usually empty.
|
||||
EXTRA_LOCALE_CATEGORIES =
|
0
plugins/pyloader/po/POTFILES.in
Normal file
0
plugins/pyloader/po/POTFILES.in
Normal file
205
plugins/pyloader/python_policy.cc
Normal file
205
plugins/pyloader/python_policy.cc
Normal file
|
@ -0,0 +1,205 @@
|
|||
// src/backend/pyloader/python_policy.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
|
||||
|
||||
#include "python_policy.hh"
|
||||
#include <limits>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
using namespace sgpem;
|
||||
using namespace std;
|
||||
|
||||
#define WAIT_FOR (250000)
|
||||
|
||||
// WARNING : this class needs extensive and above all
|
||||
// *strong* exception checking / handling!
|
||||
|
||||
PythonPolicy::PythonPolicy(const char* name)
|
||||
: _adapter(NULL), _adapter_dict(NULL), _name(name)
|
||||
{
|
||||
PyObject* pLoadmeStr = PyString_FromString(name);
|
||||
PyObject* pUserPolicyModule = PyImport_Import(pLoadmeStr);
|
||||
Py_DECREF(pLoadmeStr);
|
||||
|
||||
if( !pUserPolicyModule )
|
||||
{
|
||||
PyErr_Print(); // Error in import
|
||||
// FIXME : don't exit abruptly, but fall back gracefully
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Dictionary with defined ``symbols'' for .pyc file
|
||||
PyObject* pUserPolicyDict = PyModule_GetDict(pUserPolicyModule);
|
||||
assert(pUserPolicyDict);
|
||||
|
||||
// Loads ScriptAdapter module and get its dictionary
|
||||
pLoadmeStr = PyString_FromString("ScriptAdapter");
|
||||
PyObject* pScriptAdapterModule = PyImport_Import(pLoadmeStr);
|
||||
Py_DECREF(pLoadmeStr);
|
||||
assert(pScriptAdapterModule);
|
||||
_adapter_dict = PyModule_GetDict(pScriptAdapterModule);
|
||||
assert(_adapter_dict);
|
||||
// We want to keep a reference to it
|
||||
Py_INCREF(_adapter_dict);
|
||||
|
||||
// Now takes the user-defined policy class from pUserPolicyDict
|
||||
PyObject* pPolicyClass = PyDict_GetItemString(pUserPolicyDict, name);
|
||||
assert(pPolicyClass); // FIXME needs stricter checking and exception throwing
|
||||
|
||||
// Creates a new object of type ScriptAdapter :
|
||||
// takes init function from ScriptAdapter class
|
||||
PyObject* pAdapterClass = PyDict_GetItemString(_adapter_dict, "ScriptAdapter");
|
||||
PyObject* pAdapterCtorParam = PyTuple_New(1);
|
||||
Py_INCREF(pPolicyClass); // PyTuple_SetItem steals a reference
|
||||
PyTuple_SetItem(pAdapterCtorParam, 0, pPolicyClass);
|
||||
_adapter = PyInstance_New(pAdapterClass, pAdapterCtorParam, NULL);
|
||||
Py_DECREF(pAdapterCtorParam);
|
||||
assert(_adapter);
|
||||
|
||||
Py_DECREF(pUserPolicyModule);
|
||||
Py_DECREF(pScriptAdapterModule);
|
||||
|
||||
// And now, who's your daddy, huh?
|
||||
}
|
||||
|
||||
|
||||
PythonPolicy::~PythonPolicy()
|
||||
{
|
||||
if(_adapter) Py_DECREF(_adapter);
|
||||
if(_adapter_dict) Py_DECREF(_adapter_dict);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicy::configure() throw(UserInterruptException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_configure", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
||||
wait_unlock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicy::sort_queue(Scheduler::event event) const throw(UserInterruptException)
|
||||
{
|
||||
PyObject* pEvent = PyInt_FromLong(event);
|
||||
PyObject* pMethodName = PyString_FromString("async_sort_queue");
|
||||
PyObject* retval = PyObject_CallMethodObjArgs(_adapter, pMethodName, pEvent, NULL);
|
||||
|
||||
// Do minimal debugging
|
||||
if(!retval) PyErr_Print();
|
||||
else Py_DECREF(retval);
|
||||
|
||||
Py_DECREF(pMethodName);
|
||||
Py_DECREF(pEvent);
|
||||
|
||||
wait_unlock();
|
||||
}
|
||||
|
||||
|
||||
Glib::ustring
|
||||
PythonPolicy::get_description() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PythonPolicy::is_pre_emptive() const throw(UserInterruptException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_is_preemptive", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
||||
wait_unlock();
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyObject_CallMethod(_adapter, "get_return_value", NULL);
|
||||
assert(retval);
|
||||
bool ret = PyObject_IsTrue(retval);
|
||||
Py_DECREF(retval);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PythonPolicy::get_time_slice() const throw(UserInterruptException) {
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_get_time_slice", 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);
|
||||
|
||||
return tmp < 0 ? numeric_limits<int>::max() : static_cast<int>(tmp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicy::wait_unlock() const throw(UserInterruptException)
|
||||
{
|
||||
PyThreadState* _save;
|
||||
int i = 0; // We give the sort_queue() three seconds max time, then...
|
||||
// we shot it stone dead! Bang.
|
||||
|
||||
bool still_locked;
|
||||
do
|
||||
{
|
||||
Py_UNBLOCK_THREADS;
|
||||
usleep(WAIT_FOR); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
|
||||
Py_BLOCK_THREADS;
|
||||
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "mutex_test_lock", NULL);
|
||||
assert(retval);
|
||||
still_locked = PyObject_IsTrue(retval);
|
||||
Py_DECREF(retval);
|
||||
|
||||
if(i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
|
||||
{
|
||||
PyThreadState_Clear(_save);
|
||||
PyEval_RestoreThread(_save);
|
||||
|
||||
//Py_UNBLOCK_THREADS;
|
||||
|
||||
throw UserInterruptException("User-defined policy is "
|
||||
"taking too long to terminate.");
|
||||
}
|
||||
}
|
||||
while(still_locked);
|
||||
|
||||
// What we should really do here:
|
||||
/* do {
|
||||
enable python threads
|
||||
wait for some time...
|
||||
disable python threads
|
||||
...check if user asked for interruption, reading a
|
||||
syncronized variable...
|
||||
...if he has, break
|
||||
...else:
|
||||
if the global lock is set:
|
||||
stay in this loop
|
||||
else:
|
||||
all's went okay, can exit loop
|
||||
} */
|
||||
|
||||
}
|
92
plugins/pyloader/python_policy.hh
Normal file
92
plugins/pyloader/python_policy.hh
Normal file
|
@ -0,0 +1,92 @@
|
|||
// src/backend/pyloader/python_policy.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
|
||||
|
||||
#ifndef PYTHON_POLICY_HH
|
||||
#define PYTHON_POLICY_HH 1
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <Python.h>
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "policy.hh"
|
||||
#include "user_interrupt_exception.hh"
|
||||
|
||||
namespace sgpem
|
||||
{
|
||||
class PythonPolicy;
|
||||
class PythonPolicyManager;
|
||||
class UserInterruptException;
|
||||
|
||||
/** \brief A specialization of abstract class Policy
|
||||
|
||||
This class represents a policy written in Python. Its methods interact with Python interpreter.
|
||||
See the documentation of class Policy for more detailed informations.
|
||||
*/
|
||||
class SG_DLLEXPORT PythonPolicy : public Policy
|
||||
{
|
||||
public:
|
||||
PythonPolicy(const char* name);
|
||||
virtual ~PythonPolicy();
|
||||
|
||||
/**
|
||||
Calls the method \c async_configure
|
||||
*/
|
||||
void configure() throw(UserInterruptException);
|
||||
|
||||
/**
|
||||
Calls the method \c async_sort_queue
|
||||
*/
|
||||
void sort_queue(Scheduler::event) const throw(UserInterruptException);
|
||||
|
||||
/**
|
||||
\returns A textual description of this policy.
|
||||
*/
|
||||
Glib::ustring get_description() const;
|
||||
|
||||
/**
|
||||
\returns \c TRUE if the policy is preemptive.
|
||||
\returns \c FALSE if the policy is not preemptive.
|
||||
*/
|
||||
bool is_pre_emptive() const throw(UserInterruptException);
|
||||
|
||||
/**
|
||||
\returns The integer value of its time-slice.
|
||||
*/
|
||||
int get_time_slice() const throw(UserInterruptException);
|
||||
|
||||
private:
|
||||
PythonPolicy(const PythonPolicy&);
|
||||
PythonPolicy& operator=(const PythonPolicy&);
|
||||
|
||||
void wait_unlock() const throw(UserInterruptException);
|
||||
|
||||
PyObject* _adapter;
|
||||
PyObject* _adapter_dict;
|
||||
|
||||
Glib::ustring _name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
115
plugins/pyloader/python_policy_manager.cc
Normal file
115
plugins/pyloader/python_policy_manager.cc
Normal file
|
@ -0,0 +1,115 @@
|
|||
// src/backend/pyloader/python_policy_manager.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
|
||||
|
||||
#include "python_policy_manager.hh"
|
||||
#include "global_settings.hh"
|
||||
|
||||
#include <Python.h>
|
||||
#include <glibmm/ustring.h>
|
||||
#include <glibmm/timer.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
using namespace sgpem;
|
||||
|
||||
|
||||
|
||||
// Concatenate a string with all the policies directories
|
||||
struct pol_dirs_concat : public std::unary_function<void, const Glib::ustring&>
|
||||
{
|
||||
public:
|
||||
pol_dirs_concat(Glib::ustring& cat) : _cat(cat) {}
|
||||
void operator()(const Glib::ustring& add)
|
||||
{
|
||||
// Please note that this string will end finishing with
|
||||
// and additional ","!
|
||||
_cat += "'" + add + "', ";
|
||||
}
|
||||
private:
|
||||
Glib::ustring& _cat;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//static object
|
||||
PythonPolicyManager* PythonPolicyManager::_instance = NULL;
|
||||
|
||||
|
||||
PythonPolicyManager::PythonPolicyManager()
|
||||
: _initialized(false)
|
||||
{
|
||||
PyEval_InitThreads();
|
||||
}
|
||||
|
||||
|
||||
PythonPolicyManager* const
|
||||
PythonPolicyManager::get_instance()
|
||||
{
|
||||
if(!_instance)
|
||||
_instance = new PythonPolicyManager();
|
||||
return _instance;
|
||||
}
|
||||
|
||||
|
||||
Policy&
|
||||
PythonPolicyManager::get_policy()
|
||||
{
|
||||
// FIXME : assumes that _python_policy is always != NULL!
|
||||
return *_python_policy;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicyManager::init()
|
||||
{
|
||||
if(_initialized)
|
||||
// No-op
|
||||
return;
|
||||
|
||||
Py_Initialize();
|
||||
_initialized = true;
|
||||
|
||||
// The following lines are ugly, but necessary if we use
|
||||
// non-standard installation directories. Theoretically,
|
||||
// it should be up to the user to set correct
|
||||
// environment variables.
|
||||
// FIXME: find better way to achieve this.
|
||||
|
||||
Glib::ustring importdirs = "import sys\n"
|
||||
"sys.path[:0] = [ ";
|
||||
for_each(GlobalSettings::instance().policies_dir_begin(),
|
||||
GlobalSettings::instance().policies_dir_end(),
|
||||
pol_dirs_concat(importdirs));
|
||||
importdirs += " '" SHAREDIR "' ]\n";
|
||||
|
||||
PyRun_SimpleString(importdirs.c_str());
|
||||
|
||||
// Okay, here we go.
|
||||
// Black magic at work.
|
||||
|
||||
// FIXME : Hardcoded policy name
|
||||
char* policy_name = "fcfs";
|
||||
//char* policy_name = "sjf";
|
||||
_python_policy = std::auto_ptr<PythonPolicy>(new PythonPolicy(policy_name));
|
||||
}
|
88
plugins/pyloader/python_policy_manager.hh
Normal file
88
plugins/pyloader/python_policy_manager.hh
Normal file
|
@ -0,0 +1,88 @@
|
|||
// src/backend/pyloader/python_policy_manager.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
|
||||
|
||||
#ifndef PYTHON_POLICY_MANAGER_HH
|
||||
#define PYTHON_POLICY_MANAGER_HH 1
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "policy_manager.hh"
|
||||
#include "python_policy.hh"
|
||||
|
||||
namespace sgpem
|
||||
{
|
||||
//class PolicyManager;
|
||||
class PythonPolicyManager;
|
||||
|
||||
/** \brief Manages Python user-implemented policies
|
||||
*
|
||||
* This singleton manages the creation and destruction
|
||||
* of a Python policy.
|
||||
*/
|
||||
class SG_DLLEXPORT PythonPolicyManager : public PolicyManager
|
||||
{
|
||||
public:
|
||||
/** \brief Returns a reference to the active policy.
|
||||
*
|
||||
* For the moment, it will sufficit to keep and return
|
||||
* just one Policy for PolicyManager.
|
||||
* In the next milestones it will be possible to manage
|
||||
* more than one, and to retrieve the correct Policy by
|
||||
* passing a unique ID.
|
||||
*/
|
||||
Policy& get_policy();
|
||||
|
||||
/** \brief Initialize the Python interpreter.
|
||||
*
|
||||
* If the interpreter has already been initialized, it terminates it, cleanups old policies,
|
||||
* and restarts it.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/** \brief Returns the singleton instance of
|
||||
* PythonPolicyManager.
|
||||
*
|
||||
* Please note that the first time you'll request
|
||||
* it, it will be still uninitialized.
|
||||
* @see init()
|
||||
*/
|
||||
static PythonPolicyManager* const get_instance();
|
||||
|
||||
protected:
|
||||
/** The selected and active PyhonPolicy object. */
|
||||
PythonPolicyManager();
|
||||
std::auto_ptr<PythonPolicy> _python_policy;
|
||||
|
||||
private:
|
||||
PythonPolicyManager(const PythonPolicyManager&);
|
||||
PythonPolicyManager& operator=(const PythonPolicyManager&);
|
||||
|
||||
/** Singleton support. */
|
||||
static PythonPolicyManager* _instance;
|
||||
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
195
plugins/pyloader/sgpem.i
Normal file
195
plugins/pyloader/sgpem.i
Normal file
|
@ -0,0 +1,195 @@
|
|||
%module sgpem
|
||||
%{
|
||||
#include "policy.hh"
|
||||
#include "policy_parameters.hh"
|
||||
#include "schedulable.hh"
|
||||
#include "schedulable_list.hh"
|
||||
#include "schedulable_status.hh"
|
||||
#include "scheduler.hh"
|
||||
%}
|
||||
|
||||
/* NOTE : passing Unicode strings to C++ methods calling them
|
||||
* from Python results in a SIGSEGV. You've been warned!
|
||||
* (Investigate if this can be fixed, else please report it in
|
||||
* the sgpem user manual)
|
||||
*/
|
||||
|
||||
/** Due to the relatively new support for namespaces in SWIG,
|
||||
* make sure to include the full visibility signature when
|
||||
* returning / passing parameters from / to functions with
|
||||
* objects different to the one you're declaring.
|
||||
*/
|
||||
|
||||
namespace std {
|
||||
class exception {
|
||||
public:
|
||||
virtual const char* what() const throw();
|
||||
private:
|
||||
exception();
|
||||
};
|
||||
|
||||
class runtime_error : public std::exception {
|
||||
public:
|
||||
virtual const char* what() const throw();
|
||||
private:
|
||||
runtime_error();
|
||||
};
|
||||
}
|
||||
|
||||
namespace sgpem {
|
||||
|
||||
class Policy {
|
||||
public:
|
||||
virtual ~Policy() = 0;
|
||||
sgpem::PolicyParameters& get_parameters();
|
||||
};
|
||||
|
||||
// --------------------------------------------
|
||||
class PolicyParametersException : public std::runtime_error {
|
||||
public:
|
||||
PolicyParametersException(char* msg);
|
||||
%rename (__str__) what;
|
||||
virtual const char* what();
|
||||
}; //~ class PolicyParametersException
|
||||
|
||||
// --------------------------------------------
|
||||
class PolicyParameters
|
||||
{
|
||||
public:
|
||||
//methods to CREATE PARAMETERS
|
||||
// (rewrapped correctly for SWIG usage)
|
||||
%ignore register_int(const Glib::ustring&, const int&,
|
||||
const int&, const bool&, const int&);
|
||||
%ignore register_float(const Glib::ustring&, const float&,
|
||||
const float&, const bool&, const float&);
|
||||
%ignore register_string(const Glib::ustring&, const bool&,
|
||||
const char*);
|
||||
|
||||
%extend {
|
||||
void register_int(const char* name,
|
||||
const int& lower_bound,
|
||||
const int& upper_bound,
|
||||
const bool& required,
|
||||
const int& default_value = 0)
|
||||
{
|
||||
self->register_int(name, lower_bound, upper_bound,
|
||||
required, default_value);
|
||||
}
|
||||
|
||||
void register_float(const char* name,
|
||||
const float& lower_bound,
|
||||
const float& upper_bound,
|
||||
const bool& required,
|
||||
const float& default_value = 0.0f)
|
||||
{
|
||||
self->register_float(name, lower_bound, upper_bound,
|
||||
required, default_value);
|
||||
}
|
||||
|
||||
void register_string(const char* name,
|
||||
const bool& required,
|
||||
const char* default_value = "")
|
||||
{
|
||||
self->register_string(name, required, default_value);
|
||||
}
|
||||
}
|
||||
|
||||
//methods to SET the VALUE of PARAMETERS
|
||||
// (rewrapped correctly for SWIG usage)
|
||||
%ignore set_int(const Glib::ustring&, const int&);
|
||||
%ignore set_float(const Glib::ustring&, const float&);
|
||||
%ignore set_string(const Glib::ustring&, const Glib::ustring&);
|
||||
|
||||
%extend {
|
||||
bool set_int(const char* name, const int& value)
|
||||
{ return self->set_int(name, value); }
|
||||
bool set_float(const char* name, const float& value)
|
||||
{ return self->set_float(name, value); }
|
||||
bool set_string(const char* name, const char* value)
|
||||
{ return self->set_string(name, value); }
|
||||
}
|
||||
|
||||
//methods to GET the VALUE of PARAMETERS
|
||||
// (rewrapped correctly for SWIG usage)
|
||||
%ignore get_int(const Glib::ustring&) const;
|
||||
%ignore get_float(const Glib::ustring&) const;
|
||||
%ignore get_string(const Glib::ustring&) const;
|
||||
|
||||
%extend {
|
||||
int get_int(const char* name) const
|
||||
{ return self->get_int(name); }
|
||||
float get_float(const char* name) const
|
||||
{ return self->get_float(name); }
|
||||
const char* get_string(const char* name) const
|
||||
{ return self->get_string(name).c_str(); }
|
||||
}
|
||||
|
||||
}; //~ class PolicyParameters
|
||||
|
||||
// --------------------------------------------
|
||||
class Schedulable
|
||||
{
|
||||
public:
|
||||
virtual ~Schedulable() = 0;
|
||||
|
||||
virtual unsigned int get_arrival_time() const;
|
||||
int get_priority() const;
|
||||
unsigned int get_total_cpu_time() const;
|
||||
|
||||
%ignore Schedulable::get_name() const;
|
||||
%extend {
|
||||
const char* get_name() const
|
||||
{ return self->get_name().c_str(); }
|
||||
}
|
||||
}; //~ class Schedulable
|
||||
|
||||
|
||||
// --------------------------------------------
|
||||
class SchedulableList
|
||||
{
|
||||
public:
|
||||
unsigned int size() const;
|
||||
const sgpem::SchedulableStatus* get_item_at(const unsigned int&) const;
|
||||
void swap(unsigned int positionA, unsigned int positionB) throw();
|
||||
|
||||
private:
|
||||
// Avoid instantiation and copy
|
||||
SchedulableList();
|
||||
SchedulableList(const SchedulableList&);
|
||||
SchedulableList& operator=(const SchedulableList&);
|
||||
~SchedulableList();
|
||||
}; //~ class Schedulable
|
||||
|
||||
// ---------------------------------------------
|
||||
class SchedulableStatus
|
||||
{
|
||||
public:
|
||||
enum state
|
||||
{
|
||||
state_running = 1<<0,
|
||||
state_ready = 1<<1,
|
||||
state_blocked = 1<<2,
|
||||
state_future = 1<<3,
|
||||
state_terminated = 1<<4
|
||||
};
|
||||
|
||||
SchedulableStatus(const SchedulableStatus& obj);
|
||||
|
||||
int get_cpu_time_left() const;
|
||||
int get_last_scheduled() const;
|
||||
state get_state() const;
|
||||
const sgpem::Schedulable* get_schedulable() const;
|
||||
};
|
||||
|
||||
// ---------------------------------------------
|
||||
class Scheduler {
|
||||
public:
|
||||
sgpem::Policy& get_policy();
|
||||
static sgpem::Scheduler& get_instance();
|
||||
sgpem::SchedulableList* get_ready_queue();
|
||||
private:
|
||||
Scheduler();
|
||||
~Scheduler();
|
||||
};
|
||||
|
||||
} //~ namespace sgpem
|
20
plugins/pyloader/testsuite/python_loader_configure.py
Normal file
20
plugins/pyloader/testsuite/python_loader_configure.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from Policy import Policy
|
||||
import sys
|
||||
|
||||
class python_loader_configure(Policy) :
|
||||
def __init__(self):
|
||||
pass;
|
||||
|
||||
def configure(self):
|
||||
print "[II] Entering willingly an endless loop."
|
||||
while True:
|
||||
pass
|
||||
|
||||
def is_preemptive(self):
|
||||
return False
|
||||
|
||||
def get_time_slice(self):
|
||||
return -1
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
pass
|
21
plugins/pyloader/testsuite/python_loader_get_time_slice.py
Normal file
21
plugins/pyloader/testsuite/python_loader_get_time_slice.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from Policy import Policy
|
||||
import sys
|
||||
|
||||
class python_loader_get_time_slice(Policy) :
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
|
||||
def is_preemptive(self):
|
||||
return False
|
||||
|
||||
def get_time_slice(self):
|
||||
print "[II] Entering willingly an endless loop."
|
||||
while True:
|
||||
pass
|
||||
return -1
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
pass
|
21
plugins/pyloader/testsuite/python_loader_is_preemptive.py
Normal file
21
plugins/pyloader/testsuite/python_loader_is_preemptive.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from Policy import Policy
|
||||
import sys
|
||||
|
||||
class python_loader_is_preemptive(Policy) :
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
|
||||
def is_preemptive(self):
|
||||
print "[II] Entering willingly an endless loop."
|
||||
while True:
|
||||
pass
|
||||
return False
|
||||
|
||||
def get_time_slice(self):
|
||||
return -1
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
pass
|
20
plugins/pyloader/testsuite/python_loader_sort_queue.py
Normal file
20
plugins/pyloader/testsuite/python_loader_sort_queue.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from Policy import Policy
|
||||
import sys
|
||||
|
||||
class python_loader_sort_queue(Policy) :
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
|
||||
def is_preemptive(self):
|
||||
return False
|
||||
|
||||
def get_time_slice(self):
|
||||
return -1
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
print "[II] Entering willingly an endless loop."
|
||||
while True:
|
||||
pass
|
112
plugins/pyloader/testsuite/test-python_loader.cc
Normal file
112
plugins/pyloader/testsuite/test-python_loader.cc
Normal file
|
@ -0,0 +1,112 @@
|
|||
// src/testsuite/test-python_loader.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
|
||||
|
||||
/* This executable tests for workingness of the PythonPolicyManager
|
||||
* class and its closely related cousins. More documentation to be written
|
||||
* here, thanks very much. */
|
||||
|
||||
#include "../python_policy_manager.hh"
|
||||
#include "../python_policy.hh"
|
||||
#include "global_settings.hh"
|
||||
#include "schedulable_list.hh"
|
||||
#include "scheduler.hh"
|
||||
#include "user_interrupt_exception.hh"
|
||||
|
||||
#include <Python.h>
|
||||
#include <glibmm/module.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// FIXME: Eeeeh? Why does this work without explicit namespace resolving?
|
||||
// Is there some using declaration in included HEADERS?? Aaaaagh!
|
||||
|
||||
class TestPythonPolicyManager : public PythonPolicyManager {
|
||||
public:
|
||||
void test_init(const char* policy_name) {
|
||||
init();
|
||||
_python_policy = std::auto_ptr<PythonPolicy>(new PythonPolicy(policy_name));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv) {
|
||||
using namespace sgpem;
|
||||
using namespace std;
|
||||
|
||||
if(argc != 2) {
|
||||
std::cout << "[EE] Usage:\n\t" << argv[0] <<
|
||||
" path/to/uninstalled/policies" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
// Add argv[1] as the directory to search for uninstalled policies
|
||||
sgpem::GlobalSettings::instance().add_policies_dir(argv[1]);
|
||||
|
||||
// Self-register itself to Scheduler, however we don't care about it
|
||||
TestPythonPolicyManager polman;
|
||||
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_configure");
|
||||
polman.get_policy().configure();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "configure: Caught UserInterruptException" << endl;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_is_preemptive");
|
||||
polman.get_policy().is_pre_emptive();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "is_preemptive: Caught UserInterruptException" << endl;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_get_time_slice");
|
||||
polman.get_policy().get_time_slice();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "get_time_slice: Caught UserInterruptException" << endl;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
SchedulableList sl;
|
||||
polman.test_init("python_loader_sort_queue");
|
||||
polman.get_policy().sort_queue(Scheduler::event_schedulable_arrival);
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "sort_queue: Caught UserInterruptException" << endl;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue