- 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
This commit is contained in:
tchernobog 2006-07-02 22:20:03 +00:00
parent 787d24964b
commit 7d62f4b937
25 changed files with 564 additions and 321 deletions

View File

@ -22,3 +22,219 @@
#include "concrete_history.hh" #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 <algorithm>
#include <cassert>
#include <functional>
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<DynamicProcess&>(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();
}

View File

@ -54,9 +54,9 @@ namespace sgpem
virtual void append_new_environment(ConcreteEnvironment* environment); virtual void append_new_environment(ConcreteEnvironment* environment);
virtual size_t get_size(); virtual size_t get_size();
virtual const ConcreteEnvironment& get_last_environment() const; 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 Process& process);
virtual void remove(const Thread& thread); virtual void remove(const Thread& thread);
virtual void remove(const Request& request); virtual void remove(const Request& request);
@ -74,6 +74,7 @@ namespace sgpem
virtual DynamicThread& add_thread(const Glib::ustring& name, virtual DynamicThread& add_thread(const Glib::ustring& name,
Process& parent, Process& parent,
time_t cpu_time,
time_t arrival_time = 0, time_t arrival_time = 0,
prio_t base_priority = 0); prio_t base_priority = 0);

View File

@ -23,13 +23,14 @@
#include "dynamic_thread.hh" #include "dynamic_thread.hh"
#include <algorithm> #include <algorithm>
#include <functional>
#include <cassert> #include <cassert>
using namespace sgpem; using namespace sgpem;
using std::vector; using namespace std;
DynamicProcess::DynamicProcess(StaticProcess* core) : DynamicProcess::DynamicProcess(StaticProcess* core)
DynamicSchedulable(*core) : DynamicSchedulable(), _core(core)
{} {}
DynamicProcess::DynamicProcess(const DynamicProcess &other) : DynamicProcess::DynamicProcess(const DynamicProcess &other) :
@ -43,6 +44,11 @@ DynamicProcess::DynamicProcess(const DynamicProcess &other) :
_dynamic_threads.push_back(new DynamicThread(*(*it))); _dynamic_threads.push_back(new DynamicThread(*(*it)));
} }
DynamicProcess::~DynamicProcess()
{
for_each(_dynamic_threads.begin(), _dynamic_threads.end(), ptr_fun(operator delete));
}
std::vector<Thread*> std::vector<Thread*>
DynamicProcess::get_threads() DynamicProcess::get_threads()
@ -123,32 +129,6 @@ DynamicProcess::get_state() const
return result; return result;
} }
void
DynamicProcess::remove_thread(Thread* thread)
{
assert(thread != NULL);
vector<DynamicThread*>::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 void
DynamicProcess::serialize(SerializeVisitor& translator) const DynamicProcess::serialize(SerializeVisitor& translator) const
@ -156,3 +136,22 @@ DynamicProcess::serialize(SerializeVisitor& translator) const
//FIXME write this code. I'm predictable, I know //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<DynamicThread*>&
DynamicProcess::get_dynamic_threads()
{
return _dynamic_threads;
}

View File

@ -23,11 +23,15 @@
#include "config.h" #include "config.h"
#include "gettext.h" #include "gettext.h"
#include "glibmm/ustring.h"
#include <vector>
#include "process.hh" #include "process.hh"
#include "dynamic_schedulable.hh" #include "dynamic_schedulable.hh"
#include "static_process.hh"
#include "smartp.tcc"
#include <glibmm/ustring.h>
#include <vector>
namespace sgpem namespace sgpem
{ {
@ -41,21 +45,25 @@ namespace sgpem
public: public:
DynamicProcess(StaticProcess* core); DynamicProcess(StaticProcess* core);
DynamicProcess(const DynamicProcess &other); DynamicProcess(const DynamicProcess &other);
virtual ~DynamicProcess();
std::vector<Thread*> get_threads(); std::vector<Thread*> get_threads();
state get_state() const; state get_state() const;
void remove_thread(Thread* thread);
void add_thread(DynamicThread* thread);
void serialize(SerializeVisitor& translator) const; 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<DynamicThread*>& get_dynamic_threads();
private: private:
memory::smart_ptr<StaticProcess> _core;
std::vector<DynamicThread*> _dynamic_threads; std::vector<DynamicThread*> _dynamic_threads;
}; };
} }
#endif #endif

