From 712e14f558da391a993694b08339251b18cfb683 Mon Sep 17 00:00:00 2001 From: tchernobog Date: Tue, 21 Feb 2006 22:57:14 +0000 Subject: [PATCH] - Add first undocumented (and quite useless) test for libpyloader. It doesn't work properly for no apparent reason. - Add SWIG interface generation for Scheduler git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@375 3ecf2c5c-341e-0410-92b4-d18e462d057c --- Makefile.am | 21 ++++-- src/backend/pyloader/ScriptAdapter.py | 71 ++++++++++--------- src/backend/pyloader/python_policy_manager.cc | 64 +++++++---------- src/backend/pyloader/python_policy_manager.hh | 2 +- src/backend/sgpem.i | 12 ++++ src/builtin-policies/fcfs.py | 4 +- src/testsuite/test-python_loader.cc | 33 +++++++++ 7 files changed, 126 insertions(+), 81 deletions(-) create mode 100644 src/testsuite/test-python_loader.cc diff --git a/Makefile.am b/Makefile.am index e7bdef9..adda797 100644 --- a/Makefile.am +++ b/Makefile.am @@ -125,7 +125,8 @@ src_backend_pyloader_libpyloader_la_CXXFLAGS = \ src_backend_pyloader_libpyloader_la_LIBADD = \ $(PYTHON_LDFLAGS) \ $(PYTHON_EXTRA_LIBS) \ - $(GLIBMM_LIBS) + $(GLIBMM_LIBS) \ + src/backend/libbackend.la src_backend_pyloader_libpyloader_la_LDFLAGS = \ $(PYTHON_EXTRA_LDFLAGS) \ $(LT_LDFLAGS) @@ -162,8 +163,6 @@ src_backend_libbackend_la_CPPFLAGS = \ $(GLIBMM_CFLAGS) src_backend_libbackend_la_CXXFLAGS = \ $(VISIB_HIDDEN) -src_backend_libbackend_la_LIBADD = \ - src/backend/pyloader/libpyloader.la src_backend_libbackend_la_LDFLAGS = \ $(GLIBMM_LDFLAGS) \ $(LT_LDFLAGS) @@ -273,7 +272,8 @@ _sgpem_la_CPPFLAGS = \ $(SWIG_PYTHON_CPPFLAGS) \ $(GLIBMM_CFLAGS) _sgpem_la_LDFLAGS = -module $(GLIBMM_LDFLAGS) -_sgpem_la_LIBADD = src/backend/libbackend.la +_sgpem_la_LIBADD = src/backend/libbackend.la \ + $(GLIBMM_LIBS) _sgpem_la_SOURCES = $(wrappers) EXTRA_DIST += $(_sgpem_la_INTERFACES) @@ -310,3 +310,16 @@ pyc_PYTHON = \ # DEJATOOL = src/testsuite/example-test.exp +noinst_PROGRAMS = test-python_loader + +test_python_loader_CPPFLAGS = \ + -I@top_srcdir@/src \ + -DPYCDIR="\"$(pycdir)\"" \ + -DMODDIR="\"$(moddir)\"" \ + $(PYTHON_CPPFLAGS) \ + $(GLIBMM_CFLAGS) +test_python_loader_LDFLAGS = \ + src/backend/pyloader/libpyloader.la +test_python_loader_SOURCES = \ + src/testsuite/test-python_loader.cc + diff --git a/src/backend/pyloader/ScriptAdapter.py b/src/backend/pyloader/ScriptAdapter.py index 9d72903..e9f45f2 100644 --- a/src/backend/pyloader/ScriptAdapter.py +++ b/src/backend/pyloader/ScriptAdapter.py @@ -1,68 +1,69 @@ import mutex, thread +import sgpem _g_mutex = mutex.mutex() -## @brief This is an adapter class which will dinamically -# inherit from the user-defined policy +## @brief This is an adapter class which acts as a proxy +# for user-implemented policies # -# At runtime, this class will inherit from the user-defined -# policy, and act as a proxy for scheduler calls. It is quite -# useful also to prevent a potentially infinite-looping -# policy to indefinitely hanging the program. +# 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 should be prepared before use -# like this: +# Instantiated in the C++ code, it should be instantiated like: # @code -# '''Please note the ending comma''' -# ScriptAdapter.__bases__ = UserPolicy, -# policy_adapter = ScriptAdapter() +# adapter = ScriptAdapter(UserPolicyClass) # @endcode class ScriptAdapter : - def __init__(self): - pass; + _policy = None + + def __init__(self, policy): + self._policy = policy() + print 'ScriptAdapter for policy ', policy, ' loaded' def async_configure(self): - _g_mutex.lock(_wrap_configure, self) + print 'Calling ', self._policy, ' configure() method.' + _g_mutex.lock(ScriptAdapter._wrap_configure, self ) + print 'Returning from configure() method' def _wrap_configure(self): - thread.start_new_thread(_wrap_configure_callback, (self)) - + thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,)) def _wrap_configure_callback(self): - self.configure() + # call configure method + self._policy.configure() _g_mutex.unlock() - def async_sort_queue(self): - _g_mutex.lock(_wrap_sort_queue, self) + def async_sort_queue(self, event): + _g_mutex.lock(ScriptAdapter._wrap_sort_queue, (self, event)) - def _wrap_sort_queue(self): - thread.start_new_thread(_wrap_sort_queue_callback, (self)) + def _wrap_sort_queue(self, event): + thread.start_new_thread(ScriptAdapter._wrap_sort_queue_callback, (self, event)) - def _wrap_sort_queue_callback(self): - # here we should write the code to pass queue and event to - # the inherited method - self.sort_queue() + 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) _g_mutex.unlock() def async_is_preemptible(self): - _g_mutex.lock(_wrap_is_preemptible, self); + _g_mutex.lock(ScriptAdapter._wrap_is_preemptible, self) def _wrap_is_preemptible(self): - thread.start_new_thread(_wrap_is_preemptible_callback, (self)) + thread.start_new_thread(ScriptAdapter._wrap_is_preemptible_callback, (self,)) def _wrap_is_preemptible_callback(self): - # here we should return the call value - self.is_preemptible() + # FIXME : here we should return the call value + self._policy.is_preemptible() _g_mutex.unlock() def async_is_timesliced(self): - _g_mutex.lock(_wrap_is_timesliced, self) + _g_mutex.lock(ScriptAdapter._wrap_is_timesliced, self) def _wrap_is_timesliced(self): - thread.start_new_thread(_wrap_is_timesliced_callback, (self)) + thread.start_new_thread(ScriptAdapter._wrap_is_timesliced_callback, (self,)) def _wrap_is_timesliced_callback(self): - # return value! - self.is_timesliced() + # FIXME : return value! + self._policy.is_timesliced() _g_mutex.unlock() - - diff --git a/src/backend/pyloader/python_policy_manager.cc b/src/backend/pyloader/python_policy_manager.cc index 1ff7cd3..b542b2d 100644 --- a/src/backend/pyloader/python_policy_manager.cc +++ b/src/backend/pyloader/python_policy_manager.cc @@ -22,7 +22,7 @@ #include #include -#include +#include using namespace sgpem; //static object @@ -33,12 +33,12 @@ PythonPolicyManager::PythonPolicyManager() { } -PythonPolicyManager& +PythonPolicyManager* const PythonPolicyManager::get_instance() { - if(!_instance) - _instance = new PythonPolicyManager(); - return *_instance; + if(!_instance) + _instance = new PythonPolicyManager(); + return _instance; } Policy& @@ -70,16 +70,16 @@ PythonPolicyManager::init() // Black magic at work. // FIXME : Hardcoded policy - char* policy_name = "fcfs_policy"; + char* policy_name = "fcfs"; PyObject* pLoadmeStr = PyString_FromString(policy_name); - PyObject *pModule = PyImport_Import(pLoadmeStr); + PyObject* pModule = PyImport_Import(pLoadmeStr); Py_DECREF(pLoadmeStr); if( !pModule ) { - PyErr_Print(); // Error in import - // FIXME : don't exit abruptly, but fall back gracefully - exit(-1); + PyErr_Print(); // Error in import + // FIXME : don't exit abruptly, but fall back gracefully + exit(-1); } // Dictionary with defined ``symbols'' for .pyc file @@ -88,37 +88,25 @@ PythonPolicyManager::init() // Build up UserPythonScriptAdapter { - std::string py_adapter = std::string("class UserPythonScriptAdapter(") + - policy_name + "):\n" - " def __init__(self):\n" - " pass;\n" - " def async_configure():\n" - " pass;\n" - " def async_sort_queue():\n" - " pass;\n" - " def async_is_preemptible():\n" - " pass;\n" - " def async_is_timesliced():\n" - " pass;\n" - "\n"; - PyRun_SimpleString(py_adapter.c_str()); + // FIXME : Warning!! "import fcfs" shouldn't be here!! + std::string s = std::string("import ") + policy_name + "\n" + "import ScriptAdapter\n" + "_adapter = ScriptAdapter.ScriptAdapter(" + + policy_name + "." + policy_name + ")"; + PyRun_SimpleString(s.c_str()); } - //build SWIG proxy object inside the interpreter - PyRun_SimpleString("py_ad = UserPythonScriptAdapter"); - /* const char *buildPyProcess = - "import proto_process\n" - "p = proto_process.Process(19, 'param')\n" - "#set ownership to C++ code\n" - "p.thisown = 0\n"; - - PyRun_SimpleString(buildPyProcess); - */ + // try code + const char* tryExecute = + "_adapter.async_configure()\n" + "#set ownership to C++ code\n"; + //"_adapter.thisown = 0\n"; + PyRun_SimpleString(tryExecute); Py_DECREF(pModule); - pModule = PyImport_AddModule("__main__"); - pDict = PyModule_GetDict(pModule); + // pModule = PyImport_AddModule("__main__"); + // pDict = PyModule_GetDict(pModule); // PyObject *pPyProcess = PyMapping_GetItemString(pDict, "p"); // assert(pPyProcess); @@ -137,7 +125,5 @@ PythonPolicyManager::init() if(!ret) PyErr_Print(); else Py_DECREF(ret); } - */ - - + */ } diff --git a/src/backend/pyloader/python_policy_manager.hh b/src/backend/pyloader/python_policy_manager.hh index 66c4a34..d0da2d9 100644 --- a/src/backend/pyloader/python_policy_manager.hh +++ b/src/backend/pyloader/python_policy_manager.hh @@ -40,7 +40,7 @@ namespace sgpem void init(); PyObject* get_py_dict(); - static PythonPolicyManager& get_instance(); + static PythonPolicyManager* const get_instance(); private: PythonPolicyManager(); diff --git a/src/backend/sgpem.i b/src/backend/sgpem.i index d84fd8a..4f49015 100644 --- a/src/backend/sgpem.i +++ b/src/backend/sgpem.i @@ -5,6 +5,7 @@ #include "schedulable.hh" #include "schedulable_list.hh" #include "schedulable_status.hh" +#include "scheduler.hh" %} /* NOTE : passing Unicode strings to C++ methods calling them @@ -137,6 +138,7 @@ namespace sgpem { SchedulableList(); SchedulableList(const SchedulableList&); SchedulableList& operator=(const SchedulableList&); + ~SchedulableList(); }; //~ class Schedulable // --------------------------------------------- @@ -161,4 +163,14 @@ namespace sgpem { const Schedulable* get_schedulable() const; }; + // --------------------------------------------- + class Scheduler { + public: + static Scheduler& get_instance(); + SchedulableList* get_ready_queue(); + private: + Scheduler(); + ~Scheduler(); + }; + } //~ namespace sgpem diff --git a/src/builtin-policies/fcfs.py b/src/builtin-policies/fcfs.py index 8d5c584..480a051 100644 --- a/src/builtin-policies/fcfs.py +++ b/src/builtin-policies/fcfs.py @@ -13,12 +13,12 @@ from Policy import Policy # (this makes sense...) ############################### -class fcfs_policy(Policy) : +class fcfs(Policy) : def __init__(self): pass; def configure(self): - pass; + print 'No options to configure for fcfs' def is_preemptive(self): return False diff --git a/src/testsuite/test-python_loader.cc b/src/testsuite/test-python_loader.cc new file mode 100644 index 0000000..ca13390 --- /dev/null +++ b/src/testsuite/test-python_loader.cc @@ -0,0 +1,33 @@ +// 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 "backend/pyloader/python_policy_manager.hh" + +int +main(int, char** ) { + using namespace sgpem; + + PythonPolicyManager* ppm = PythonPolicyManager::get_instance(); + ppm->init(); +}