- 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
This commit is contained in:
tchernobog 2006-02-21 22:57:14 +00:00
parent cc26da0b59
commit 712e14f558
7 changed files with 126 additions and 81 deletions

View File

@ -125,7 +125,8 @@ src_backend_pyloader_libpyloader_la_CXXFLAGS = \
src_backend_pyloader_libpyloader_la_LIBADD = \ src_backend_pyloader_libpyloader_la_LIBADD = \
$(PYTHON_LDFLAGS) \ $(PYTHON_LDFLAGS) \
$(PYTHON_EXTRA_LIBS) \ $(PYTHON_EXTRA_LIBS) \
$(GLIBMM_LIBS) $(GLIBMM_LIBS) \
src/backend/libbackend.la
src_backend_pyloader_libpyloader_la_LDFLAGS = \ src_backend_pyloader_libpyloader_la_LDFLAGS = \
$(PYTHON_EXTRA_LDFLAGS) \ $(PYTHON_EXTRA_LDFLAGS) \
$(LT_LDFLAGS) $(LT_LDFLAGS)
@ -162,8 +163,6 @@ src_backend_libbackend_la_CPPFLAGS = \
$(GLIBMM_CFLAGS) $(GLIBMM_CFLAGS)
src_backend_libbackend_la_CXXFLAGS = \ src_backend_libbackend_la_CXXFLAGS = \
$(VISIB_HIDDEN) $(VISIB_HIDDEN)
src_backend_libbackend_la_LIBADD = \
src/backend/pyloader/libpyloader.la
src_backend_libbackend_la_LDFLAGS = \ src_backend_libbackend_la_LDFLAGS = \
$(GLIBMM_LDFLAGS) \ $(GLIBMM_LDFLAGS) \
$(LT_LDFLAGS) $(LT_LDFLAGS)
@ -273,7 +272,8 @@ _sgpem_la_CPPFLAGS = \
$(SWIG_PYTHON_CPPFLAGS) \ $(SWIG_PYTHON_CPPFLAGS) \
$(GLIBMM_CFLAGS) $(GLIBMM_CFLAGS)
_sgpem_la_LDFLAGS = -module $(GLIBMM_LDFLAGS) _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) _sgpem_la_SOURCES = $(wrappers)
EXTRA_DIST += $(_sgpem_la_INTERFACES) EXTRA_DIST += $(_sgpem_la_INTERFACES)
@ -310,3 +310,16 @@ pyc_PYTHON = \
# DEJATOOL = src/testsuite/example-test.exp # 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

View File

@ -1,68 +1,69 @@
import mutex, thread import mutex, thread
import sgpem
_g_mutex = mutex.mutex() _g_mutex = mutex.mutex()
## @brief This is an adapter class which will dinamically ## @brief This is an adapter class which acts as a proxy
# inherit from the user-defined policy # for user-implemented policies
# #
# At runtime, this class will inherit from the user-defined # At runtime, this class will be initialized with the
# policy, and act as a proxy for scheduler calls. It is quite # user-implemented policy, and then it will proxy the calls
# useful also to prevent a potentially infinite-looping # the policy member functions on a different thread, so
# policy to indefinitely hanging the program. # to ensure asyncronous control.
# #
# Instantiated in the C++ code, it should be prepared before use # Instantiated in the C++ code, it should be instantiated like:
# like this:
# @code # @code
# '''Please note the ending comma''' # adapter = ScriptAdapter(UserPolicyClass)
# ScriptAdapter.__bases__ = UserPolicy,
# policy_adapter = ScriptAdapter()
# @endcode # @endcode
class ScriptAdapter : class ScriptAdapter :
def __init__(self): _policy = None
pass;
def __init__(self, policy):
self._policy = policy()
print 'ScriptAdapter for policy ', policy, ' loaded'
def async_configure(self): 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): 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): def _wrap_configure_callback(self):
self.configure() # call configure method
self._policy.configure()
_g_mutex.unlock() _g_mutex.unlock()
def async_sort_queue(self): def async_sort_queue(self, event):
_g_mutex.lock(_wrap_sort_queue, self) _g_mutex.lock(ScriptAdapter._wrap_sort_queue, (self, event))
def _wrap_sort_queue(self): def _wrap_sort_queue(self, event):
thread.start_new_thread(_wrap_sort_queue_callback, (self)) thread.start_new_thread(ScriptAdapter._wrap_sort_queue_callback, (self, event))
def _wrap_sort_queue_callback(self): def _wrap_sort_queue_callback(self, event):
# here we should write the code to pass queue and event to # here we retrieve and pass the ready queue
# the inherited method queue = sgpem.Scheduler.get_instance().get_ready_queue()
self.sort_queue() self._policy.sort_queue(event, queue)
_g_mutex.unlock() _g_mutex.unlock()
def async_is_preemptible(self): 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): 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): def _wrap_is_preemptible_callback(self):
# here we should return the call value # FIXME : here we should return the call value
self.is_preemptible() self._policy.is_preemptible()
_g_mutex.unlock() _g_mutex.unlock()
def async_is_timesliced(self): 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): 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): def _wrap_is_timesliced_callback(self):
# return value! # FIXME : return value!
self.is_timesliced() self._policy.is_timesliced()
_g_mutex.unlock() _g_mutex.unlock()

View File

