- Finish implementing async setup for Python policies' access
- Correct method names for the Python policy (design problem?) - Compiles, but can't run it on this machine. I'll test it later (and I expect quite a lot of SIGSEGVs). git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@382 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
882a6acf5e
commit
8f655f2f69
|
@ -50,6 +50,4 @@ namespace sgpem
|
|||
|
||||
}//~ namespace sgpem
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -41,22 +41,21 @@ namespace sgpem
|
|||
class SG_DLLEXPORT Policy
|
||||
{
|
||||
public:
|
||||
virtual ~Policy();
|
||||
|
||||
virtual void configure() = 0;
|
||||
virtual void sort_queue(sgpem::Scheduler::event) const = 0;
|
||||
int get_id() const;
|
||||
virtual Glib::ustring get_description() const = 0;
|
||||
virtual bool is_pre_emptive() const = 0;
|
||||
virtual int get_time_slice() const = 0;
|
||||
virtual void set_time_slice(const int&) = 0;
|
||||
|
||||
PolicyParameters& get_parameters();
|
||||
|
||||
|
||||
virtual ~Policy();
|
||||
|
||||
virtual void configure() = 0;
|
||||
virtual void sort_queue(sgpem::Scheduler::event) const = 0;
|
||||
int get_id() const;
|
||||
virtual Glib::ustring get_description() const = 0;
|
||||
virtual bool is_pre_emptive() const = 0;
|
||||
virtual int get_time_slice() const = 0;
|
||||
virtual void set_time_slice(const int&) = 0;
|
||||
|
||||
PolicyParameters& get_parameters();
|
||||
|
||||
protected:
|
||||
PolicyParameters _parameters;
|
||||
int _id;
|
||||
PolicyParameters _parameters;
|
||||
int _id;
|
||||
};
|
||||
|
||||
}//~ namespace sgpem
|
||||
|
|
|
@ -7,5 +7,5 @@ class Policy:
|
|||
configure = AbstractMethod('configure')
|
||||
sort_queue = AbstractMethod('sort_queue')
|
||||
is_preemptive = AbstractMethod('is_preemptive')
|
||||
is_time_sliced = AbstractMethod('is_time_sliced')
|
||||
get_time_slice = AbstractMethod('get_time_slice')
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@ import sgpem
|
|||
|
||||
_g_mutex = mutex.mutex()
|
||||
|
||||
## @val Synchronized return value you can read from C++
|
||||
# when a threaded function returns
|
||||
_ret_val = None
|
||||
|
||||
## @brief This is an adapter class which acts as a proxy
|
||||
# for user-implemented policies
|
||||
#
|
||||
|
@ -29,6 +33,7 @@ class ScriptAdapter :
|
|||
|
||||
def _wrap_configure(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,))
|
||||
|
||||
def _wrap_configure_callback(self):
|
||||
# call configure method
|
||||
self._policy.configure()
|
||||
|
@ -53,17 +58,15 @@ class ScriptAdapter :
|
|||
thread.start_new_thread(ScriptAdapter._wrap_is_preemptible_callback, (self,))
|
||||
|
||||
def _wrap_is_preemptible_callback(self):
|
||||
# FIXME : here we should return the call value
|
||||
self._policy.is_preemptible()
|
||||
_ret_val = self._policy.is_preemptible()
|
||||
_g_mutex.unlock()
|
||||
|
||||
def async_is_timesliced(self):
|
||||
_g_mutex.lock(ScriptAdapter._wrap_is_timesliced, self)
|
||||
def async_get_time_slice(self):
|
||||
_g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self)
|
||||
|
||||
def _wrap_is_timesliced(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_is_timesliced_callback, (self,))
|
||||
def _wrap_get_time_slice(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,))
|
||||
|
||||
def _wrap_is_timesliced_callback(self):
|
||||
# FIXME : return value!
|
||||
self._policy.is_timesliced()
|
||||
def _wrap_get_time_slice_callback(self):
|
||||
_ret_val = self._policy.get_time_slice()
|
||||
_g_mutex.unlock()
|
||||
|
|
|
@ -19,10 +19,159 @@
|
|||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "python_policy.hh"
|
||||
#include <unistd.h>
|
||||
using namespace sgpem;
|
||||
using namespace std;
|
||||
|
||||
PythonPolicy::PythonPolicy()
|
||||
// WARNING : this class needs extensive and above all
|
||||
// *strong* exception checking / handling!
|
||||
|
||||
PythonPolicy::PythonPolicy(const char* name)
|
||||
: _adapter(NULL), _adapter_dict(NULL),
|
||||
_lock(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 even if we decref
|
||||
// its containing module
|
||||
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
|
||||
|
||||
// Save a reference to the global lock
|
||||
_lock = PyDict_GetItemString(_adapter_dict, "_g_mutex");
|
||||
assert(_lock);
|
||||
|
||||
// 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()
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_configure", NULL);
|
||||
Py_DECREF(retval);
|
||||
wait_unlock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicy::sort_queue(Scheduler::event event) const
|
||||
{
|
||||
PyObject* pEvent = PyInt_FromLong(event);
|
||||
PyObject* pMethodName = PyString_FromString("async_sort_queue");
|
||||
PyObject* retval = PyObject_CallMethodObjArgs(_adapter, pMethodName, pEvent, NULL);
|
||||
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 {
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_is_preemptive", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
||||
wait_unlock();
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyDict_GetItemString(_adapter_dict, "_ret_val");
|
||||
return static_cast<bool>(PyInt_AsLong(retval));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PythonPolicy::get_time_slice() const {
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_get_time_slice", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
||||
wait_unlock();
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyDict_GetItemString(_adapter_dict, "_ret_val");
|
||||
return static_cast<int>(PyInt_AsLong(retval));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicy::set_time_slice(const int&)
|
||||
{
|
||||
throw "The design is wrong, and I shouldn't be called.";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicy::wait_unlock() const
|
||||
{
|
||||
PyThreadState *_save;
|
||||
Py_UNBLOCK_THREADS
|
||||
sleep(5); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
|
||||
|
||||
// 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
|
||||
} */
|
||||
|
||||
Py_BLOCK_THREADS
|
||||
}
|
||||
|
|
|
@ -32,28 +32,37 @@
|
|||
|
||||
namespace sgpem
|
||||
{
|
||||
class PythonPolicy;
|
||||
class PythonPolicyManager;
|
||||
|
||||
class PythonPolicy;
|
||||
class PythonPolicyManager;
|
||||
class SG_DLLEXPORT PythonPolicy : public Policy
|
||||
{
|
||||
public:
|
||||
//only PythonPolicyManager can create a PythonPolicy object
|
||||
friend class PythonPolicyManager;
|
||||
|
||||
class SG_DLLEXPORT PythonPolicy : public Policy
|
||||
{
|
||||
public:
|
||||
//only PythonPolicyManager can create a PythonPolicy object
|
||||
friend class PythonPolicyManager;
|
||||
|
||||
void configure() {}
|
||||
void sort_queue(sgpem::Scheduler::event) const {}
|
||||
Glib::ustring get_description() const {}
|
||||
bool is_pre_emptive() const {}
|
||||
int get_time_slice() const {}
|
||||
void set_time_slice(const int&) {}
|
||||
|
||||
private:
|
||||
PythonPolicy();
|
||||
PythonPolicy(const PythonPolicy&);
|
||||
PythonPolicy& operator=(const PythonPolicy&);
|
||||
};
|
||||
virtual ~PythonPolicy();
|
||||
|
||||
void configure();
|
||||
void sort_queue(Scheduler::event) const;
|
||||
Glib::ustring get_description() const;
|
||||
bool is_pre_emptive() const;
|
||||
int get_time_slice() const;
|
||||
void set_time_slice(const int&);
|
||||
|
||||
private:
|
||||
PythonPolicy(const char* name);
|
||||
PythonPolicy(const PythonPolicy&);
|
||||
PythonPolicy& operator=(const PythonPolicy&);
|
||||
|
||||
void wait_unlock() const;
|
||||
|
||||
PyObject* _adapter;
|
||||
PyObject* _adapter_dict;
|
||||
PyObject* _lock;
|
||||
|
||||
Glib::ustring _name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -76,50 +76,7 @@ PythonPolicyManager::init()
|
|||
|
||||
// FIXME : Hardcoded policy name
|
||||
char* policy_name = "fcfs";
|
||||
PyObject* pLoadmeStr = PyString_FromString(policy_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);
|
||||
PyObject* pScriptAdapterDict = PyModule_GetDict(pScriptAdapterModule);
|
||||
assert(pScriptAdapterDict);
|
||||
|
||||
// Now takes the user-defined policy class from pUserPolicyDict
|
||||
PyObject* pPolicyClass = PyDict_GetItemString(pUserPolicyDict, policy_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(pScriptAdapterDict, "ScriptAdapter");
|
||||
PyObject* pAdapterCtorParam = PyTuple_New(1);
|
||||
Py_INCREF(pPolicyClass); // PyTuple_SetItem steals a reference
|
||||
PyTuple_SetItem(pAdapterCtorParam, 0, pPolicyClass);
|
||||
PyObject* pAdapterObject = PyInstance_New(pAdapterClass, pAdapterCtorParam, NULL);
|
||||
|
||||
// try code
|
||||
PyObject_CallMethod(pAdapterObject, "async_configure", NULL);
|
||||
|
||||
PyThreadState *_save;
|
||||
Py_UNBLOCK_THREADS
|
||||
sleep(5); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
|
||||
|
||||
Py_BLOCK_THREADS
|
||||
|
||||
// And now, who's your daddy, huh?
|
||||
PythonPolicy policy(policy_name);
|
||||
policy.configure();
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ class fcfs(Policy) :
|
|||
def is_preemptive(self):
|
||||
return False
|
||||
|
||||
def is_time_sliced(self):
|
||||
return False
|
||||
def get_time_slice(self):
|
||||
return -1
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
# How am I supposed to sort that mess??
|
||||
|
|
Loading…
Reference in New Issue