- 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:
parent
cc26da0b59
commit
712e14f558
21
Makefile.am
21
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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
Policy&
|
||||
|
@ -70,7 +70,7 @@ 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);
|
||||
Py_DECREF(pLoadmeStr);
|
||||
|
@ -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);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace sgpem
|
|||
void init();
|
||||
PyObject* get_py_dict();
|
||||
|
||||
static PythonPolicyManager& get_instance();
|
||||
static PythonPolicyManager* const get_instance();
|
||||
|
||||
private:
|
||||
PythonPolicyManager();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
Loading…
Reference in New Issue