From 7d62f4b937b12430d811d069eda04da1199730e6 Mon Sep 17 00:00:00 2001 From: tchernobog Date: Sun, 2 Jul 2006 22:20:03 +0000 Subject: [PATCH] - Mega-update. Take it while it's hot... but my brain's frying! - Fixed all Dynamic and Static entities lacking proper destructors: Dynamic entities need to delete Dynamic children, Static entities need only to delete them from the list of their siblings - Added methods to get Static "core" from Dynamic*. - Now get_core() is a pure virtual function into DynamicSchedulable. A quite nice solution(?), really, if I can say that myself... ;-) - ConcreteHistory is half-implemented. It's the other half that worries me. - TODO: finish off ConcreteHistory, and check that things get destroyed properly (no leaks allowed, use valgrind). - TODO: rework Simulation - TODO: Scheduler rewrite - *A side note*: this code is becoming a mess. I prefer references over pointers, but someone other prefer pointers over references, and what happens is that you've to continously pass from one to another when invoking other methods... this is bad. git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@694 3ecf2c5c-341e-0410-92b4-d18e462d057c --- src/backend/concrete_history.cc | 216 +++++++++++++++++++++++++++++ src/backend/concrete_history.hh | 5 +- src/backend/dynamic_process.cc | 57 ++++---- src/backend/dynamic_process.hh | 20 ++- src/backend/dynamic_request.cc | 61 ++++---- src/backend/dynamic_request.hh | 14 +- src/backend/dynamic_resource.cc | 12 ++ src/backend/dynamic_resource.hh | 5 +- src/backend/dynamic_schedulable.cc | 68 ++------- src/backend/dynamic_schedulable.hh | 78 +++-------- src/backend/dynamic_sub_request.cc | 31 ++++- src/backend/dynamic_sub_request.hh | 13 +- src/backend/dynamic_thread.cc | 67 +++++---- src/backend/dynamic_thread.hh | 12 +- src/backend/history.cc | 12 ++ src/backend/history.hh | 8 +- src/backend/static_process.cc | 30 +++- src/backend/static_process.hh | 23 ++- src/backend/static_request.cc | 11 ++ src/backend/static_schedulable.cc | 36 +---- src/backend/static_schedulable.hh | 31 +---- src/backend/static_sub_request.cc | 11 ++ src/backend/static_sub_request.hh | 2 + src/backend/static_thread.cc | 47 +++---- src/backend/static_thread.hh | 15 +- 25 files changed, 564 insertions(+), 321 deletions(-) diff --git a/src/backend/concrete_history.cc b/src/backend/concrete_history.cc index eb13bcc..bdb1c3f 100644 --- a/src/backend/concrete_history.cc +++ b/src/backend/concrete_history.cc @@ -22,3 +22,219 @@ #include "concrete_history.hh" +#include "static_process.hh" +#include "static_thread.hh" +#include "static_resource.hh" +#include "static_request.hh" +#include "static_sub_request.hh" + +#include "smartp.tcc" + +#include +#include +#include + +using namespace sgpem; +using namespace std; +using memory::smart_ptr; + +ConcreteHistory::ConcreteHistory() + : History(), _snapshots() +{ + _snapshots.push_back(new ConcreteEnvironment()); +} + + +ConcreteHistory::~ConcreteHistory() +{ + for_each(_snapshots.begin(), _snapshots.end(), ptr_fun(operator delete)); +} + + +void +ConcreteHistory::append_new_environment(ConcreteEnvironment* environment) +{ + _snapshots.push_back(environment); +} + + +ConcreteHistory::size_t +ConcreteHistory::get_size() +{ + return _snapshots.size(); +} + + +const ConcreteEnvironment& +ConcreteHistory::get_last_environment() const +{ + // Should always be true: + assert(_snapshots.size() > 0); + return *_snapshots.back(); +} + + +const ConcreteEnvironment& +ConcreteHistory::get_environment_at(position index) const + throw(std::out_of_range) +{ + return *_snapshots.at(index); +} + + +void +ConcreteHistory::remove(resource_key_t resource_key) +{ + ConcreteEnvironment& initial = *_snapshots.front(); + ConcreteEnvironment::Resources& resources = initial.get_resources(); + ConcreteEnvironment::Resources::iterator found = resources.find(resource_key); + if(found == resources.end()) + { + notify_change(); + return; // not found, just return. Can we do this better (without a reset)? + } + + reset(false); + + // FIXME: I'm really tired, check that the next two lines do + // what they're meant to do! + delete found->second; + resources.erase(found); + + +#warning "write me!" + // FIXME write me : check for subrequests to remove + + notify_change(); +} + + +void +ConcreteHistory::remove(const Process& process) +{ + + reset(false); + + ConcreteEnvironment& initial = *_snapshots.front(); + ConcreteEnvironment::Processes& processes = initial.get_processes(); + ConcreteEnvironment::Processes::iterator found = find(processes.begin(), processes.end(), &process); + if(found == processes.end()) + { + notify_change(); + return; // not found, just return. Can we do this better (without a reset)? + } + + // FIXME: I'm really tired, check that the next two lines do + // what they're meant to do! + delete *found; + processes.erase(found); + + notify_change(); +} + + +void +ConcreteHistory::remove(const Thread& thread) +{ +#warning "write me!" +} + + +void +ConcreteHistory::remove(const Request& request) +{ +#warning "write me!" +} + + +void +ConcreteHistory::remove(const SubRequest& subrequest) +{ +#warning "write me!" +} + + +ConcreteHistory::ResourcePair& +ConcreteHistory::add_resource(const Glib::ustring& name, + bool preemptable, + size_t places, + size_t availability) +{ + #warning "write me!" +} + + +DynamicProcess& +ConcreteHistory::add_process(const Glib::ustring& name, + time_t arrival_time, + prio_t base_priority) +{ + reset(false); + + StaticProcess* core = new StaticProcess(name, arrival_time, base_priority); + DynamicProcess* proc = new DynamicProcess(core); + + ConcreteEnvironment::Processes& processes = _snapshots.front()->get_processes(); + processes.push_back(proc); + + notify_change(); +} + + +DynamicThread& +ConcreteHistory::add_thread(const Glib::ustring& name, + Process& parent, + time_t cpu_time, + time_t arrival_time, + prio_t base_priority) +{ + reset(false); + + // Holy cow! *THIS* is ugly!!!! + DynamicProcess& parent_process = dynamic_cast(parent); + StaticProcess& parent_core = parent_process.get_core(); + StaticThread* core = new StaticThread(name, parent_core, cpu_time, arrival_time, base_priority); + DynamicThread* thread = new DynamicThread(core, &parent_process); + + notify_change(); +} + + +DynamicRequest& +ConcreteHistory::add_request(Thread& owner, + time_t instant) +{ +#warning "write me!" +} + + +DynamicSubRequest& +ConcreteHistory::add_subrequest(Request& request, + resource_key_t resource_key, + time_t duration, + size_t places) +{ +#warning "write me!" +} + + +void +ConcreteHistory::reset(bool notify) +{ + Snapshots::iterator it = _snapshots.begin(); + ConcreteEnvironment* model = *it; + + it++; // Skip first environment that we saved + for_each(it, _snapshots.end(), ptr_fun(operator delete)); + _snapshots.clear(); + _snapshots.push_back(new ConcreteEnvironment()); + + // FIXME write code to copy processes and threads and subrequests...... +#warning "write me!" + + delete model; + + if(notify) + notify_change(); +} + diff --git a/src/backend/concrete_history.hh b/src/backend/concrete_history.hh index d6e8af6..9f0b9f6 100644 --- a/src/backend/concrete_history.hh +++ b/src/backend/concrete_history.hh @@ -54,9 +54,9 @@ namespace sgpem virtual void append_new_environment(ConcreteEnvironment* environment); virtual size_t get_size(); virtual const ConcreteEnvironment& get_last_environment() const; - virtual const ConcreteEnvironment& get_environment_at() const throw(std::out_of_range); + virtual const ConcreteEnvironment& get_environment_at(position index) const throw(std::out_of_range); - virtual void remove(const Resource& resource); + virtual void remove(resource_key_t resource_key); virtual void remove(const Process& process); virtual void remove(const Thread& thread); virtual void remove(const Request& request); @@ -74,6 +74,7 @@ namespace sgpem virtual DynamicThread& add_thread(const Glib::ustring& name, Process& parent, + time_t cpu_time, time_t arrival_time = 0, prio_t base_priority = 0); diff --git a/src/backend/dynamic_process.cc b/src/backend/dynamic_process.cc index a1fc875..f722fb8 100644 --- a/src/backend/dynamic_process.cc +++ b/src/backend/dynamic_process.cc @@ -23,13 +23,14 @@ #include "dynamic_thread.hh" #include +#include #include using namespace sgpem; -using std::vector; +using namespace std; -DynamicProcess::DynamicProcess(StaticProcess* core) : - DynamicSchedulable(*core) +DynamicProcess::DynamicProcess(StaticProcess* core) + : DynamicSchedulable(), _core(core) {} DynamicProcess::DynamicProcess(const DynamicProcess &other) : @@ -43,6 +44,11 @@ DynamicProcess::DynamicProcess(const DynamicProcess &other) : _dynamic_threads.push_back(new DynamicThread(*(*it))); } +DynamicProcess::~DynamicProcess() +{ + for_each(_dynamic_threads.begin(), _dynamic_threads.end(), ptr_fun(operator delete)); +} + std::vector DynamicProcess::get_threads() @@ -123,32 +129,6 @@ DynamicProcess::get_state() const return result; } -void -DynamicProcess::remove_thread(Thread* thread) -{ - assert(thread != NULL); - - vector::iterator it; - - it = std::find(_dynamic_threads.begin(), _dynamic_threads.end(), thread); - - if(it != _dynamic_threads.end()) - { - _dynamic_threads.erase(it); - // FIXME remove me and leave the responsibility for deletion to the caller - // (which is?) - delete *it; - } - -} - -void -DynamicProcess::add_thread(DynamicThread* thread) -{ - assert(thread != NULL); - - _dynamic_threads.push_back(thread); -} void DynamicProcess::serialize(SerializeVisitor& translator) const @@ -156,3 +136,22 @@ DynamicProcess::serialize(SerializeVisitor& translator) const //FIXME write this code. I'm predictable, I know } +StaticProcess& +DynamicProcess::get_core() +{ + return *_core; +} + + +const StaticProcess& +DynamicProcess::get_core() const +{ + return *_core; +} + + +std::vector& +DynamicProcess::get_dynamic_threads() +{ + return _dynamic_threads; +} diff --git a/src/backend/dynamic_process.hh b/src/backend/dynamic_process.hh index aa3a850..69070a0 100644 --- a/src/backend/dynamic_process.hh +++ b/src/backend/dynamic_process.hh @@ -23,11 +23,15 @@ #include "config.h" #include "gettext.h" -#include "glibmm/ustring.h" -#include #include "process.hh" #include "dynamic_schedulable.hh" +#include "static_process.hh" + +#include "smartp.tcc" + +#include +#include namespace sgpem { @@ -41,21 +45,25 @@ namespace sgpem public: DynamicProcess(StaticProcess* core); DynamicProcess(const DynamicProcess &other); + virtual ~DynamicProcess(); std::vector get_threads(); state get_state() const; - void remove_thread(Thread* thread); - void add_thread(DynamicThread* thread); - void serialize(SerializeVisitor& translator) const; + virtual StaticProcess& get_core(); + virtual const StaticProcess& get_core() const; + + // Does also the job of "add_thread" and "remove_thread" + std::vector& get_dynamic_threads(); + private: + memory::smart_ptr _core; std::vector _dynamic_threads; }; } #endif - diff --git a/src/backend/dynamic_request.cc b/src/backend/dynamic_request.cc index c1f1338..0bbcf1a 100644 --- a/src/backend/dynamic_request.cc +++ b/src/backend/dynamic_request.cc @@ -21,13 +21,16 @@ #include "dynamic_request.hh" #include "static_request.hh" #include "dynamic_sub_request.hh" +#include "dynamic_thread.hh" #include "smartp.tcc" +#include +#include #include using namespace sgpem; -using std::vector; +using namespace std; DynamicRequest::DynamicRequest(StaticRequest *core, DynamicThread* owner) : @@ -36,6 +39,17 @@ DynamicRequest::DynamicRequest(StaticRequest *core, { assert(core != NULL); assert(owner != NULL); + owner->get_requests().push_back(this); +} + + +DynamicRequest::~DynamicRequest() +{ + typedef std::vector Requests; + Requests& siblings = _dynamic_thread->get_dynamic_requests(); + siblings.erase(find(siblings.begin(), siblings.end(), this)); + + for_each(_dynamic_subrequests.begin(), _dynamic_subrequests.end(), ptr_fun(operator delete)); } @@ -50,7 +64,14 @@ DynamicRequest::operator==(const Request& op2) const vector DynamicRequest::get_subrequests() { - return vector(_dynamic_subrequests.begin(), _dynamic_subrequests.end()); + return std::vector(_dynamic_subrequests.begin(), _dynamic_subrequests.end()); +} + + +vector& +DynamicRequest::get_dynamic_subrequests() +{ + return _dynamic_subrequests; } DynamicThread& @@ -71,29 +92,6 @@ DynamicRequest::get_current_state() const return _state; } -void -DynamicRequest::add_subrequest(DynamicSubRequest* subreq) -{ - assert(subreq != NULL); - - _dynamic_subrequests.push_back(subreq); -} - -void -DynamicRequest::remove_subrequest(SubRequest* subreq) -{ - assert(subreq != NULL); - - vector::iterator it; - - it = std::find(_dynamic_subrequests.begin(), _dynamic_subrequests.end(), subreq); - - if(it != _dynamic_subrequests.end()) - { - _dynamic_subrequests.erase(it); - delete *it; - } -} void DynamicRequest::serialize(SerializeVisitor& translator) const @@ -101,3 +99,16 @@ DynamicRequest::serialize(SerializeVisitor& translator) const // Let a drunk monkey write this code ;P } + +StaticRequest& +DynamicRequest::get_core() +{ + return *_static_request; +} + + +const StaticRequest& +DynamicRequest::get_core() const +{ + return *_static_request; +} diff --git a/src/backend/dynamic_request.hh b/src/backend/dynamic_request.hh index d8f3467..b32a947 100644 --- a/src/backend/dynamic_request.hh +++ b/src/backend/dynamic_request.hh @@ -42,10 +42,11 @@ namespace sgpem { public: DynamicRequest(StaticRequest *core, DynamicThread* owner); + ~DynamicRequest(); virtual bool operator==(const Request& op2) const; - std::vector get_subrequests(); + virtual std::vector get_subrequests(); DynamicThread& get_thread(); @@ -53,11 +54,16 @@ namespace sgpem state get_current_state() const; - void add_subrequest(DynamicSubRequest* subreq); - void remove_subrequest(SubRequest* subreq); - void serialize(SerializeVisitor& translator) const; + StaticRequest& get_core(); + const StaticRequest& get_core() const; + + // Since this method is visible only by the backend, + // return directly a reference that lets us to + // add and remove subrequests at will. + std::vector& get_dynamic_subrequests(); + private: memory::smart_ptr _static_request; DynamicThread* _dynamic_thread; diff --git a/src/backend/dynamic_resource.cc b/src/backend/dynamic_resource.cc index cc25915..fe55eeb 100644 --- a/src/backend/dynamic_resource.cc +++ b/src/backend/dynamic_resource.cc @@ -58,3 +58,15 @@ DynamicResource::serialize(SerializeVisitor& translator) const // Let a drunk monkey write this code ;P } +StaticResource& +DynamicResource::get_core() +{ + return *_static_resource; +} + + +const StaticResource& +DynamicResource::get_core() const +{ + return *_static_resource; +} diff --git a/src/backend/dynamic_resource.hh b/src/backend/dynamic_resource.hh index fde3aea..09401e0 100644 --- a/src/backend/dynamic_resource.hh +++ b/src/backend/dynamic_resource.hh @@ -27,12 +27,12 @@ #include "smartp.hh" #include "resource.hh" +#include "static_resource.hh" namespace sgpem { class DynamicResource; class SerializeVisitor; - class StaticResource; class SG_DLLLOCAL DynamicResource : public Resource { @@ -46,6 +46,9 @@ namespace sgpem void serialize(SerializeVisitor& translator) const; + StaticResource& get_core(); + const StaticResource& get_core() const; + private: memory::smart_ptr _static_resource; }; diff --git a/src/backend/dynamic_schedulable.cc b/src/backend/dynamic_schedulable.cc index 67b2487..8b7e547 100644 --- a/src/backend/dynamic_schedulable.cc +++ b/src/backend/dynamic_schedulable.cc @@ -27,41 +27,40 @@ using namespace sgpem; using namespace std; -DynamicSchedulable::DynamicSchedulable(StaticSchedulable& obj) : - _time_left(obj.get_total_cpu_time()), _ref(&obj), _last_acquisition(-1), - _last_release(-1), _priority_push(0), _last(-1), - _my_state(state_future) +DynamicSchedulable::DynamicSchedulable() + : _ran_for(0), _last_acquisition(-1), + _last_release(-1), _priority_push(0) {} bool DynamicSchedulable::operator==(const Schedulable& op2) const { assert(dynamic_cast(&op2) != NULL); - return _ref == dynamic_cast(op2)._ref; + return &get_core() == &(dynamic_cast(op2).get_core()); } Glib::ustring DynamicSchedulable::get_name() const { - return _ref->get_name(); + return get_core().get_name(); } unsigned int DynamicSchedulable::get_arrival_time() const { - return _ref->get_arrival_time(); + return get_core().get_arrival_time(); } int DynamicSchedulable::get_base_priority() const { - return _ref->get_priority(); + return get_core().get_priority(); } unsigned int DynamicSchedulable::get_total_cpu_time() const { - return _ref->get_total_cpu_time(); + return get_core().get_total_cpu_time(); } int @@ -70,10 +69,12 @@ DynamicSchedulable::get_priority_push() const return _priority_push; } -void +int DynamicSchedulable::set_priority_push(int new_value) { + int temp = _priority_push; _priority_push = new_value; + return temp; } int @@ -85,13 +86,13 @@ DynamicSchedulable::get_current_priority() const unsigned int DynamicSchedulable::get_remaining_time() const { - return _time_left; + return get_total_cpu_time() - _ran_for; } void DynamicSchedulable::decrease_remaining_time() { - --_time_left; + _ran_for++; } int @@ -118,47 +119,4 @@ DynamicSchedulable::set_last_release(int instant) _last_release = instant; } -int -DynamicSchedulable::get_cpu_time_left() const -{ - return _time_left; -} -void -DynamicSchedulable::give_cpu_time(const int& time) -{ - _time_left -= time; - if (_time_left < 0) - _time_left = 0; -} - -void -DynamicSchedulable::set_last_scheduled(const int& time) -{ - _last = time; -} - -int -DynamicSchedulable::get_last_scheduled() const -{ - return _last; -} - -DynamicSchedulable::state -DynamicSchedulable::get_state() const -{ - return _my_state; -} - -void -DynamicSchedulable::set_state(state s) -{ - _my_state = s; -} - -StaticSchedulable* -DynamicSchedulable::get_schedulable() const -{ - //HACK This is an enormous hack!!! - return (StaticSchedulable*)&(*_ref); -} diff --git a/src/backend/dynamic_schedulable.hh b/src/backend/dynamic_schedulable.hh index 584a47b..dfb4e25 100644 --- a/src/backend/dynamic_schedulable.hh +++ b/src/backend/dynamic_schedulable.hh @@ -25,8 +25,6 @@ #include "schedulable.hh" #include "static_schedulable.hh" -#include "smartp.hh" - namespace sgpem { class DynamicSchedulable; @@ -44,7 +42,7 @@ namespace sgpem { public: /** \brief Object constructor */ - DynamicSchedulable(StaticSchedulable& obj); + DynamicSchedulable(); //DynamicSchedulable(const DynamicSchedulable& obj); //copy constructor @@ -54,85 +52,47 @@ namespace sgpem * actual represented process is the same, and if the status is also the * same. */ - bool operator==(const Schedulable&) const; + virtual bool operator==(const Schedulable&) const; - Glib::ustring get_name() const; + virtual Glib::ustring get_name() const; - void set_name(const Glib::ustring& new_name); + virtual unsigned int get_arrival_time() const; - unsigned int get_arrival_time() const; + virtual int get_base_priority() const; - int get_base_priority() const; + virtual unsigned int get_total_cpu_time() const; - unsigned int get_total_cpu_time() const; + virtual int get_priority_push() const; - int get_priority_push() const; + virtual int set_priority_push(int new_value = 0); - void set_priority_push(int new_value = 0); + virtual int get_current_priority() const; - int get_current_priority() const; + virtual unsigned int get_remaining_time() const; - unsigned int get_remaining_time() const; + virtual void decrease_remaining_time(); - void decrease_remaining_time(); + virtual int get_last_acquisition() const; - int get_last_acquisition() const; + virtual void set_last_acquisition(int instant); - void set_last_acquisition(int instant); + virtual int get_last_release() const; - int get_last_release() const; - - void set_last_release(int instant); - - - /* - FIXME - all following methods are deprecated, drop them - */ - - /** \brief Returns the remaining CPU time */ - int get_cpu_time_left() const; - - /** \brief Decrements cpu time left by this amount until it reaches zero */ - void give_cpu_time(const int& time); - - /** \brief Sets the time when this process was last scheduled */ - void set_last_scheduled(const int& time); - - /** \brief Gets the time when this process was last scheduled */ - int get_last_scheduled() const; - - /** \brief Returns the schedule stack in which this process resides - * \see state */ - state get_state() const; - - /** \brief Sets the state of this process - * \see state - */ - void set_state(state s); - - void serialize(SerializeVisitor& translator) const - {} + virtual void set_last_release(int instant); /** \brief Returns a pointer to the schedulable object * - * This function returns a pointer to the actual schedable object + * This function returns a reference to the actual schedable object * represented, along with its status, by this instance. */ - StaticSchedulable* get_schedulable() const; - - protected: - int _time_left; - memory::smart_ptr _ref; + virtual StaticSchedulable& get_core() = 0; + virtual const StaticSchedulable& get_core() const = 0; private: + int _ran_for; int _last_acquisition; int _last_release; int _priority_push; - - //FIXME deprecated stuff used by deprecated methods - int _last; - state _my_state; }; } diff --git a/src/backend/dynamic_sub_request.cc b/src/backend/dynamic_sub_request.cc index 5c3db7c..aedd9ae 100644 --- a/src/backend/dynamic_sub_request.cc +++ b/src/backend/dynamic_sub_request.cc @@ -19,20 +19,34 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "dynamic_sub_request.hh" +#include "dynamic_request.hh" #include "smartp.tcc" +#include #include using namespace sgpem; -DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core, resource_key_t key) : - _static_subrequest(core), _resource_key(key), +DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core, + DynamicRequest* owner, + resource_key_t key) : + _static_subrequest(core), _owner(owner), _resource_key(key), _queue_position(-1) { assert(core != NULL); + owner->get_subrequests().push_back(this); } + +DynamicSubRequest::~DynamicSubRequest() +{ + typedef std::vector SubRequests; + SubRequests& siblings = _owner->get_dynamic_subrequests(); + siblings.erase(find(siblings.begin(), siblings.end(), this)); +} + + bool DynamicSubRequest::operator==(const SubRequest& op2) const { @@ -77,3 +91,16 @@ DynamicSubRequest::serialize(SerializeVisitor& translator) const //blah blah blah TODO } + +StaticSubRequest& +DynamicSubRequest::get_core() +{ + return *_static_subrequest; +} + + +const StaticSubRequest& +DynamicSubRequest::get_core() const +{ + return *_static_subrequest; +} diff --git a/src/backend/dynamic_sub_request.hh b/src/backend/dynamic_sub_request.hh index d14cce6..fc6f6a1 100644 --- a/src/backend/dynamic_sub_request.hh +++ b/src/backend/dynamic_sub_request.hh @@ -31,14 +31,19 @@ namespace sgpem { class DynamicSubRequest; - class SerializeVisitor; + class DynamicRequest; + class SerializeVisitor; class Resource; class StaticSubRequest; class SG_DLLLOCAL DynamicSubRequest : public SubRequest { public: - DynamicSubRequest(StaticSubRequest* core, resource_key_t resource); + DynamicSubRequest(StaticSubRequest* core, + DynamicRequest* owner, + resource_key_t resource); + + virtual ~DynamicSubRequest(); virtual bool operator==(const SubRequest& op2) const; @@ -53,8 +58,12 @@ namespace sgpem void serialize(SerializeVisitor& translator) const; + StaticSubRequest& get_core(); + const StaticSubRequest& get_core() const; + private: memory::smart_ptr _static_subrequest; + DynamicRequest* _owner; resource_key_t _resource_key; int _queue_position; }; diff --git a/src/backend/dynamic_thread.cc b/src/backend/dynamic_thread.cc index 2461a28..5f11780 100644 --- a/src/backend/dynamic_thread.cc +++ b/src/backend/dynamic_thread.cc @@ -21,17 +21,22 @@ #include "dynamic_thread.hh" #include "static_thread.hh" #include "dynamic_request.hh" + +#include +#include #include #include "smartp.tcc" using namespace sgpem; -using std::vector; +using namespace std; -DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) : - DynamicSchedulable(*core), _state(state_future), _parent(parent) -{} +DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) + : DynamicSchedulable(), _core(core), _state(state_future), _parent(parent) +{ + parent->get_threads().push_back(this); +} DynamicThread::DynamicThread(const DynamicThread &other) : Schedulable(), DynamicSchedulable(other), Thread() @@ -47,6 +52,16 @@ DynamicThread::DynamicThread(const DynamicThread &other) : _dynamic_requests.push_back(new DynamicRequest(*(*it))); } +DynamicThread::~DynamicThread() +{ + typedef std::vector Threads; + Threads& siblings = _parent->get_dynamic_threads(); + siblings.erase(find(siblings.begin(), siblings.end(), this)); + + for_each(_dynamic_requests.begin(), _dynamic_requests.end(), ptr_fun(operator delete)); +} + + DynamicProcess& DynamicThread::get_process() { @@ -74,33 +89,27 @@ DynamicThread::get_requests() return vector(_dynamic_requests.begin(), _dynamic_requests.end()); } -void -DynamicThread::remove_request(Request* request) -{ - assert(request != NULL); - - vector::iterator it; - - it = std::find(_dynamic_requests.begin(), _dynamic_requests.end(), request); - - if(it != _dynamic_requests.end()) - { - _dynamic_requests.erase(it); - delete *it; - } - -} - -void -DynamicThread::add_request(DynamicRequest* request) -{ - assert(request != NULL); - - _dynamic_requests.push_back(request); -} - void DynamicThread::serialize(SerializeVisitor& translator) const { // TODO fill-in appropriate code } + +StaticThread& +DynamicThread::get_core() +{ + return *_core; +} + +const StaticThread& +DynamicThread::get_core() const +{ + return *_core; +} + + +std::vector& +DynamicThread::get_dynamic_requests() +{ + return _dynamic_requests; +} diff --git a/src/backend/dynamic_thread.hh b/src/backend/dynamic_thread.hh index 6195849..7a1d221 100644 --- a/src/backend/dynamic_thread.hh +++ b/src/backend/dynamic_thread.hh @@ -45,6 +45,7 @@ namespace sgpem public: DynamicThread(StaticThread* core, DynamicProcess* parent); DynamicThread(const DynamicThread &other); + virtual ~DynamicThread(); DynamicProcess& get_process(); @@ -54,13 +55,16 @@ namespace sgpem std::vector get_requests(); - void remove_request(Request* request); - - void add_request(DynamicRequest* request); - void serialize(SerializeVisitor& translator) const; + virtual StaticThread& get_core(); + virtual const StaticThread& get_core() const; + + // Does also the job of "add_request" and "remove_request" + std::vector& get_dynamic_requests(); + private: + memory::smart_ptr _core; state _state; std::vector _dynamic_requests; DynamicProcess* _parent; diff --git a/src/backend/history.cc b/src/backend/history.cc index 463be75..438085b 100644 --- a/src/backend/history.cc +++ b/src/backend/history.cc @@ -21,9 +21,12 @@ #include "config.h" #include "history.hh" +#include "history_observer.hh" #include +#include using namespace sgpem; +using namespace std; History::~History() { @@ -44,3 +47,12 @@ History::detach(const HistoryObserver& observer) _observers.end(), &observer)); } + + +void +History::notify_change() +{ + for(RegisteredObservers::iterator it =_observers.begin(); + it != _observers.end(); it++) + (*it)->update(*this); +} diff --git a/src/backend/history.hh b/src/backend/history.hh index f1d0541..52bd765 100644 --- a/src/backend/history.hh +++ b/src/backend/history.hh @@ -58,6 +58,7 @@ namespace sgpem public: typedef unsigned int size_t; typedef unsigned int time_t; + typedef unsigned int position; typedef int prio_t; typedef Environment::resource_key_t resource_key_t; @@ -66,10 +67,10 @@ namespace sgpem virtual ~History() = 0; virtual size_t get_size() = 0; - virtual const Environment& get_last_environment() const = 0; + virtual const Environment& get_last_environment(position index) const = 0; virtual const Environment& get_environment_at() const throw(std::out_of_range) = 0; - virtual void remove(const Resource& resource) = 0; + virtual void remove(resource_key_t resource_key) = 0; virtual void remove(const Process& process) = 0; virtual void remove(const Thread& thread) = 0; virtual void remove(const Request& request) = 0; @@ -87,6 +88,7 @@ namespace sgpem virtual Thread& add_thread(const Glib::ustring& name, Process& parent, + time_t cpu_time, time_t arrival_time = 0, prio_t base_priority = 0) = 0; @@ -106,7 +108,7 @@ namespace sgpem typedef std::vector RegisteredObservers; RegisteredObservers _observers; - virtual void notify_change() = 0; + virtual void notify_change(); }; //~ class History diff --git a/src/backend/static_process.cc b/src/backend/static_process.cc index cd6bf6e..31faea8 100644 --- a/src/backend/static_process.cc +++ b/src/backend/static_process.cc @@ -22,16 +22,36 @@ using namespace sgpem; -StaticProcess::StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const unsigned int& total, const int& priority) - : StaticSchedulable(name, arrival, total, priority) +StaticProcess::StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const int& priority) + : StaticSchedulable(name, priority), _start_time(arrival) {} + StaticProcess::~StaticProcess() {} -Glib::ustring -StaticProcess::get_type() const + +unsigned int +StaticProcess::get_arrival_time() const { - return "StaticProcess"; + return _start_time; } + +unsigned int +StaticProcess::get_total_cpu_time() const +{ + tyepdef std::vector::iterator ThreadIterator; + + unsigned int result = 0; + for(ThreadIterator it = _threads.begin(); it != _threads.end(); it++) + result += (*it)->get_total_cpu_time(); + return result; +} + + +std::vector& +StaticProcess::get_threads() +{ + return _threads; +} diff --git a/src/backend/static_process.hh b/src/backend/static_process.hh index 62b988b..6ebcc92 100644 --- a/src/backend/static_process.hh +++ b/src/backend/static_process.hh @@ -22,10 +22,12 @@ #define STATIC_PROCESS_HH 1 #include "config.h" -#include "gettext.h" -#include "glibmm/ustring.h" #include "static_schedulable.hh" +#include "static_thread.hh" + +#include +#include namespace sgpem { @@ -39,13 +41,22 @@ namespace sgpem { public: /** \brief Creates a new object with the given parameters. */ - StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const unsigned int& total, const int& priority); + StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const int& priority = 0); + /** \brief Destructor. */ - ~StaticProcess(); - /** \brief Returns a string describing the type of the object. */ - Glib::ustring get_type() const; + virtual ~StaticProcess(); + + virtual unsigned int get_total_cpu_time() const; + virtual unsigned int get_arrival_time() const; + + // Does the job also of add_thread() and remove_thread(). :-) + // Since we're touching backend internals, we can do this safely + // (because we know what we're doing, isn't it?) + virtual std::vector& get_threads(); private: + unsigned int _start_time; + std::vector _threads; }; } diff --git a/src/backend/static_request.cc b/src/backend/static_request.cc index cdca74d..a1d1127 100644 --- a/src/backend/static_request.cc +++ b/src/backend/static_request.cc @@ -19,15 +19,26 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "static_request.hh" + +#include #include using namespace sgpem; +using namespace std; StaticRequest::StaticRequest(StaticThread* thread, unsigned int instant) : _thread(thread), _instant(instant) { assert(thread != NULL); + _thread->get_requests().push_back(this); +} + +StaticRequest::~StaticRequest() +{ + typedef std::vector Requests; + Requests& siblings = _thread->get_requests(); + siblings.erase(find(siblings.begin(), siblings.end(), this)); } unsigned int diff --git a/src/backend/static_schedulable.cc b/src/backend/static_schedulable.cc index 803f72b..20964c7 100644 --- a/src/backend/static_schedulable.cc +++ b/src/backend/static_schedulable.cc @@ -23,33 +23,14 @@ using namespace sgpem; StaticSchedulable::StaticSchedulable(const Glib::ustring& name, - const unsigned int& arrival, - const unsigned int& total, const int& priority) : - _name(name), _arrival_time(arrival), _total_time(total), _priority(priority) + _name(name), _priority(priority) {} + StaticSchedulable::~StaticSchedulable() {} -unsigned int -StaticSchedulable::get_arrival_time() const -{ - return _arrival_time; -} - -void -StaticSchedulable::set_arrival_time(unsigned int new_time) -{ - _arrival_time = new_time; -} - -unsigned int -StaticSchedulable::get_total_cpu_time() const -{ - return _total_time; -} - int StaticSchedulable::get_priority() const @@ -57,20 +38,9 @@ StaticSchedulable::get_priority() const return _priority; } -void -StaticSchedulable::set_priority(int new_priority) -{ - _priority = new_priority; -} -Glib::ustring +const Glib::ustring& StaticSchedulable::get_name() const { return _name; } - -void -StaticSchedulable::set_name(const Glib::ustring& new_name) -{ - _name = new_name; -} diff --git a/src/backend/static_schedulable.hh b/src/backend/static_schedulable.hh index 6a1a9e1..daea108 100644 --- a/src/backend/static_schedulable.hh +++ b/src/backend/static_schedulable.hh @@ -42,8 +42,7 @@ namespace sgpem { public: /** \brief Create a new object with the given parameters */ - StaticSchedulable(const Glib::ustring& name, const unsigned int& arrival, - const unsigned int& total, const int& priority); + StaticSchedulable(const Glib::ustring& name, const int& priority); virtual ~StaticSchedulable(); /** \brief Returns the arrival time for this process @@ -51,45 +50,27 @@ namespace sgpem * The arrival time of a process is the number of time units, starting * from instant zero, at which the process is added on the queue. */ - virtual unsigned int get_arrival_time() const; - - /** - FIXME make me pure virtual when StaticProcess and StaticThread are completed - */ - void set_arrival_time(unsigned int new_time); + virtual unsigned int get_arrival_time() const = 0; /** \brief Returns the amount of CPU time this process is going to require */ - unsigned int get_total_cpu_time() const; + virtual unsigned int get_total_cpu_time() const = 0; /** \brief Returns the priority of this process * * The priority of a process is a number assigned to it when it is * spawned, and never changes for its lifetime. */ - int get_priority() const; - - void set_priority(int new_priority); + virtual int get_priority() const; /** \brief Returns a string representing this object * * The name of a process is a human readable string assigned to it by the * user, that allows it to be quickly recognized. */ - Glib::ustring get_name() const; - - void set_name(const Glib::ustring& new_name); - - /** \brief Returns the type of the process - * - * This is an abstract method as the schedulable type is defined by the - * concrete process, thread, or any other schedulable entity. - */ - virtual Glib::ustring get_type() const = 0; - + virtual const Glib::ustring& get_name() const; + private: Glib::ustring _name; - unsigned int _arrival_time; - unsigned int _total_time; int _priority; }; } diff --git a/src/backend/static_sub_request.cc b/src/backend/static_sub_request.cc index edd69f8..f9fcabf 100644 --- a/src/backend/static_sub_request.cc +++ b/src/backend/static_sub_request.cc @@ -19,6 +19,8 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "static_sub_request.hh" + +#include #include #include @@ -32,6 +34,15 @@ StaticSubRequest::StaticSubRequest(StaticRequest* req, _length(length), _places(places) { assert(req != NULL && resource != NULL); + req->get_subrequests().push_back(this); +} + + +StaticSubRequest::~StaticSubRequest() +{ + typedef std::vector SubRequests; + SubRequests siblings& = _static_request.get_subrequests(); + siblings.erase(find(siblings.begin(), siblings.end(), this); } StaticResource& diff --git a/src/backend/static_sub_request.hh b/src/backend/static_sub_request.hh index 46c1d82..3466193 100644 --- a/src/backend/static_sub_request.hh +++ b/src/backend/static_sub_request.hh @@ -37,6 +37,8 @@ namespace sgpem unsigned int length, unsigned int places = 1); + virtual ~StaticSubRequest(); + StaticResource& get_static_resource(); StaticRequest& get_static_request(); diff --git a/src/backend/static_thread.cc b/src/backend/static_thread.cc index 27748c3..572a64a 100644 --- a/src/backend/static_thread.cc +++ b/src/backend/static_thread.cc @@ -21,19 +21,33 @@ #include "static_thread.hh" #include "static_request.hh" +#include #include using namespace sgpem; -using std::vector; +using namespace std; StaticThread::StaticThread(const Glib::ustring& name, StaticProcess& process, + unsigned int cpu_time, unsigned int arrival_time, int base_priority) : - StaticSchedulable(name, arrival_time, 0, base_priority), - _start_time_delta(arrival_time), _required_cpu_time(0), + StaticSchedulable(name, base_priority), + _start_time_delta(arrival_time), + _required_cpu_time(cpu_time), _process(&process) -{} +{ + process.get_threads().push_back(this); +} + + +StaticThread::~StaticThread() +{ + typedef std::vector Threads; + Threads siblings& = _process.get_threads(); + siblings.erase(find(siblings.begin(), siblings.end(), this); +} + unsigned int StaticThread::get_total_cpu_time() const @@ -53,27 +67,8 @@ StaticThread::get_process() return *_process; } -void -StaticThread::remove_request(StaticRequest* request) +std::vector& +StaticThread::get_requests() { - assert(request != NULL); - - vector::iterator it; - - it = std::find(_static_requests.begin(), _static_requests.end(), request); - - if(it != _static_requests.end()) - { - _static_requests.erase(it); - delete *it; - } + return _requests; } - -void -StaticThread::add_request(StaticRequest* request) -{ - assert(request != NULL); - - _static_requests.push_back(request); -} - diff --git a/src/backend/static_thread.hh b/src/backend/static_thread.hh index 957006f..31ed3aa 100644 --- a/src/backend/static_thread.hh +++ b/src/backend/static_thread.hh @@ -39,18 +39,23 @@ namespace sgpem public: StaticThread(const Glib::ustring& name, StaticProcess& process, + unsigned int cpu_time, unsigned int arrival_time = 0, int base_priority = 0); - unsigned int get_total_cpu_time() const; + virtual ~StaticThread(); - unsigned int get_arrival_time() const; + virtual unsigned int get_total_cpu_time() const; - StaticProcess& get_process(); + virtual unsigned int get_arrival_time() const; - void remove_request(StaticRequest* request); + virtual StaticProcess& get_process(); - void add_request(StaticRequest* request); + // Caller can use directly the vector instead that + // the "remove_request()" and "add_request()" method + // of the design. Since this class is internal to the + // backend anyway, this is okay. + virtual std::vector& get_requests(); private: StaticThread(const StaticThread&);