- 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:
tchernobog 2006-04-06 19:01:13 +00:00
parent c6d4f5fd27
commit 51f0d7fbe7
36 changed files with 849 additions and 48 deletions

10
plugins/pyloader/AUTHORS Normal file
View 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>

View 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)

View 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
View file

178
plugins/pyloader/Policy.py Normal file
View 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
View file

View 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()

View 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)

View 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)

View 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

View 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
View 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

View 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
])

View 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!
#
])

View 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
])

View 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 ----------------------

View 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 ----------------------

View 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 ----------------------

View 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 =

View file

View 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
} */
}

View 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

View 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));
}

View 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
View 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

View 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

View 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

View 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

View 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

View 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);
}