# src/ScriptAdapter.py - 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 import sys, mutex, thread import sgpem ## @brief This is an adapter class which acts as a proxy # for user-implemented policies # # 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 is created like: # @code # adapter = ScriptAdapter(UserPolicyClass) # @endcode # # @remarks The user shouldn't care about this class at all. class ScriptAdapter : ## @var The policy this ScriptAdapter will use for calls _policy = 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() ## @var The exception raised from the last called user-defined # method. It's value is \c None if no exception were raised _g_last_exception = None ## @brief Constructor of ScriptAdapter # # @param self The caller object # @param policy A user-implemented class inheriting from Policy.Policy def __init__(self, policy): self._policy = policy() print 'ScriptAdapter for policy ', policy, ' loaded' ## @brief Asynchronously call Policy.configure() # # @param self The caller object def async_configure(self): self._g_last_exception = None self._g_mutex.lock(ScriptAdapter._wrap_configure, self ) def _wrap_configure(self): thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,)) def _wrap_configure_callback(self): # call configure method try: self._policy.configure() except: self._g_last_exception = sys.exc_value self._g_mutex.unlock() ## @brief Asynchronously call Policy.sort_queue() # # The queue is asked directly to the C++ sgpem::Scheduler # singleton, via SWIG # # @param self The caller object def async_sort_queue(self): self._g_last_exception = None self._g_mutex.lock(ScriptAdapter._wrap_sort_queue, self) def _wrap_sort_queue(self): thread.start_new_thread(ScriptAdapter._wrap_sort_queue_callback, (self,)) def _wrap_sort_queue_callback(self): # here we retrieve and pass the ready queue queue = sgpem.Scheduler.get_instance().get_ready_queue() try: self._policy.sort_queue(queue) except: # exception raised in user-defined method, # save it so the C++ code can tell the # user what went wrong self._g_last_exception = sys.exc_value self._g_mutex.unlock() ## @brief Asynchronously call Policy.is_preemptive() # # @param self The caller object def async_is_preemptive(self): self._g_last_exception = None self._g_mutex.lock(ScriptAdapter._wrap_is_preemptive, self) def _wrap_is_preemptive(self): thread.start_new_thread(ScriptAdapter._wrap_is_preemptive_callback, (self,)) def _wrap_is_preemptive_callback(self): try: self._ret_val = self._policy.is_preemptive() except: # exception raised in user-defined method, # save it so the C++ code can tell the # user what went wrong self._g_last_exception = sys.exc_value self._g_mutex.unlock() ## @brief Asynchronously call Policy.get_time_slice() # # @param self The caller object def async_get_time_slice(self): self._g_last_exception = None 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): try: self._ret_val = self._policy.get_time_slice() except: # exception raised in user-defined method, # save it so the C++ code can tell the # user what went wrong self._g_last_exception = sys.exc_value 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 mutex_test_lock(self): return self._g_mutex.test() def get_last_exception(self): return self._g_last_exception