@ -22,7 +22,7 @@
#include <string> #include <string>
#include <cassert> #include <cassert>
#include <cstdio> #include <iostream>
using namespace sgpem; using namespace sgpem;
//static object //static object
@ -33,12 +33,12 @@ PythonPolicyManager::PythonPolicyManager()
{ {
} }
PythonPolicyManager& PythonPolicyManager* const
PythonPolicyManager::get_instance() PythonPolicyManager::get_instance()
{ {
if(!_instance) if(!_instance)
_instance = new PythonPolicyManager(); _instance = new PythonPolicyManager();
return *_instance; return _instance;
} }
Policy& Policy&
@ -70,16 +70,16 @@ PythonPolicyManager::init()
// Black magic at work. // Black magic at work.
// FIXME : Hardcoded policy // FIXME : Hardcoded policy
char* policy_name = "fcfs_policy"; char* policy_name = "fcfs";
PyObject* pLoadmeStr = PyString_FromString(policy_name); PyObject* pLoadmeStr = PyString_FromString(policy_name);
PyObject *pModule = PyImport_Import(pLoadmeStr); PyObject* pModule = PyImport_Import(pLoadmeStr);
Py_DECREF(pLoadmeStr); Py_DECREF(pLoadmeStr);
if( !pModule ) if( !pModule )
{ {
PyErr_Print(); // Error in import PyErr_Print(); // Error in import
// FIXME : don't exit abruptly, but fall back gracefully // FIXME : don't exit abruptly, but fall back gracefully
exit(-1); exit(-1);
} }
// Dictionary with defined ``symbols'' for .pyc file // Dictionary with defined ``symbols'' for .pyc file
@ -88,37 +88,25 @@ PythonPolicyManager::init()
// Build up UserPythonScriptAdapter // Build up UserPythonScriptAdapter
{ {
std::string py_adapter = std::string("class UserPythonScriptAdapter(") + // FIXME : Warning!! "import fcfs" shouldn't be here!!
policy_name + "):\n" std::string s = std::string("import ") + policy_name + "\n"
" def __init__(self):\n" "import ScriptAdapter\n"
" pass;\n" "_adapter = ScriptAdapter.ScriptAdapter(" +
" def async_configure():\n" policy_name + "." + policy_name + ")";
" pass;\n" PyRun_SimpleString(s.c_str());
" 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());
} }
//build SWIG proxy object inside the interpreter // try code
PyRun_SimpleString("py_ad = UserPythonScriptAdapter"); const char* tryExecute =
/* const char *buildPyProcess = "_adapter.async_configure()\n"
"import proto_process\n" "#set ownership to C++ code\n";
"p = proto_process.Process(19, 'param')\n" //"_adapter.thisown = 0\n";
"#set ownership to C++ code\n" PyRun_SimpleString(tryExecute);
"p.thisown = 0\n";
PyRun_SimpleString(buildPyProcess);
*/
Py_DECREF(pModule); Py_DECREF(pModule);
pModule = PyImport_AddModule("__main__"); // pModule = PyImport_AddModule("__main__");
pDict = PyModule_GetDict(pModule); // pDict = PyModule_GetDict(pModule);
// PyObject *pPyProcess = PyMapping_GetItemString(pDict, "p"); // PyObject *pPyProcess = PyMapping_GetItemString(pDict, "p");
// assert(pPyProcess); // assert(pPyProcess);
@ -137,7 +125,5 @@ PythonPolicyManager::init()
if(!ret) PyErr_Print(); if(!ret) PyErr_Print();
else Py_DECREF(ret); else Py_DECREF(ret);
} }
*/ */
} }

View File

@ -40,7 +40,7 @@ namespace sgpem
void init(); void init();
PyObject* get_py_dict(); PyObject* get_py_dict();
static PythonPolicyManager& get_instance(); static PythonPolicyManager* const get_instance();
private: private:
PythonPolicyManager(); PythonPolicyManager();

View File

@ -5,6 +5,7 @@
#include "schedulable.hh" #include "schedulable.hh"
#include "schedulable_list.hh" #include "schedulable_list.hh"
#include "schedulable_status.hh" #include "schedulable_status.hh"
#include "scheduler.hh"
%} %}
/* NOTE : passing Unicode strings to C++ methods calling them /* NOTE : passing Unicode strings to C++ methods calling them
@ -137,6 +138,7 @@ namespace sgpem {
SchedulableList(); SchedulableList();
SchedulableList(const SchedulableList&); SchedulableList(const SchedulableList&);
SchedulableList& operator=(const SchedulableList&); SchedulableList& operator=(const SchedulableList&);
~SchedulableList();
}; //~ class Schedulable }; //~ class Schedulable
// --------------------------------------------- // ---------------------------------------------
@ -161,4 +163,14 @@ namespace sgpem {
const Schedulable* get_schedulable() const; const Schedulable* get_schedulable() const;
}; };
// ---------------------------------------------
class Scheduler {
public:
static Scheduler& get_instance();
SchedulableList* get_ready_queue();
private:
Scheduler();
~Scheduler();
};
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -13,12 +13,12 @@ from Policy import Policy
# (this makes sense...) # (this makes sense...)
############################### ###############################
class fcfs_policy(Policy) : class fcfs(Policy) :
def __init__(self): def __init__(self):
pass; pass;
def configure(self): def configure(self):
pass; print 'No options to configure for fcfs'
def is_preemptive(self): def is_preemptive(self):
return False return False

View File

@ -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();
}