View File

@ -21,13 +21,16 @@
#include "dynamic_request.hh" #include "dynamic_request.hh"
#include "static_request.hh" #include "static_request.hh"
#include "dynamic_sub_request.hh" #include "dynamic_sub_request.hh"
#include "dynamic_thread.hh"
#include "smartp.tcc" #include "smartp.tcc"
#include <algorithm>
#include <functional>
#include <cassert> #include <cassert>
using namespace sgpem; using namespace sgpem;
using std::vector; using namespace std;
DynamicRequest::DynamicRequest(StaticRequest *core, DynamicRequest::DynamicRequest(StaticRequest *core,
DynamicThread* owner) : DynamicThread* owner) :
@ -36,6 +39,17 @@ DynamicRequest::DynamicRequest(StaticRequest *core,
{ {
assert(core != NULL); assert(core != NULL);
assert(owner != NULL); assert(owner != NULL);
owner->get_requests().push_back(this);
}
DynamicRequest::~DynamicRequest()
{
typedef std::vector<DynamicRequest*> 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<SubRequest*> vector<SubRequest*>
DynamicRequest::get_subrequests() DynamicRequest::get_subrequests()
{ {
return vector<SubRequest*>(_dynamic_subrequests.begin(), _dynamic_subrequests.end()); return std::vector<SubRequest*>(_dynamic_subrequests.begin(), _dynamic_subrequests.end());
}
vector<DynamicSubRequest*>&
DynamicRequest::get_dynamic_subrequests()
{
return _dynamic_subrequests;
} }
DynamicThread& DynamicThread&
@ -71,29 +92,6 @@ DynamicRequest::get_current_state() const
return _state; 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<DynamicSubRequest*>::iterator it;
it = std::find(_dynamic_subrequests.begin(), _dynamic_subrequests.end(), subreq);
if(it != _dynamic_subrequests.end())
{
_dynamic_subrequests.erase(it);
delete *it;
}
}
void void
DynamicRequest::serialize(SerializeVisitor& translator) const DynamicRequest::serialize(SerializeVisitor& translator) const
@ -101,3 +99,16 @@ DynamicRequest::serialize(SerializeVisitor& translator) const
// Let a drunk monkey write this code ;P // Let a drunk monkey write this code ;P
} }
StaticRequest&
DynamicRequest::get_core()
{
return *_static_request;
}
const StaticRequest&
DynamicRequest::get_core() const
{
return *_static_request;
}

View File

@ -42,10 +42,11 @@ namespace sgpem
{ {
public: public:
DynamicRequest(StaticRequest *core, DynamicThread* owner); DynamicRequest(StaticRequest *core, DynamicThread* owner);
~DynamicRequest();
virtual bool operator==(const Request& op2) const; virtual bool operator==(const Request& op2) const;
std::vector<SubRequest*> get_subrequests(); virtual std::vector<SubRequest*> get_subrequests();
DynamicThread& get_thread(); DynamicThread& get_thread();
@ -53,11 +54,16 @@ namespace sgpem
state get_current_state() const; state get_current_state() const;
void add_subrequest(DynamicSubRequest* subreq);
void remove_subrequest(SubRequest* subreq);
void serialize(SerializeVisitor& translator) const; 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<DynamicSubRequest*>& get_dynamic_subrequests();
private: private:
memory::smart_ptr<StaticRequest> _static_request; memory::smart_ptr<StaticRequest> _static_request;
DynamicThread* _dynamic_thread; DynamicThread* _dynamic_thread;

View File

@ -58,3 +58,15 @@ DynamicResource::serialize(SerializeVisitor& translator) const
// Let a drunk monkey write this code ;P // Let a drunk monkey write this code ;P
} }
StaticResource&
DynamicResource::get_core()
{
return *_static_resource;
}
const StaticResource&
DynamicResource::get_core() const
{
return *_static_resource;
}

View File

@ -27,12 +27,12 @@
#include "smartp.hh" #include "smartp.hh"
#include "resource.hh" #include "resource.hh"
#include "static_resource.hh"
namespace sgpem namespace sgpem
{ {
class DynamicResource; class DynamicResource;
class SerializeVisitor; class SerializeVisitor;
class StaticResource;
class SG_DLLLOCAL DynamicResource : public Resource class SG_DLLLOCAL DynamicResource : public Resource
{ {
@ -46,6 +46,9 @@ namespace sgpem
void serialize(SerializeVisitor& translator) const; void serialize(SerializeVisitor& translator) const;
StaticResource& get_core();
const StaticResource& get_core() const;
private: private:
memory::smart_ptr<StaticResource> _static_resource; memory::smart_ptr<StaticResource> _static_resource;
}; };

View File

@ -27,41 +27,40 @@
using namespace sgpem; using namespace sgpem;
using namespace std; using namespace std;
DynamicSchedulable::DynamicSchedulable(StaticSchedulable& obj) : DynamicSchedulable::DynamicSchedulable()
_time_left(obj.get_total_cpu_time()), _ref(&obj), _last_acquisition(-1), : _ran_for(0), _last_acquisition(-1),
_last_release(-1), _priority_push(0), _last(-1), _last_release(-1), _priority_push(0)
_my_state(state_future)
{} {}
bool bool
DynamicSchedulable::operator==(const Schedulable& op2) const DynamicSchedulable::operator==(const Schedulable& op2) const
{ {
assert(dynamic_cast<const DynamicSchedulable*>(&op2) != NULL); assert(dynamic_cast<const DynamicSchedulable*>(&op2) != NULL);
return _ref == dynamic_cast<const DynamicSchedulable&>(op2)._ref; return &get_core() == &(dynamic_cast<const DynamicSchedulable&>(op2).get_core());
} }
Glib::ustring Glib::ustring
DynamicSchedulable::get_name() const DynamicSchedulable::get_name() const
{ {
return _ref->get_name(); return get_core().get_name();
} }
unsigned int unsigned int
DynamicSchedulable::get_arrival_time() const DynamicSchedulable::get_arrival_time() const
{ {
return _ref->get_arrival_time(); return get_core().get_arrival_time();
} }
int int
DynamicSchedulable::get_base_priority() const DynamicSchedulable::get_base_priority() const
{ {
return _ref->get_priority(); return get_core().get_priority();
} }
unsigned int unsigned int
DynamicSchedulable::get_total_cpu_time() const DynamicSchedulable::get_total_cpu_time() const
{ {
return _ref->get_total_cpu_time(); return get_core().get_total_cpu_time();
} }
int int
@ -70,10 +69,12 @@ DynamicSchedulable::get_priority_push() const
return _priority_push; return _priority_push;
} }
void int
DynamicSchedulable::set_priority_push(int new_value) DynamicSchedulable::set_priority_push(int new_value)
{ {
int temp = _priority_push;
_priority_push = new_value; _priority_push = new_value;
return temp;
} }
int int
@ -85,13 +86,13 @@ DynamicSchedulable::get_current_priority() const
unsigned int unsigned int
DynamicSchedulable::get_remaining_time() const DynamicSchedulable::get_remaining_time() const
{ {
return _time_left; return get_total_cpu_time() - _ran_for;
} }
void void
DynamicSchedulable::decrease_remaining_time() DynamicSchedulable::decrease_remaining_time()
{ {
--_time_left; _ran_for++;
} }
int int
@ -118,47 +119,4 @@ DynamicSchedulable::set_last_release(int instant)
_last_release = 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);
}

View File

@ -25,8 +25,6 @@
#include "schedulable.hh" #include "schedulable.hh"
#include "static_schedulable.hh" #include "static_schedulable.hh"
#include "smartp.hh"
namespace sgpem namespace sgpem
{ {
class DynamicSchedulable; class DynamicSchedulable;
@ -44,7 +42,7 @@ namespace sgpem
{ {
public: public:
/** \brief Object constructor */ /** \brief Object constructor */
DynamicSchedulable(StaticSchedulable& obj); DynamicSchedulable();
//DynamicSchedulable(const DynamicSchedulable& obj); //copy constructor //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 * actual represented process is the same, and if the status is also the
* same. * 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; virtual void set_last_release(int instant);
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
{}
/** \brief Returns a pointer to the schedulable object /** \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. * represented, along with its status, by this instance.
*/ */
StaticSchedulable* get_schedulable() const; virtual StaticSchedulable& get_core() = 0;
virtual const StaticSchedulable& get_core() const = 0;
protected:
int _time_left;
memory::smart_ptr<StaticSchedulable> _ref;
private: private:
int _ran_for;
int _last_acquisition; int _last_acquisition;
int _last_release; int _last_release;
int _priority_push; int _priority_push;
//FIXME deprecated stuff used by deprecated methods
int _last;
state _my_state;
}; };
} }

View File

@ -19,20 +19,34 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "dynamic_sub_request.hh" #include "dynamic_sub_request.hh"
#include "dynamic_request.hh"
#include "smartp.tcc" #include "smartp.tcc"
#include <algorithm>
#include <cassert> #include <cassert>
using namespace sgpem; using namespace sgpem;
DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core, resource_key_t key) : DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core,
_static_subrequest(core), _resource_key(key), DynamicRequest* owner,
resource_key_t key) :
_static_subrequest(core), _owner(owner), _resource_key(key),
_queue_position(-1) _queue_position(-1)
{ {
assert(core != NULL); assert(core != NULL);
owner->get_subrequests().push_back(this);
} }
DynamicSubRequest::~DynamicSubRequest()
{
typedef std::vector<DynamicSubRequest*> SubRequests;
SubRequests& siblings = _owner->get_dynamic_subrequests();
siblings.erase(find(siblings.begin(), siblings.end(), this));
}
bool bool
DynamicSubRequest::operator==(const SubRequest& op2) const DynamicSubRequest::operator==(const SubRequest& op2) const
{ {
@ -77,3 +91,16 @@ DynamicSubRequest::serialize(SerializeVisitor& translator) const
//blah blah blah TODO //blah blah blah TODO
} }
StaticSubRequest&
DynamicSubRequest::get_core()
{
return *_static_subrequest;
}
const StaticSubRequest&
DynamicSubRequest::get_core() const
{
return *_static_subrequest;
}

View File

@ -31,6 +31,7 @@
namespace sgpem namespace sgpem
{ {
class DynamicSubRequest; class DynamicSubRequest;
class DynamicRequest;
class SerializeVisitor; class SerializeVisitor;
class Resource; class Resource;
class StaticSubRequest; class StaticSubRequest;
@ -38,7 +39,11 @@ namespace sgpem
class SG_DLLLOCAL DynamicSubRequest : public SubRequest class SG_DLLLOCAL DynamicSubRequest : public SubRequest
{ {
public: 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; virtual bool operator==(const SubRequest& op2) const;
@ -53,8 +58,12 @@ namespace sgpem
void serialize(SerializeVisitor& translator) const; void serialize(SerializeVisitor& translator) const;
StaticSubRequest& get_core();
const StaticSubRequest& get_core() const;
private: private:
memory::smart_ptr<StaticSubRequest> _static_subrequest; memory::smart_ptr<StaticSubRequest> _static_subrequest;
DynamicRequest* _owner;
resource_key_t _resource_key; resource_key_t _resource_key;
int _queue_position; int _queue_position;
}; };

View File

@ -21,17 +21,22 @@
#include "dynamic_thread.hh" #include "dynamic_thread.hh"
#include "static_thread.hh" #include "static_thread.hh"
#include "dynamic_request.hh" #include "dynamic_request.hh"
#include <algorithm>
#include <functional>
#include <cassert> #include <cassert>
#include "smartp.tcc" #include "smartp.tcc"
using namespace sgpem; using namespace sgpem;
using std::vector; using namespace std;
DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) : DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent)
DynamicSchedulable(*core), _state(state_future), _parent(parent) : DynamicSchedulable(), _core(core), _state(state_future), _parent(parent)
{} {
parent->get_threads().push_back(this);
}
DynamicThread::DynamicThread(const DynamicThread &other) : DynamicThread::DynamicThread(const DynamicThread &other) :
Schedulable(), DynamicSchedulable(other), Thread() Schedulable(), DynamicSchedulable(other), Thread()
@ -47,6 +52,16 @@ DynamicThread::DynamicThread(const DynamicThread &other) :
_dynamic_requests.push_back(new DynamicRequest(*(*it))); _dynamic_requests.push_back(new DynamicRequest(*(*it)));
} }
DynamicThread::~DynamicThread()
{
typedef std::vector<DynamicThread*> 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& DynamicProcess&
DynamicThread::get_process() DynamicThread::get_process()
{ {
@ -74,33 +89,27 @@ DynamicThread::get_requests()
return vector<Request*>(_dynamic_requests.begin(), _dynamic_requests.end()); return vector<Request*>(_dynamic_requests.begin(), _dynamic_requests.end());
} }
void
DynamicThread::remove_request(Request* request)
{
assert(request != NULL);
vector<DynamicRequest*>::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 void
DynamicThread::serialize(SerializeVisitor& translator) const DynamicThread::serialize(SerializeVisitor& translator) const
{ {
// TODO fill-in appropriate code // TODO fill-in appropriate code
} }
StaticThread&
DynamicThread::get_core()
{
return *_core;
}
const StaticThread&
DynamicThread::get_core() const
{
return *_core;
}
std::vector<DynamicRequest*>&
DynamicThread::get_dynamic_requests()
{
return _dynamic_requests;
}

View File

@ -45,6 +45,7 @@ namespace sgpem
public: public:
DynamicThread(StaticThread* core, DynamicProcess* parent); DynamicThread(StaticThread* core, DynamicProcess* parent);
DynamicThread(const DynamicThread &other); DynamicThread(const DynamicThread &other);
virtual ~DynamicThread();
DynamicProcess& get_process(); DynamicProcess& get_process();
@ -54,13 +55,16 @@ namespace sgpem
std::vector<Request*> get_requests(); std::vector<Request*> get_requests();
void remove_request(Request* request);
void add_request(DynamicRequest* request);
void serialize(SerializeVisitor& translator) const; 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<DynamicRequest*>& get_dynamic_requests();
private: private:
memory::smart_ptr<StaticThread> _core;
state _state; state _state;
std::vector<DynamicRequest*> _dynamic_requests; std::vector<DynamicRequest*> _dynamic_requests;
DynamicProcess* _parent; DynamicProcess* _parent;

View File

@ -21,9 +21,12 @@
#include "config.h" #include "config.h"
#include "history.hh" #include "history.hh"
#include "history_observer.hh"
#include <algorithm> #include <algorithm>
#include <functional>
using namespace sgpem; using namespace sgpem;
using namespace std;
History::~History() History::~History()
{ {
@ -44,3 +47,12 @@ History::detach(const HistoryObserver& observer)
_observers.end(), _observers.end(),
&observer)); &observer));
} }
void
History::notify_change()
{
for(RegisteredObservers::iterator it =_observers.begin();
it != _observers.end(); it++)
(*it)->update(*this);
}

View File

@ -58,6 +58,7 @@ namespace sgpem
public: public:
typedef unsigned int size_t; typedef unsigned int size_t;
typedef unsigned int time_t; typedef unsigned int time_t;
typedef unsigned int position;
typedef int prio_t; typedef int prio_t;
typedef Environment::resource_key_t resource_key_t; typedef Environment::resource_key_t resource_key_t;
@ -66,10 +67,10 @@ namespace sgpem
virtual ~History() = 0; virtual ~History() = 0;
virtual size_t get_size() = 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 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 Process& process) = 0;
virtual void remove(const Thread& thread) = 0; virtual void remove(const Thread& thread) = 0;
virtual void remove(const Request& request) = 0; virtual void remove(const Request& request) = 0;
@ -87,6 +88,7 @@ namespace sgpem
virtual Thread& add_thread(const Glib::ustring& name, virtual Thread& add_thread(const Glib::ustring& name,
Process& parent, Process& parent,
time_t cpu_time,
time_t arrival_time = 0, time_t arrival_time = 0,
prio_t base_priority = 0) = 0; prio_t base_priority = 0) = 0;
@ -106,7 +108,7 @@ namespace sgpem
typedef std::vector<HistoryObserver*> RegisteredObservers; typedef std::vector<HistoryObserver*> RegisteredObservers;
RegisteredObservers _observers; RegisteredObservers _observers;
virtual void notify_change() = 0; virtual void notify_change();
}; //~ class History }; //~ class History

View File

@ -22,16 +22,36 @@
using namespace sgpem; using namespace sgpem;
StaticProcess::StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const unsigned int& total, const int& priority) StaticProcess::StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const int& priority)
: StaticSchedulable(name, arrival, total, priority) : StaticSchedulable(name, priority), _start_time(arrival)
{} {}
StaticProcess::~StaticProcess() 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<Thread*>::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<StaticThread*>&
StaticProcess::get_threads()
{
return _threads;
}

View File

@ -22,10 +22,12 @@
#define STATIC_PROCESS_HH 1 #define STATIC_PROCESS_HH 1
#include "config.h" #include "config.h"
#include "gettext.h"
#include "glibmm/ustring.h"
#include "static_schedulable.hh" #include "static_schedulable.hh"
#include "static_thread.hh"
#include <glibmm/ustring.h>
#include <vector>
namespace sgpem namespace sgpem
{ {
@ -39,13 +41,22 @@ namespace sgpem
{ {
public: public:
/** \brief Creates a new object with the given parameters. */ /** \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. */ /** \brief Destructor. */
~StaticProcess(); virtual ~StaticProcess();
/** \brief Returns a string describing the type of the object. */
Glib::ustring get_type() const; 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<StaticThread*>& get_threads();
private: private:
unsigned int _start_time;
std::vector<StaticThread*> _threads;
}; };
} }

View File

@ -19,15 +19,26 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "static_request.hh" #include "static_request.hh"
#include <algorithm>
#include <cassert> #include <cassert>
using namespace sgpem; using namespace sgpem;
using namespace std;
StaticRequest::StaticRequest(StaticThread* thread, StaticRequest::StaticRequest(StaticThread* thread,
unsigned int instant) : unsigned int instant) :
_thread(thread), _instant(instant) _thread(thread), _instant(instant)
{ {
assert(thread != NULL); assert(thread != NULL);
_thread->get_requests().push_back(this);
}
StaticRequest::~StaticRequest()
{
typedef std::vector<StaticRequest*> Requests;
Requests& siblings = _thread->get_requests();
siblings.erase(find(siblings.begin(), siblings.end(), this));
} }
unsigned int unsigned int

View File

@ -23,33 +23,14 @@
using namespace sgpem; using namespace sgpem;
StaticSchedulable::StaticSchedulable(const Glib::ustring& name, StaticSchedulable::StaticSchedulable(const Glib::ustring& name,
const unsigned int& arrival,
const unsigned int& total,
const int& priority) : const int& priority) :
_name(name), _arrival_time(arrival), _total_time(total), _priority(priority) _name(name), _priority(priority)
{} {}
StaticSchedulable::~StaticSchedulable() 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 int
StaticSchedulable::get_priority() const StaticSchedulable::get_priority() const
@ -57,20 +38,9 @@ StaticSchedulable::get_priority() const
return _priority; return _priority;
} }
void
StaticSchedulable::set_priority(int new_priority)
{
_priority = new_priority;
}
Glib::ustring const Glib::ustring&
StaticSchedulable::get_name() const StaticSchedulable::get_name() const
{ {
return _name; return _name;
} }
void
StaticSchedulable::set_name(const Glib::ustring& new_name)
{
_name = new_name;
}

View File

@ -42,8 +42,7 @@ namespace sgpem
{ {
public: public:
/** \brief Create a new object with the given parameters */ /** \brief Create a new object with the given parameters */
StaticSchedulable(const Glib::ustring& name, const unsigned int& arrival, StaticSchedulable(const Glib::ustring& name, const int& priority);
const unsigned int& total, const int& priority);
virtual ~StaticSchedulable(); virtual ~StaticSchedulable();
/** \brief Returns the arrival time for this process /** \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 * 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. * from instant zero, at which the process is added on the queue.
*/ */
virtual unsigned int get_arrival_time() const; virtual unsigned int get_arrival_time() const = 0;
/**
FIXME make me pure virtual when StaticProcess and StaticThread are completed
*/
void set_arrival_time(unsigned int new_time);
/** \brief Returns the amount of CPU time this process is going to require */ /** \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 /** \brief Returns the priority of this process
* *
* The priority of a process is a number assigned to it when it is * The priority of a process is a number assigned to it when it is
* spawned, and never changes for its lifetime. * spawned, and never changes for its lifetime.
*/ */
int get_priority() const; virtual int get_priority() const;
void set_priority(int new_priority);
/** \brief Returns a string representing this object /** \brief Returns a string representing this object
* *
* The name of a process is a human readable string assigned to it by the * The name of a process is a human readable string assigned to it by the
* user, that allows it to be quickly recognized. * user, that allows it to be quickly recognized.
*/ */
Glib::ustring get_name() const; virtual const 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;
private: private:
Glib::ustring _name; Glib::ustring _name;
unsigned int _arrival_time;
unsigned int _total_time;
int _priority; int _priority;
}; };
} }

View File

@ -19,6 +19,8 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "static_sub_request.hh" #include "static_sub_request.hh"
#include <algorithm>
#include <cstddef> #include <cstddef>
#include <cassert> #include <cassert>
@ -32,6 +34,15 @@ StaticSubRequest::StaticSubRequest(StaticRequest* req,
_length(length), _places(places) _length(length), _places(places)
{ {
assert(req != NULL && resource != NULL); assert(req != NULL && resource != NULL);
req->get_subrequests().push_back(this);
}
StaticSubRequest::~StaticSubRequest()
{
typedef std::vector<StaticSubRequest*> SubRequests;
SubRequests siblings& = _static_request.get_subrequests();
siblings.erase(find(siblings.begin(), siblings.end(), this);
} }
StaticResource& StaticResource&

View File

@ -37,6 +37,8 @@ namespace sgpem
unsigned int length, unsigned int length,
unsigned int places = 1); unsigned int places = 1);
virtual ~StaticSubRequest();
StaticResource& get_static_resource(); StaticResource& get_static_resource();
StaticRequest& get_static_request(); StaticRequest& get_static_request();

View File

@ -21,19 +21,33 @@
#include "static_thread.hh" #include "static_thread.hh"
#include "static_request.hh" #include "static_request.hh"
#include <algorithm>
#include <cassert> #include <cassert>
using namespace sgpem; using namespace sgpem;
using std::vector; using namespace std;
StaticThread::StaticThread(const Glib::ustring& name, StaticThread::StaticThread(const Glib::ustring& name,
StaticProcess& process, StaticProcess& process,
unsigned int cpu_time,
unsigned int arrival_time, unsigned int arrival_time,
int base_priority) : int base_priority) :
StaticSchedulable(name, arrival_time, 0, base_priority), StaticSchedulable(name, base_priority),
_start_time_delta(arrival_time), _required_cpu_time(0), _start_time_delta(arrival_time),
_required_cpu_time(cpu_time),
_process(&process) _process(&process)
{} {
process.get_threads().push_back(this);
}
StaticThread::~StaticThread()
{
typedef std::vector<StaticThread*> Threads;
Threads siblings& = _process.get_threads();
siblings.erase(find(siblings.begin(), siblings.end(), this);
}
unsigned int unsigned int
StaticThread::get_total_cpu_time() const StaticThread::get_total_cpu_time() const
@ -53,27 +67,8 @@ StaticThread::get_process()
return *_process; return *_process;
} }
void std::vector<StaticRequest*>&
StaticThread::remove_request(StaticRequest* request) StaticThread::get_requests()
{ {
assert(request != NULL); return _requests;
vector<StaticRequest*>::iterator it;
it = std::find(_static_requests.begin(), _static_requests.end(), request);
if(it != _static_requests.end())
{
_static_requests.erase(it);
delete *it;
}
} }
void
StaticThread::add_request(StaticRequest* request)
{
assert(request != NULL);
_static_requests.push_back(request);
}

View File

@ -39,18 +39,23 @@ namespace sgpem
public: public:
StaticThread(const Glib::ustring& name, StaticThread(const Glib::ustring& name,
StaticProcess& process, StaticProcess& process,
unsigned int cpu_time,
unsigned int arrival_time = 0, unsigned int arrival_time = 0,
int base_priority = 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<StaticRequest*>& get_requests();
private: private:
StaticThread(const StaticThread&); StaticThread(const StaticThread&);