infamous st8ad_cast bug. git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@1194 3ecf2c5c-341e-0410-92b4-d18e462d057c
219 lines
6 KiB
C++
219 lines
6 KiB
C++
// 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 <sgpemv2/sub_request.hh>
|
|
#include <sgpemv2/thread.hh>
|
|
|
|
#include <sgpemv2/templates/deletor.tcc>
|
|
#include <sgpemv2/templates/down_cast.tcc>
|
|
#include <sgpemv2/templates/sequences.tcc>
|
|
|
|
#include <algorithm>
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <iterator>
|
|
|
|
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<const DynamicResource&>(*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<Processes> dest(_processes, _processes.begin());
|
|
for (Iseq<Processes::const_iterator> orig = iseq(ce_proc); orig; orig++)
|
|
*dest++ = new DynamicProcess(down_cast<const DynamicProcess&>(**orig));
|
|
}
|
|
|
|
|
|
|
|
// Update the subrequest queues.
|
|
|
|
// for each subrequest
|
|
typedef Processes::const_iterator it1_t;
|
|
|
|
typedef std::vector<Thread*> v2_t;
|
|
typedef v2_t::const_iterator it2_t;
|
|
|
|
typedef std::vector<Request*> v3_t;
|
|
typedef v3_t::const_iterator it3_t;
|
|
|
|
typedef std::vector<SubRequest*> 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<DynamicSubRequest&>(**it5);
|
|
DynamicSubRequest& _new = down_cast<DynamicSubRequest&>(**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<Process>());
|
|
|
|
// 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 ----------------
|
|
|