- 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 = \
$(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

View File

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

View File

@ -22,7 +22,7 @@
#include <string>
#include <cassert>
#include <cstdio>
#include <iostream>
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);
@ -138,6 +126,4 @@ PythonPolicyManager::init()
else Py_DECREF(ret);
}
*/
}

View File

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

View File

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

View File

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

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