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&);