// src/backend/concrete_environment.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 "concrete_environment.hh" #include "dynamic_process.hh" #include "dynamic_resource.hh" #include "dynamic_sub_request.hh" #include #include #include #include #include #include #include #include #include using namespace sgpem; using namespace std; ConcreteEnvironment::ConcreteEnvironment() { // Nothing to do here. Really. } ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment& ce) : Environment(ce), _resources(ce._resources), _processes(), _sched_queue(), _sreq_queues(ce._sreq_queues) { // The ReadyQueue won't be copied. Pointers to objects contained into // the ready queue _will_ have changed in the new one. The ready queue // needs to be reset: it is Scheduler that builds it again from time to time. // Update resource pointers in a way you won't like :-) { for (Resources::iterator it = _resources.begin(); it != _resources.end(); it++) it->second = new DynamicResource(down_cast(*it->second)); } // DynamicProcess object need to be copied. // The deep copy is guaranteed by the DynamicProcess copy constructor { const Processes& ce_proc = ce._processes; insert_iterator dest(_processes, _processes.begin()); for (Iseq orig = iseq(ce_proc); orig; orig++) *dest++ = new DynamicProcess(down_cast(**orig)); } // Update the subrequest queues. // for each subrequest typedef Processes::const_iterator it1_t; typedef std::vector v2_t; typedef v2_t::const_iterator it2_t; typedef std::vector v3_t; typedef v3_t::const_iterator it3_t; typedef std::vector v4_t; typedef v4_t::const_iterator it4_t; typedef SubRequestQueue::iterator it5_t; for (it1_t it1 = _processes.begin(); it1 != _processes.end(); it1++) { const v2_t& threads = (*it1)->get_threads(); for (it2_t it2 = threads.begin(); it2 != threads.end(); it2++) { const v3_t& reqs = (*it2)->get_requests(); for (it3_t it3 = reqs.begin(); it3 != reqs.end(); it3++) { // an optimization here: there is no reason in iterating through // future or exausted requests. (Do you know why?) const v4_t& subr = (*it3)->get_subrequests(); for (it4_t it4 = subr.begin(); it4 != subr.end(); it4++) { SubRequest::state curr_state = (*it4)->get_state(); if (curr_state != Request::state_future && curr_state != Request::state_exhausted) { // the subrequest is the following queue: SubRequestQueue & queue = get_request_queue((*it4)->get_resource_key()); // we must replace the old pointer: bool found = false; for (it5_t it5 = queue.begin(); !found && it5 != queue.end(); it5++) { DynamicSubRequest& _old = down_cast(**it5); DynamicSubRequest& _new = down_cast(**it4); if (&_old.get_core() == &_new.get_core()) { found = true; *it5 = *it4; } } } } } } } } const Environment::Processes& ConcreteEnvironment::get_processes() const { return _processes; } ConcreteEnvironment::Processes& ConcreteEnvironment::get_processes() { return _processes; } const Environment::Resources& ConcreteEnvironment::get_resources() const { return _resources; } ConcreteEnvironment::Resources& ConcreteEnvironment::get_resources() { return _resources; } const Environment::SubRequestQueue& ConcreteEnvironment::get_request_queue(resource_key_t resource_key) const { // Should always return something... return _sreq_queues.find(resource_key)->second; } Environment::SubRequestQueue& ConcreteEnvironment::get_request_queue(resource_key_t resource_key) { // Inserts a new element in none is there! return _sreq_queues[resource_key]; } ConcreteEnvironment::SubRequestQueues& ConcreteEnvironment::get_subrequest_queues() { return _sreq_queues; } const ReadyQueue& ConcreteEnvironment::get_sorted_queue() const { return _sched_queue; } ReadyQueue& ConcreteEnvironment::get_sorted_queue() { return _sched_queue; } ConcreteEnvironment::~ConcreteEnvironment() { // This call will invoke the DynamicProcess virtual destructor // Which will delete on cascade all DynamicThreads and so on. for_each(_processes.begin(), _processes.end(), memory::deletor()); // We do the same with Resources. for (Resources::iterator it = _resources.begin(); it != _resources.end(); it++) delete it->second; // After this, the destructor of _sched_queue is invoked (only invalid pointers) // After that, the destructor of _processes is invoked (only invalid pointers) // After that, the destructor of _resources is invoked (only invalid pointers) } // -------------------------------- TO BE FIXED ----------------