- Partial attempt at fixing PythonPolicies broken return values
git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@525 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
50a5214bb9
commit
3b593e00ae
5 changed files with 54 additions and 44 deletions
|
@ -1,13 +1,6 @@
|
|||
import mutex, thread
|
||||
import sgpem
|
||||
|
||||
## Var Global syncronization object
|
||||
_g_mutex = mutex.mutex()
|
||||
|
||||
## @var 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
|
||||
#
|
||||
|
@ -28,7 +21,13 @@ class ScriptAdapter :
|
|||
|
||||
## @var The event to pass to Policy.sort_queue() after the asynchronous call
|
||||
_event = None
|
||||
|
||||
## @var Synchronized return value you can read from C++
|
||||
# when a threaded function returns
|
||||
_ret_val = None
|
||||
|
||||
## Var Testable syncronization object
|
||||
_g_mutex = mutex.mutex()
|
||||
|
||||
## @brief Constructor of ScriptAdapter
|
||||
#
|
||||
|
@ -43,7 +42,7 @@ class ScriptAdapter :
|
|||
#
|
||||
# @param self The caller object
|
||||
def async_configure(self):
|
||||
_g_mutex.lock(ScriptAdapter._wrap_configure, self )
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_configure, self )
|
||||
|
||||
def _wrap_configure(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,))
|
||||
|
@ -51,7 +50,7 @@ class ScriptAdapter :
|
|||
def _wrap_configure_callback(self):
|
||||
# call configure method
|
||||
self._policy.configure()
|
||||
_g_mutex.unlock()
|
||||
self._g_mutex.unlock()
|
||||
|
||||
|
||||
## @brief Asynchronously call Policy.sort_queue()
|
||||
|
@ -63,7 +62,7 @@ class ScriptAdapter :
|
|||
# @param event The event to pass to sort_queue
|
||||
def async_sort_queue(self, event):
|
||||
self._event = event
|
||||
_g_mutex.lock(ScriptAdapter._wrap_sort_queue, self)
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_sort_queue, self)
|
||||
|
||||
def _wrap_sort_queue(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_sort_queue_callback,
|
||||
|
@ -73,7 +72,7 @@ class ScriptAdapter :
|
|||
# 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()
|
||||
self._g_mutex.unlock()
|
||||
|
||||
|
||||
## @brief Asynchronously call Policy.is_preemptive()
|
||||
|
@ -86,19 +85,25 @@ class ScriptAdapter :
|
|||
thread.start_new_thread(ScriptAdapter._wrap_is_preemptive_callback, (self,))
|
||||
|
||||
def _wrap_is_preemptive_callback(self):
|
||||
_ret_val = self._policy.is_preemptive()
|
||||
_g_mutex.unlock()
|
||||
|
||||
self._ret_val = self._policy.is_preemptive()
|
||||
self._g_mutex.unlock()
|
||||
|
||||
## @brief Asynchronously call Policy.get_time_slice()
|
||||
#
|
||||
# @param self The caller object
|
||||
def async_get_time_slice(self):
|
||||
_g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self)
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self)
|
||||
|
||||
def _wrap_get_time_slice(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,))
|
||||
|
||||
def _wrap_get_time_slice_callback(self):
|
||||
_ret_val = self._policy.get_time_slice()
|
||||
_g_mutex.unlock()
|
||||
self._ret_val = self._policy.get_time_slice()
|
||||
self._g_mutex.unlock()
|
||||
|
||||
## @brief Return the global shared variable with the methods' last return value
|
||||
def get_return_value(self):
|
||||
return self._ret_val
|
||||
|
||||
def test_lock(self):
|
||||
return self._g_mutex.test()
|
||||
|
|
|
@ -31,8 +31,7 @@ using namespace std;
|
|||
// *strong* exception checking / handling!
|
||||
|
||||
PythonPolicy::PythonPolicy(const char* name)
|
||||
: _adapter(NULL), _adapter_dict(NULL),
|
||||
_lock(NULL), _name(name)
|
||||
: _adapter(NULL), _adapter_dict(NULL), _name(name)
|
||||
{
|
||||
PyObject* pLoadmeStr = PyString_FromString(name);
|
||||
PyObject* pUserPolicyModule = PyImport_Import(pLoadmeStr);
|
||||
|
@ -56,18 +55,13 @@ PythonPolicy::PythonPolicy(const char* name)
|
|||
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
|
||||
// We want to keep a reference to it
|
||||
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");
|
||||
|
@ -136,8 +130,10 @@ PythonPolicy::is_pre_emptive() const throw(UserInterruptException)
|
|||
wait_unlock();
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyDict_GetItemString(_adapter_dict, "_ret_val");
|
||||
return PyBool_Check(retval);
|
||||
retval = PyObject_CallMethod(_adapter, "get_return_value", NULL);
|
||||
bool ret = PyObject_IsTrue(retval);
|
||||
Py_DECREF(retval);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,8 +145,10 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException) {
|
|||
wait_unlock();
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyDict_GetItemString(_adapter_dict, "_ret_val");
|
||||
retval = PyObject_CallMethod(_adapter, "get_return_value", NULL);
|
||||
long tmp = PyInt_AsLong(retval);
|
||||
Py_DECREF(retval);
|
||||
|
||||
return tmp < 0 ? numeric_limits<int>::max() : static_cast<int>(tmp);
|
||||
}
|
||||
|
||||
|
@ -169,24 +167,24 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException)
|
|||
usleep(WAIT_FOR); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
|
||||
Py_BLOCK_THREADS;
|
||||
|
||||
PyObject* retval = PyObject_CallMethod(_lock, "test", NULL);
|
||||
still_locked = PyBool_Check(retval);
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "test_lock", NULL);
|
||||
assert(retval);
|
||||
still_locked = PyObject_IsTrue(retval);
|
||||
Py_DECREF(retval);
|
||||
|
||||
if(i++ > WAIT_FOR*12)
|
||||
if(i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
|
||||
{
|
||||
PyThreadState_Clear(_save);
|
||||
PyEval_RestoreThread(_save);
|
||||
|
||||
//Py_UNBLOCK_THREADS;
|
||||
|
||||
|
||||
throw UserInterruptException("User-defined policy is "
|
||||
"taking too long to terminate.");
|
||||
}
|
||||
}
|
||||
while(still_locked);
|
||||
|
||||
|
||||
// What we should really do here:
|
||||
/* do {
|
||||
enable python threads
|
||||
|
|
|
@ -82,7 +82,6 @@ namespace sgpem
|
|||
|
||||
PyObject* _adapter;
|
||||
PyObject* _adapter_dict;
|
||||
PyObject* _lock;
|
||||
|
||||
Glib::ustring _name;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue