From 787d24964b4e9517b6c0074a53e47d627b2b2f2b Mon Sep 17 00:00:00 2001 From: tchernobog Date: Sun, 2 Jul 2006 17:38:30 +0000 Subject: [PATCH] - Big swing of untested code, all for you verifiers :-) - Fix ReadyQueue constructor - Change DynamicSubRequest to take an int as a parameter - Implement ConcreteEnvironment::get_request_queue() (my word, it's ugly!) - Please note that it still doesn't compile right: ConcreteHistory and Scheduler need to be radically changed git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@692 3ecf2c5c-341e-0410-92b4-d18e462d057c --- src/backend/concrete_environment.cc | 136 +++++++++++++++++----------- src/backend/concrete_environment.hh | 58 +++++------- src/backend/dynamic_sub_request.cc | 14 ++- src/backend/dynamic_sub_request.hh | 8 +- src/backend/environment.hh | 25 +++-- src/backend/history.hh | 3 +- src/backend/sub_request.hh | 8 +- 7 files changed, 142 insertions(+), 110 deletions(-) diff --git a/src/backend/concrete_environment.cc b/src/backend/concrete_environment.cc index 36d69d3..edb36ad 100644 --- a/src/backend/concrete_environment.cc +++ b/src/backend/concrete_environment.cc @@ -1,4 +1,4 @@ -// src/backend/resource.cc - Copyright 2005, 2006, University +// src/backend/concrete_environment.cc - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // @@ -19,11 +19,18 @@ // 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 "sub_request.hh" +#include "thread.hh" + +#include +#include +#include #include using namespace sgpem; - - +using namespace std; ConcreteEnvironment::ConcreteEnvironment() { @@ -31,43 +38,43 @@ ConcreteEnvironment::ConcreteEnvironment() } - -ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment & c) : - Environment(c), _sched_queue(c._sched_queue) +ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment& ce) : + Environment(ce), _resources(ce._resources), _processes(), _sched_queue() { - // DynamicRequest objects never change, so there is no need to keep - // a separate copy for each instant of the simulation, therefore - // we simply copy the map. - // Actually we may even avoid copiying the map, but this would not - // be worth the effort (too much code to change) - // Anyway, this causes much trouble when coming to destruction, see. - _resources = c._resources; + // 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(*it->second)); + } // DynamicProcess object need to be copied. // The deep copy is guaranteed by the DynamicProcess copy constructor - std::vector::const_iterator iter = c._processes.begin(); - while (iter != c._processes.end()) - { - DynamicProcess * current = dynamic_cast(*iter++); - _processes.push_back(new DynamicProcess(*current)); - } - - // The ready queue needs to be copied, too. - // This implementation relies on the copy constructor - // which is explicit in the initialization list + { + const Processes& ce_proc = ce._processes; + insert_iterator dest(_processes, _processes.begin()); + for(Processes::const_iterator orig = ce_proc.begin(); orig != ce_proc.end(); orig++) + *dest++ = new DynamicProcess(dynamic_cast(**orig)); + } } -const std::vector +const Environment::ConstProcesses ConcreteEnvironment::get_processes() const { - return std::vector(_processes.begin(), _processes.end()); + return ConstProcesses(_processes.begin(), _processes.end()); } -std::vector& +ConcreteEnvironment::Processes& ConcreteEnvironment::get_processes() { return _processes; @@ -75,15 +82,15 @@ ConcreteEnvironment::get_processes() -const std::map +const Environment::ConstResources ConcreteEnvironment::get_resources() const { - return std::map(_resources.begin(), _resources.end()); + return map(_resources.begin(), _resources.end()); } -std::map& +ConcreteEnvironment::Resources& ConcreteEnvironment::get_resources() { return _resources; @@ -91,12 +98,44 @@ ConcreteEnvironment::get_resources() -const std::vector -ConcreteEnvironment::get_request_queue(Resource* resource) const +const Environment::ConstRequests +ConcreteEnvironment::get_request_queue(resource_key_t resource_key) const { - std::vector request_queue; - // TODO: fill that vector, walking over the classes, looking for - // those no-more-valid requests. + ConstRequests request_queue; + + 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; + + // 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() == resource_key) + { + request_queue.push_back(*it3); + break; + } + } + } + } + } + return request_queue; } @@ -120,24 +159,17 @@ ConcreteEnvironment::get_sorted_queue() ConcreteEnvironment::~ConcreteEnvironment() { - std::vector::iterator iter = _processes.begin(); - while (iter != _processes.end()) - { - // This call will invoke the DynamicProcess virtual destructor - // Which will delete on cascade all DynamicThreads and so on. - delete *iter++; - // The iterator is still valid, since the pointed object is not, - // but the pointer is. - } - // After this, the destructor of _sched_queue is invoked - // After that, the destructor of _processes is invoked - // After that, the destructor of _resources is invoked - // The current implementation does not destroy the DynamicResource - // objects, as they are shared among all the DynamicEnvironment - // objects. This means that if none deletes them when deleting the - // last DynamicEnvironment object, we have a memory leak. - // And we do have one, since none by now cares for this. Maybe - // History will. Anyway, this is not nice, so please FIXME. + // This call will invoke the DynamicProcess virtual destructor + // Which will delete on cascade all DynamicThreads and so on. + for_each(_processes.begin(), _processes.end(), ptr_fun(operator delete)); + + // 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) } diff --git a/src/backend/concrete_environment.hh b/src/backend/concrete_environment.hh index b0b6fa3..a6ee378 100644 --- a/src/backend/concrete_environment.hh +++ b/src/backend/concrete_environment.hh @@ -1,4 +1,4 @@ -// src/backend/resource.hh - Copyright 2005, 2006, University +// src/backend/concrete_environment.hh - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // @@ -47,18 +47,18 @@ namespace sgpem { public: + typedef std::vector Processes; + typedef std::map Resources; + /// \brief Standard constructor. /// Builds an empty environment. ConcreteEnvironment(); - - /// \brief Copy constructor. /// Performs a deep copy of all structures. ConcreteEnvironment(const ConcreteEnvironment & c); - /// \brief Returns an indexed set of snapshots of the processes /// Returns a standard vector of Process objects describing /// all the processes of the simulated environment at the @@ -69,8 +69,8 @@ namespace sgpem /// always safe. /// /// \return a constant set of snapshots of processes - virtual const std::vector - get_processes() const; + virtual const ConstProcesses + get_processes() const; @@ -78,8 +78,8 @@ namespace sgpem /// /// \return a set of snapshots of processes /// \see get_processes() - virtual std::vector& - get_processes(); + virtual Processes& + get_processes(); @@ -101,8 +101,8 @@ namespace sgpem /// /// \return a indexed constant set of snapshot of resources. /// \see DynamicSybrequest::get_resource() - virtual const std::map - get_resources() const; + virtual const ConstResources + get_resources() const; @@ -110,8 +110,8 @@ namespace sgpem /// /// \return an indexed set of snapshots of resources /// \see get_resources() - virtual std::map& - get_resources(); + virtual Resources& + get_resources(); @@ -126,10 +126,10 @@ namespace sgpem /// /// \param resource The resource the requests are for /// \return The current ready requests queue. - virtual const std::vector - get_request_queue(Resource * resource) const; - - + virtual const ConstRequests + get_request_queue(resource_key_t resource_key) const; + + /// \brief Returns a snapshot of the current scheduler's ready queue. /// Returns a ReadyQueue object representing the queue @@ -139,7 +139,7 @@ namespace sgpem /// /// \return the current ready queue (constant). virtual const ReadyQueue& - get_sorted_queue() const; + get_sorted_queue() const; @@ -148,46 +148,36 @@ namespace sgpem /// \return the current ready queue. /// \see get_sorted_queue() virtual ReadyQueue& - get_sorted_queue(); - + get_sorted_queue(); + /// \brief The standard virtual destructor. /// The standard virtual destructor. virtual - ~ConcreteEnvironment(); + ~ConcreteEnvironment(); /// \brief Serializes the whole environment. /// \see SerializeVisitor virtual void - serialize(SerializeVisitor& translator) const; - - + serialize(SerializeVisitor& translator) const; private: - /// \brief The container of all Resource objecs. /// Actually contains only DynamicResource objects. // resources come before processes because of // destruction order. See destructor implementation - std::map - _resources; - - + Resources _resources; /// \brief The container of all Process objecs. /// Actually contains only DynamicProcess objects. - std::vector - _processes; - - + Processes _processes; /// \brief The queue of the ready schedulables /// Does not contain the running process. - ReadyQueue - _sched_queue; + ReadyQueue _sched_queue; }; //~ class ConcreteEnvironment diff --git a/src/backend/dynamic_sub_request.cc b/src/backend/dynamic_sub_request.cc index 78f9abd..5c3db7c 100644 --- a/src/backend/dynamic_sub_request.cc +++ b/src/backend/dynamic_sub_request.cc @@ -26,13 +26,11 @@ using namespace sgpem; -DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core, - DynamicResource* resource) : - _static_subrequest(core), _dynamic_resource(resource), - _queue_position(-1) +DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core, resource_key_t key) : + _static_subrequest(core), _resource_key(key), + _queue_position(-1) { assert(core != NULL); - assert(resource != NULL); } bool @@ -43,10 +41,10 @@ DynamicSubRequest::operator==(const SubRequest& op2) const } -DynamicResource& -DynamicSubRequest::get_resource() +SubRequest::resource_key_t +DynamicSubRequest::get_resource_key() const { - return *_dynamic_resource; + return _resource_key; } unsigned int diff --git a/src/backend/dynamic_sub_request.hh b/src/backend/dynamic_sub_request.hh index 43fee13..d14cce6 100644 --- a/src/backend/dynamic_sub_request.hh +++ b/src/backend/dynamic_sub_request.hh @@ -38,11 +38,11 @@ namespace sgpem class SG_DLLLOCAL DynamicSubRequest : public SubRequest { public: - DynamicSubRequest(StaticSubRequest* core, DynamicResource* resource); + DynamicSubRequest(StaticSubRequest* core, resource_key_t resource); virtual bool operator==(const SubRequest& op2) const; - DynamicResource& get_resource(); + resource_key_t get_resource_key() const; unsigned int get_places() const; @@ -55,8 +55,8 @@ namespace sgpem private: memory::smart_ptr _static_subrequest; - DynamicResource* _dynamic_resource; - int _queue_position; + resource_key_t _resource_key; + int _queue_position; }; } diff --git a/src/backend/environment.hh b/src/backend/environment.hh index 9913010..49ed66b 100644 --- a/src/backend/environment.hh +++ b/src/backend/environment.hh @@ -22,8 +22,12 @@ #define ENVIRONMENT_HH 1 #include "config.h" -#include + +#include "sub_request.hh" + #include +#include +#include namespace sgpem { @@ -54,6 +58,11 @@ namespace sgpem class SG_DLLEXPORT Environment { public: + typedef SubRequest::resource_key_t resource_key_t; + + typedef std::vector ConstProcesses; + typedef std::map ConstResources; + typedef std::vector ConstRequests; /// \brief Returns an indexed set of snapshots of the processes /// Returns a standard vector of Process objects describing @@ -62,8 +71,8 @@ namespace sgpem /// /// \return a constant set of snapshots of processes - virtual const std::vector - get_processes() const = 0; + virtual const ConstProcesses + get_processes() const = 0; /// \brief Returns an indexed set of snapshots of the resources @@ -80,8 +89,8 @@ namespace sgpem /// /// \return an indexed constant set of snapshot of resources. - virtual const std::map - get_resources() const = 0; + virtual const ConstResources + get_resources() const = 0; /// \brief Returns a snapshot of the current request queue for a resource. @@ -91,8 +100,8 @@ namespace sgpem /// \param resource the resource the requests are for /// \return the current ready requests queue (constant). - virtual const std::vector - get_request_queue(const Resource * resource) const = 0; + virtual const ConstRequests + get_request_queue(resource_key_t resource_key) const = 0; /// \brief Returns a snapshot of the current scheduler's ready queue. @@ -103,7 +112,7 @@ namespace sgpem /// \return the current ready queue (constant). virtual const ReadyQueue& - get_sorted_queue() const = 0; + get_sorted_queue() const = 0; /// \brief The standard virtual destructor. diff --git a/src/backend/history.hh b/src/backend/history.hh index 69bfbfd..f1d0541 100644 --- a/src/backend/history.hh +++ b/src/backend/history.hh @@ -59,7 +59,8 @@ namespace sgpem typedef unsigned int size_t; typedef unsigned int time_t; typedef int prio_t; - typedef int resource_key_t; + + typedef Environment::resource_key_t resource_key_t; typedef const std::pair ResourcePair; virtual ~History() = 0; diff --git a/src/backend/sub_request.hh b/src/backend/sub_request.hh index 6ee3bec..358fc0c 100644 --- a/src/backend/sub_request.hh +++ b/src/backend/sub_request.hh @@ -32,15 +32,17 @@ namespace sgpem class SG_DLLEXPORT SubRequest { public: + typedef int resource_key_t; + virtual ~SubRequest(); virtual bool operator==(const SubRequest& op2) const = 0; - virtual Resource& get_resource() = 0; + virtual resource_key_t get_resource() = 0; - virtual unsigned int get_places() const = 0; + virtual unsigned int get_places() const = 0; - virtual unsigned int get_length() const = 0; + virtual unsigned int get_length() const = 0; virtual int get_queue_position() const = 0;