- 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
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@ class fcfs(Policy) :
|
|||
return False
|
||||
|
||||
def get_time_slice(self):
|
||||
return -1
|
||||
return -2
|
||||
|
||||
def sort_queue(self, event, queue):
|
||||
cmpf = lambda a, b: \
|
||||
|
|
|
@ -77,8 +77,17 @@ Simulation::run() throw(UserInterruptException)
|
|||
{
|
||||
History& h = History::get_instance();
|
||||
|
||||
if (_state == state_stopped)
|
||||
h.truncate_at(0);
|
||||
switch(_state)
|
||||
{
|
||||
case state_running:
|
||||
// FIXME: write out something, or just ignore user input?
|
||||
return;
|
||||
case state_stopped:
|
||||
h.truncate_at(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_state = state_running;
|
||||
|
||||
|
@ -86,7 +95,7 @@ Simulation::run() throw(UserInterruptException)
|
|||
|
||||
if (_mode)
|
||||
{
|
||||
loop:
|
||||
do {
|
||||
// chech for termination
|
||||
bool all_term = true;
|
||||
smart_ptr<SchedulableList> left = h.get_simulation_status_at(h.get_current_time());
|
||||
|
@ -101,8 +110,8 @@ loop:
|
|||
//by the last execution of upadate()
|
||||
if (all_term)
|
||||
{
|
||||
_state = state_paused;
|
||||
return;
|
||||
_state = state_stopped;
|
||||
return; // Exit from loop
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -116,16 +125,15 @@ loop:
|
|||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
stop();
|
||||
|
||||
throw;
|
||||
stop();
|
||||
throw;
|
||||
}
|
||||
|
||||
//check the state
|
||||
if (_state == state_stopped || _state == state_paused)
|
||||
return;
|
||||
|
||||
goto loop;
|
||||
} while(true);
|
||||
}
|
||||
|
||||
//******* STEP by STEP
|
||||
|
|
Loading…
Reference in New Issue