// src/backend/cpu_policies_gatekeeper.cc - 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 #include "config.h" #include "cpu_policies_gatekeeper.hh" #include "cpu_policy_manager.hh" #include "cpu_policy.hh" // Include full template definition only in implementation files: #include "singleton.tcc" #include #include using std::vector; using std::map; using std::find; using std::runtime_error; using namespace sgpem; // Explicit template instantiation to allow to export symbols from the DSO. template class SG_DLLEXPORT Singleton; typedef vector::iterator ManagerIterator; typedef map::iterator ActiveIterator; vector CPUPoliciesGatekeeper::get_registered() const { return _registered; } void CPUPoliciesGatekeeper::register_manager(CPUPolicyManager* manager) { assert(manager != NULL); ManagerIterator end = _registered.end(); if (find(_registered.begin(), end, manager) == end) _registered.push_back(manager); } void CPUPoliciesGatekeeper::unregister_manager(CPUPolicyManager* manager) { assert(manager != NULL); ManagerIterator end = _registered.end(); ManagerIterator pos = find(_registered.begin(), end, manager); if (pos != end) { deactivate_policies(*pos); _registered.erase(pos); } } CPUPolicy* CPUPoliciesGatekeeper::get_current_policy(History* history) throw(runtime_error) { assert(history != NULL); ActiveIterator policy = _active_policies.find(history); if (policy == _active_policies.end()) throw runtime_error("No active policy associated with this " "history is available."); return policy->second; } void CPUPoliciesGatekeeper::activate_policy(History *history, CPUPolicy* policy) { assert(history != NULL); ActiveIterator end = _active_policies.end(); ActiveIterator pos = _active_policies.find(history); if (pos != end && pos->second != policy) _active_policies[history]->deactivate(); if(policy == NULL) { _active_policies.erase(pos); return; } if (pos == end || pos->second != policy) { try { // policy->activate() needs already an active policy, because: // * it calls the configure() method on the // insert-your-favourite-scripting-language-here-policy // * which in turn calls the configure() method in the // code written by the user // * which probably uses Simulation to get the _active_ C++ policy, // so it can get its policy_parameters() // ... so **DON'T** play Mr. Clever Dick and swap the following two // lines in an optimization frenzy! Or the user policy WILL fail. _active_policies[history] = policy; policy->activate(); } catch(const CPUPolicyException& e) { // See the comment above to understand why we do this // in this way _active_policies.erase(_active_policies.find(history)); } } } CPUPoliciesGatekeeper::CPUPoliciesGatekeeper() {} void CPUPoliciesGatekeeper::deactivate_policies(CPUPolicyManager* manager) { typedef vector::iterator CPUPolicyIterator; vector avail_policies = manager->get_avail_policies(); CPUPolicyIterator avail_it = avail_policies.begin(); CPUPolicyIterator avail_end = avail_policies.end(); for (; avail_it != avail_end; ++avail_it) { // TODO isn't there a way to write more compact code by using // library utilities? ActiveIterator act_it = _active_policies.begin(); while (act_it != _active_policies.end()) { if (act_it->second == *avail_it) { ActiveIterator removable = act_it++; removable->second->deactivate(); _active_policies.erase(removable); } else act_it++; } } //~ for(avail_it) }