diff --git a/Makefile.am b/Makefile.am index 19c83a8..db83a96 100644 --- a/Makefile.am +++ b/Makefile.am @@ -206,11 +206,11 @@ src_backend_libbackend_la_SOURCES = \ src/backend/concrete_simulation_statistics.cc \ src/backend/concrete_statistics.cc \ src/backend/concrete_thread_statistics.cc \ + src/backend/cpp_resource_policy_manager.cc \ src/backend/cpu_policies_gatekeeper.cc \ src/backend/cpu_policy.cc \ src/backend/cpu_policy_exception.cc \ src/backend/cpu_policy_manager.cc \ - src/backend/default_resource_policy_manager.cc \ src/backend/dynamic_process.cc \ src/backend/dynamic_request.cc \ src/backend/dynamic_resource.cc \ @@ -268,11 +268,11 @@ src_backend_libbackend_la_SOURCES = \ # Please note that the first listed header is generated by # configure. pkginclude_HEADERS += \ + src/backend/sgpemv2/cpp_resource_policy_manager.hh \ src/backend/sgpemv2/cpu_policies_gatekeeper.hh \ src/backend/sgpemv2/cpu_policy.hh \ src/backend/sgpemv2/cpu_policy_exception.hh \ src/backend/sgpemv2/cpu_policy_manager.hh \ - src/backend/sgpemv2/default_resource_policy_manager.hh \ src/backend/sgpemv2/environment.hh \ src/backend/sgpemv2/global_preferences.hh \ src/backend/sgpemv2/history.hh \ diff --git a/plugins/pyloader/src/python_cpu_policy.hh b/plugins/pyloader/src/python_cpu_policy.hh index 85b7b0f..70a6c5a 100644 --- a/plugins/pyloader/src/python_cpu_policy.hh +++ b/plugins/pyloader/src/python_cpu_policy.hh @@ -36,14 +36,20 @@ namespace sgpem { - /** \brief A specialization of abstract class Policy - - Implements the Policy abstract class specified in the backend component to allow - user-written Python policies to run. - - This class represents a policy written in Python. Its methods interact with Python interpreter. - See the documentation of class Policy for more detailed informations. - */ + /// \brief A specialization of abstract class Policy + /// + /// Implements the Policy abstract class specified in the backend component to allow + /// user-written Python policies to run. + /// + /// This class represents a policy written in Python. Its methods interact + /// with Python interpreter. + /// See the documentation of class Policy for more detailed informations. + /// + /// Since both the methods get_name() and get_description() must be available before + /// backend::Policy activation, then map them to the class name and the return of + /// the __doc__() method, respectively. + /// That information can be obtained statically (without + /// instantiating an object of that class). class PythonCPUPolicy; class PythonCPUPolicyManager; @@ -55,58 +61,123 @@ namespace sgpem /// \brief Constructor taking the name of the policy. /// /// Constructor taking the name of the policy. + /// Perform the first half of the two-staged construction /// - /// \param name the name of the policy + /// A ::PythonPolicy object is instantiated as soon as its ::PythonPolicyManager + /// calls collect_policies(). In order to save memory, since only a small subset + /// of policies can be activated in a given time frame, this constructor only + /// takes care to determine the policy name and description, without actually + /// preparing a separate PyInterpreter and/or PyThreadState. + /// @see activate(). + /// @throw an exception when the policy is malformed and therefore not usable. + /// @param name the name of the policy PythonCPUPolicy(const char* name) throw(MalformedPolicyException); /// \brief Standard virtual destructor /// virtual ~PythonCPUPolicy(); - /** - Calls the method \c async_configure - */ - void configure() throw(UserInterruptException, MalformedPolicyException); + /// \brief Configures the policy, asynchronously. + /// + /// Configures the policy, asynchronously. Calls the method \c async_configure + /// Performs the following operations in this order: - /** - Calls the method \c async_sort_queue - */ - void sort_queue() const throw(UserInterruptException, MalformedPolicyException); + /// -# Erases the content of the PolicyParameters attribute + /// -# Calls associated method async_configure() from the loaded + /// ::ScriptAdapter, which has been properly initialized from the activate() method + /// -# Wait for the async call to return, calling wait_unlock() + /// @throw an exception when the policy is malformed and therefore not usable, + /// or when the policy is taking too long to terminate its work. + /// @see ::CPUPolicy::configure(). + void configure() throw(UserInterruptException, MalformedPolicyException); - /** - \returns A textual description of this policy. - */ - Glib::ustring get_description() const; + /// \brief Sorts the queue, asynchronously. + /// + /// Sorts the queue, asynchronously. Calls the method \c async_sort_queue. + /// @throw an exception when the policy is malformed and therefore not usable, + /// or when the policy is taking too long to terminate its work. + /// @see ::CPUPolicy::sort_queue(). + void sort_queue() const throw(UserInterruptException, MalformedPolicyException); - Glib::ustring get_name() const; + /// \brief Returns a textual description of the policy. + /// + /// Returns a textual description of this policy. + /// Tries to get the result of calling __doc__() of the corresponding + /// Python-implemented Policy object, if available. Else, returns the empty string. + /// @return long description of the policy. + /// @see ::CPUPolicy::get_description(). + Glib::ustring get_description() const; - /** - \returns \c TRUE if the policy is preemptive. - \returns \c FALSE if the policy is not preemptive. - */ - bool is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException); + /// \brief Returns a human-readable name of this policy. + /// + /// Returns a human-readable name of this policy. + /// The name of the script file, stripped by its extension -- + /// typically, it's regexp(/.py(c?)/i) + /// @return the name of this policy. + /// @see ::CPUPolicy::get_name(). + Glib::ustring get_name() const; - /** - \returns The integer value of its time-slice. - */ - int get_time_slice() const throw(UserInterruptException, MalformedPolicyException); + /// \brief Returns whether this policy is preemptive or not, asynchronously. + /// + /// Returns whether this policy is preemptive or not, asynchronously. + /// Calls ScriptAdapter::async_is_preemptive(). Waits for an answer into wait_unlock() + /// @throw an exception when the policy is malformed and therefore not usable, + /// or when the policy is taking too long to terminate its work. + /// @return \c TRUE if the policy is preemptive. + /// @return \c FALSE if the policy is not preemptive. + /// @see ::CPUPolicy::is_pre_emptive(). + bool is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException); + /// \brief Returns the lenght of the time slice, asynchronously. + /// + /// Returns the lenght of the time slice, asynchronously. + /// Calls ScriptAdapter::async_get_timeslice(). Waits for an answer into wait_unlock() + /// @throw an exception when the policy is malformed and therefore not usable, + /// or when the policy is taking too long to terminate its work. + /// @return the lenght of the time slice. + /// @see ::CPUPolicy::get_time_slice(). + int get_time_slice() const throw(UserInterruptException, MalformedPolicyException); + + /// \brief Load the corresponding Python module and initialize a new Policy object (in Python). + /// + /// It will have its own PyThreadState and/or PyInterpreter. + /// @throw an exception when the policy is malformed and therefore not usable, + /// or when the policy is taking too long to terminate its work. + /// @see ::CPUPolicy::activate(). void activate() throw(UserInterruptException, MalformedPolicyException); + /// \brief Activates the policy. + /// + /// Cleanup operations to perform before another policy is loaded. + /// @see ::CPUPolicy::deactivate(). void deactivate(); private: PythonCPUPolicy(const PythonCPUPolicy&); PythonCPUPolicy& operator=(const PythonCPUPolicy&); + /// \brief Helps in implementing an asynchronous call to a method. + /// + /// Enters in a loop waiting for a ::ScriptAdapter method to return. If this + /// doesn't happen before a timeout expires, puts Policy and the Python + /// interpreter in a safe state and throws UserInterruptException. + /// + /// After an "async*()" call, the global Python interpreter lock has to be + /// released. This is necessary to let the Python threads to run. + /// After having waited for a specified amount of time (we're polling), + /// the lock is taken again, and we check if the thread has finished via + /// the mutex present in ::ScriptAdapter. If so, wait_unlock() terminates + /// successfully. Else it stays in its main loop. void wait_unlock() const throw(UserInterruptException, MalformedPolicyException); + + /// \brief Returns a brief description of a thrown exception. + /// Returns the description of the exception occurred. static std::string get_exception_information(); static Glib::StaticRecMutex _mtx; PyObject* _upolicy_dict; PyObject* _adapter; - Glib::ustring _name; Glib::ustring _description; }; diff --git a/plugins/pyloader/src/python_cpu_policy_manager.hh b/plugins/pyloader/src/python_cpu_policy_manager.hh index 7a0a7f9..9008e92 100644 --- a/plugins/pyloader/src/python_cpu_policy_manager.hh +++ b/plugins/pyloader/src/python_cpu_policy_manager.hh @@ -31,28 +31,58 @@ namespace sgpem { - //class CPUPolicyManager; + + /// \brief Manages Python user-implemented policies + /// + /// Manages the creation, the organization and the destruction of the + /// cpu policies implemented using Python. + /// + /// It is also responsible for handling malformed policies: as soon as the + /// application detects the presence of a malformed policy, it will ask this + /// class to terminate the Python interpreter and to reinitialize the objects + /// which were previously created by the manager itself. class PythonCPUPolicyManager; - /** \brief Manages Python user-implemented policies - * - * This singleton manages the creation and destruction - * of a Python policy. - */ class SG_DLLEXPORT PythonCPUPolicyManager : public CPUPolicyManager { public: + + /// \brief Standard constructor. + /// + /// Standard constructor. + /// Calls collect_policies() to instantiate all manageable .py policy scripts. PythonCPUPolicyManager(); + + /// \brief Standard virtual destructor. + /// + /// Standard virtual desctuctor. ~PythonCPUPolicyManager(); + /// \brief Returns policies found and instantiated by collect_policies(). + /// + /// Returns policies found and instantiated by collect_policies(). + /// \return the policies found and instantiated by collect_policies(). const std::vector& get_avail_policies(); protected: - /** The selected and active PyhonCPUPolicy object. */ + + /// \brief Scans through directories for loadable Python scripts. + /// + /// Scans through directories for loadable Python scripts. + /// For each found valid python script, tries to load it, and assess if it contains at least a class which: + /// -# type(classname) is of type "classobj" + /// -# classname.__bases is a tuple containing Policy::Policy void collect_policies(); private: + /// \brief Standard copy constructor. + /// + /// Standard private copy constructor. PythonCPUPolicyManager(const PythonCPUPolicyManager&); + + /// \brief Standard private operator assign. + /// + /// Standard private operator assign. PythonCPUPolicyManager& operator=(const PythonCPUPolicyManager&); }; diff --git a/src/backend/default_resource_policy_manager.cc b/src/backend/cpp_resource_policy_manager.cc similarity index 80% rename from src/backend/default_resource_policy_manager.cc rename to src/backend/cpp_resource_policy_manager.cc index ef0b464..ea315f7 100644 --- a/src/backend/default_resource_policy_manager.cc +++ b/src/backend/cpp_resource_policy_manager.cc @@ -1,4 +1,4 @@ -// src/backend/default_resource_policy_manager.cc - Copyright 2005, 2006, University +// src/backend/cpp_resource_policy_manager.cc - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // @@ -19,20 +19,20 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#include #include #include #include #include -#include #include using namespace sgpem; // instantiate a default instance of this class. -DefaultResourcePolicyManager DefaultResourcePolicyManager::_default_instance; +CppResourcePolicyManager CppResourcePolicyManager::_default_instance; -DefaultResourcePolicyManager::DefaultResourcePolicyManager() +CppResourcePolicyManager::CppResourcePolicyManager() { ResourcePoliciesGatekeeper::get_instance().register_manager(this); // Includes default policies. @@ -43,13 +43,13 @@ DefaultResourcePolicyManager::DefaultResourcePolicyManager() } -DefaultResourcePolicyManager::~DefaultResourcePolicyManager() +CppResourcePolicyManager::~CppResourcePolicyManager() { ResourcePoliciesGatekeeper::get_instance().unregister_manager(this); } const std::vector& -DefaultResourcePolicyManager::get_avail_policies() const +CppResourcePolicyManager::get_avail_policies() const { return _policies; } diff --git a/src/backend/resource_policy_fifo.cc b/src/backend/resource_policy_fifo.cc index 14c54ce..b382cfd 100644 --- a/src/backend/resource_policy_fifo.cc +++ b/src/backend/resource_policy_fifo.cc @@ -70,13 +70,13 @@ ResourcePolicyFiFo::enforce(Environment& environment, Environment::SubRequestQue Glib::ustring ResourcePolicyFiFo::get_description() const { - return "A resource policy which satisfies earlier requests before older ones."; + return _("A resource policy which satisfies earlier requests before older ones."); } Glib::ustring ResourcePolicyFiFo::get_name() const { - return "First In, First Out"; + return _("First In, First Out"); } diff --git a/src/backend/resource_policy_lifo.cc b/src/backend/resource_policy_lifo.cc index 9f82ca7..c9e3208 100644 --- a/src/backend/resource_policy_lifo.cc +++ b/src/backend/resource_policy_lifo.cc @@ -82,13 +82,13 @@ ResourcePolicyLiFo::enforce(Environment& environment, Environment::SubRequestQue Glib::ustring ResourcePolicyLiFo::get_description() const { - return "A resource policy which allows a request to be immediately allocated if there is enough space."; + return _("A resource policy which allows a request to be immediately allocated if there is enough space."); } Glib::ustring ResourcePolicyLiFo::get_name() const { - return "Last In, First Out"; + return _("Last In, First Out"); } diff --git a/src/backend/resource_policy_priority.cc b/src/backend/resource_policy_priority.cc index d846ef1..56610d9 100644 --- a/src/backend/resource_policy_priority.cc +++ b/src/backend/resource_policy_priority.cc @@ -85,13 +85,13 @@ ResourcePolicyPriority::enforce(Environment& environment, Environment::SubReques Glib::ustring ResourcePolicyPriority::get_description() const { - return "A resource policy which satisfies higher priority requests before lower priority ones."; + return _("A resource policy which satisfies higher priority requests before lower priority ones."); } Glib::ustring ResourcePolicyPriority::get_name() const { - return "Higher Priority First"; + return _("Higher Priority First"); } diff --git a/src/backend/resource_policy_priority_inheritance.cc b/src/backend/resource_policy_priority_inheritance.cc index f52067f..881ebb7 100644 --- a/src/backend/resource_policy_priority_inheritance.cc +++ b/src/backend/resource_policy_priority_inheritance.cc @@ -98,13 +98,13 @@ ResourcePolicyPriorityInheritance::enforce(Environment& environment, Environment Glib::ustring ResourcePolicyPriorityInheritance::get_description() const { - return "A resource policy which solves the priority inversion problem by raising the priority of a thread to the maximum relative to the queue."; + return _("A resource policy which solves the priority inversion problem by raising the priority of a thread to the maximum relative to the queue."); } Glib::ustring ResourcePolicyPriorityInheritance::get_name() const { - return "Basic Priority Inheritance Protocol"; + return _("Basic Priority Inheritance Protocol"); } diff --git a/src/backend/sgpemv2/cpp_resource_policy_manager.hh b/src/backend/sgpemv2/cpp_resource_policy_manager.hh new file mode 100644 index 0000000..2514f50 --- /dev/null +++ b/src/backend/sgpemv2/cpp_resource_policy_manager.hh @@ -0,0 +1,67 @@ +// src/backend/sgpemv2/cpp_resource_policy_manager.hh - 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 + +#ifndef CPP_RESOURCE_POLICY_MANAGER_HH +#define CPP_RESOURCE_POLICY_MANAGER_HH 1 + +namespace sgpem +{ + class ResourcePolicy; +} + +#include + +#include + +#include + + +namespace sgpem +{ + class CppResourcePolicyManager; + + /** + ResourcePolicyManager is the Abstract Factory for \ref ResourcePolicy objects. + */ + class SG_DLLEXPORT CppResourcePolicyManager : public ResourcePolicyManager + { + public: + /** \brief CppResourcePolicyManager constructor + * + * Registers itself to the ResourcePoliciesGatekeeper singleton. + */ + CppResourcePolicyManager(); + + virtual ~CppResourcePolicyManager(); + + virtual const std::vector& get_avail_policies() const; + + private: + std::vector _policies; + + // an Instance of this class is created by default and it is registered to + // the ResourcePolicyGateKeeper + static CppResourcePolicyManager _default_instance; + }; + +} //~ namespace sgpem + +#endif + diff --git a/src/backend/sgpemv2/default_resource_policy_manager.hh b/src/backend/sgpemv2/default_resource_policy_manager.hh index 5045f1f..2514f50 100644 --- a/src/backend/sgpemv2/default_resource_policy_manager.hh +++ b/src/backend/sgpemv2/default_resource_policy_manager.hh @@ -1,4 +1,4 @@ -// src/backend/default_resource_policy_manager.hh - Copyright 2005, 2006, University +// src/backend/sgpemv2/cpp_resource_policy_manager.hh - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // @@ -18,8 +18,8 @@ // along with SGPEMv2; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#ifndef DEFAULT_RESOURCE_POLICY_MANAGER_HH -#define DEFAULT_RESOURCE_POLICY_MANAGER_HH 1 +#ifndef CPP_RESOURCE_POLICY_MANAGER_HH +#define CPP_RESOURCE_POLICY_MANAGER_HH 1 namespace sgpem { @@ -35,21 +35,21 @@ namespace sgpem namespace sgpem { - class DefaultResourcePolicyManager; + class CppResourcePolicyManager; /** ResourcePolicyManager is the Abstract Factory for \ref ResourcePolicy objects. */ - class SG_DLLEXPORT DefaultResourcePolicyManager : public ResourcePolicyManager + class SG_DLLEXPORT CppResourcePolicyManager : public ResourcePolicyManager { public: - /** \brief DefaultResourcePolicyManager constructor + /** \brief CppResourcePolicyManager constructor * * Registers itself to the ResourcePoliciesGatekeeper singleton. */ - DefaultResourcePolicyManager(); + CppResourcePolicyManager(); - virtual ~DefaultResourcePolicyManager(); + virtual ~CppResourcePolicyManager(); virtual const std::vector& get_avail_policies() const; @@ -58,7 +58,7 @@ namespace sgpem // an Instance of this class is created by default and it is registered to // the ResourcePolicyGateKeeper - static DefaultResourcePolicyManager _default_instance; + static CppResourcePolicyManager _default_instance; }; } //~ namespace sgpem diff --git a/src/backend/sgpemv2/resource_policy_priority.hh b/src/backend/sgpemv2/resource_policy_priority.hh index a216656..1d7be05 100644 --- a/src/backend/sgpemv2/resource_policy_priority.hh +++ b/src/backend/sgpemv2/resource_policy_priority.hh @@ -1,4 +1,4 @@ -// src/backend/resource_policy_priority.hh - Copyright 2005, 2006, University +// src/backend/sgpemv2/resource_policy_priority.hh - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics //