- Request queues are now correctly managed by the ConcreteEnvironment

copy constructor and by the add_resource and remove_resource methods
  found in ConcreteHistory.
- Scheduler now adds the requests in the queue when appropriate, and
  removes them when exhausted.
- Still to implement the management of the state of requests depending
  on their position in the queue
- Still to implement the way threads block depending on the state of
  their requests
- step_forward now reuses some bunch of code taken from the prototype


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@824 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
matrevis 2006-08-05 17:09:45 +00:00
parent 132db18b8c
commit efe7dedd61
5 changed files with 360 additions and 105 deletions

View file

@ -21,6 +21,7 @@
#include "concrete_environment.hh"
#include "dynamic_process.hh"
#include "dynamic_resource.hh"
#include "dynamic_sub_request.hh"
#include "sub_request.hh"
#include "thread.hh"
@ -41,16 +42,13 @@ ConcreteEnvironment::ConcreteEnvironment()
ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment& ce) :
Environment(ce), _resources(ce._resources), _processes(), _sched_queue()
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 Marco -> optimization is the root of all evil! We have to
// copy DynamicResource too; this make things simpler (and
// future code modifications to DynamicResource easier))
{
for(Resources::iterator it = _resources.begin(); it != _resources.end(); it++)
it->second = new DynamicResource(dynamic_cast<const DynamicResource&>(*it->second));
@ -64,6 +62,62 @@ ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment& ce) :
for(Processes::const_iterator orig = ce_proc.begin(); orig != ce_proc.end(); orig++)
*dest++ = new DynamicProcess(dynamic_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 = dynamic_cast<DynamicSubRequest&>(**it5);
DynamicSubRequest& _new = dynamic_cast<DynamicSubRequest&>(**it4);
if (&_old.get_core() == &_new.get_core())
{
found = true;
*it5 = *it4;
}
}
}
}
}
}
}
}
@ -115,6 +169,13 @@ ConcreteEnvironment::get_request_queue(resource_key_t resource_key)
return _sreq_queues[resource_key];
}
ConcreteEnvironment::SubRequestQueues&
ConcreteEnvironment::get_subrequest_queues()
{
return _sreq_queues;
}
const ReadyQueue&
ConcreteEnvironment::get_sorted_queue() const
@ -153,40 +214,3 @@ ConcreteEnvironment::~ConcreteEnvironment()
// -------------------------------- TO BE FIXED ----------------
// Prepare subrequest list for each resource:
// Requests request_queue;
// 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;
// // Cyclomatic complexity will go nuts here. Feel the love. _ALL_ of it.
// 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++)
// {
// const v4_t& subr = (*it3)->get_subrequests();
// for(it4_t it4 = subr.begin(); it4 != subr.end(); it4++)
// {
// if((*it4)->get_resource_key() == resource_key)
// {
// request_queue.push_back(*it3);
// break;
// }
// }
// }
// }
// }