Reformat using clang-format

This commit is contained in:
Matteo Settenvini 2018-09-25 10:20:45 +02:00
parent c1ac6f279b
commit ffd4b6b319
197 changed files with 13059 additions and 13569 deletions

View File

@ -22,230 +22,221 @@
#include <sgpemv2/templates/sequences.tcc>
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/resource.hh>
#include <sgpemv2/simulation.hh>
#include "gettext.h"
#include <gtkmm/spinbutton.h>
#include <cassert>
#include <iostream>
#include <sstream>
#include <cassert>
using namespace sgpem;
using namespace Gtk;
using namespace Glib;
using std::vector;
AddRequestDialog::AddRequestDialog(BaseObjectType* cobject, const RefPtr<Builder>& ui) :
Dialog(cobject), _ui(ui)
AddRequestDialog::AddRequestDialog (BaseObjectType *cobject, const RefPtr<Builder> &ui) : Dialog (cobject), _ui (ui)
{
_ui->get_widget("SubRequests.View", _list);
_ui->get_widget("Add", _add_button);
_ui->get_widget("Remove", _remove_button);
_ui->get_widget("Resource.Combo", _resource_combo);
_ui->get_widget("OK.Button", _ok_button);
_ui->get_widget("Instant.Spin", _instant_spin);
_ui->get_widget("Duration.Spin", _duration_spin);
_ui->get_widget ("SubRequests.View", _list);
_ui->get_widget ("Add", _add_button);
_ui->get_widget ("Remove", _remove_button);
_ui->get_widget ("Resource.Combo", _resource_combo);
_ui->get_widget ("OK.Button", _ok_button);
_ui->get_widget ("Instant.Spin", _instant_spin);
_ui->get_widget ("Duration.Spin", _duration_spin);
/** ATTACH SIGNAL HANDLERS FOR BUTTONS **/
/** ATTACH SIGNAL HANDLERS FOR BUTTONS **/
_add_button->signal_clicked().connect(
sigc::mem_fun(*this, &AddRequestDialog::_on_add));
_add_button->signal_clicked ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_add));
_remove_button->signal_clicked().connect(
sigc::mem_fun(*this, &AddRequestDialog::_on_remove));
_remove_button->signal_clicked ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_remove));
_ok_button->set_sensitive(false);
_remove_button->set_sensitive(false);
_add_button->set_sensitive(false);
_ok_button->set_sensitive (false);
_remove_button->set_sensitive (false);
_add_button->set_sensitive (false);
/** INITIALIZE COMBOBOX **/
_combo_columns.add(_combo_key_column);
_combo_columns.add(_combo_resource_column);
/** INITIALIZE COMBOBOX **/
_combo_columns.add (_combo_key_column);
_combo_columns.add (_combo_resource_column);
_combo_model = ListStore::create(_combo_columns);
_resource_combo->set_model(_combo_model);
_resource_combo->pack_start(_combo_key_column, false);
_resource_combo->pack_start(_combo_resource_column, true);
_combo_model = ListStore::create (_combo_columns);
_resource_combo->set_model (_combo_model);
_resource_combo->pack_start (_combo_key_column, false);
_resource_combo->pack_start (_combo_resource_column, true);
_resource_combo->signal_changed().connect(
sigc::mem_fun(*this, &AddRequestDialog::_on_combo_selection_changed));
_resource_combo->signal_changed ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_combo_selection_changed));
/** INITIALIZE LISTVIEW **/
/** INITIALIZE LISTVIEW **/
_list_columns.add(_list_key_column);
_list_columns.add(_list_resource_column);
_list_columns.add(_list_duration_column);
_list_columns.add (_list_key_column);
_list_columns.add (_list_resource_column);
_list_columns.add (_list_duration_column);
_list_model = ListStore::create(_list_columns);
_list->set_model(_list_model);
_list_model = ListStore::create (_list_columns);
_list->set_model (_list_model);
_list_model->signal_row_deleted().connect(
sigc::mem_fun(*this, &AddRequestDialog::_on_row_removed));
_list_model->signal_row_deleted ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_row_removed));
_list_model->signal_row_inserted().connect(
sigc::mem_fun(*this, &AddRequestDialog::_on_row_added));
_list_model->signal_row_inserted ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_row_added));
_list->append_column(_("key"), _list_key_column);
_list->append_column(_("resource"), _list_resource_column);
_list->append_column(_("duration"), _list_duration_column);
_list->append_column (_ ("key"), _list_key_column);
_list->append_column (_ ("resource"), _list_resource_column);
_list->append_column (_ ("duration"), _list_duration_column);
_list->get_selection()->signal_changed().connect(
sigc::mem_fun(*this, &AddRequestDialog::_on_list_selection_changed));
_list->get_selection ()->signal_changed ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_list_selection_changed));
}
Request*
AddRequestDialog::run_add(sgpem::Thread& owner)
Request *
AddRequestDialog::run_add (sgpem::Thread &owner)
{
update_combo();
update_combo ();
Request* r = nullptr;
Request *r = nullptr;
// reset the dialog data
// _list_model->clear();
// _instant_spin->set_value(0.0);
// _duration_spin->set_value(0.0);
// reset the dialog data
// _list_model->clear();
// _instant_spin->set_value(0.0);
// _duration_spin->set_value(0.0);
if(run() == RESPONSE_OK)
{
assert(_list_model->children());
if (run () == RESPONSE_OK)
{
assert (_list_model->children ());
History& h = Simulation::get_instance().get_history();
History &h = Simulation::get_instance ().get_history ();
r = &h.add_request(owner, _instant_spin->get_value_as_int());
r = &h.add_request (owner, _instant_spin->get_value_as_int ());
TreeNodeChildren sreq_container = _list_model->children();
TreeNodeChildren sreq_container = _list_model->children ();
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it)
h.add_subrequest(*r, (*it)[_list_key_column], (*it)[_list_duration_column]);
}
for (Iseq<TreeIter> it = iseq (sreq_container); it; ++it)
h.add_subrequest (*r, (*it)[_list_key_column], (*it)[_list_duration_column]);
}
hide();
hide ();
return r;
return r;
}
void
AddRequestDialog::run_edit(Request& request)
AddRequestDialog::run_edit (Request &request)
{
update_combo();
update_combo ();
_list_model->clear();
_list_model->clear ();
History& history = Simulation::get_instance().get_history();
const Environment::Resources& resources = history.get_last_environment().get_resources();
History &history = Simulation::get_instance ().get_history ();
const Environment::Resources &resources = history.get_last_environment ().get_resources ();
_instant_spin->set_value(static_cast<double>(request.get_instant()));
_instant_spin->set_value (static_cast<double> (request.get_instant ()));
// PLEASE KEEP THIS A COPY, WE *NEED* TO COPY IT
vector<SubRequest*> subrequests = request.get_subrequests();
// PLEASE KEEP THIS A COPY, WE *NEED* TO COPY IT
vector<SubRequest *> subrequests = request.get_subrequests ();
for(Iseq<vector<SubRequest*>::iterator> it = iseq(subrequests); it; ++it)
{
SubRequest& sr = *(*it);
for (Iseq<vector<SubRequest *>::iterator> it = iseq (subrequests); it; ++it)
{
SubRequest &sr = *(*it);
TreeModel::Row row = *(_list_model->append());
TreeModel::Row row = *(_list_model->append ());
unsigned int key = sr.get_resource_key();
row[_list_key_column] = key;
unsigned int key = sr.get_resource_key ();
row[_list_key_column] = key;
const ustring name = resources.find(key)->second->get_name();
row[_list_resource_column] = name;
const ustring name = resources.find (key)->second->get_name ();
row[_list_resource_column] = name;
row[_list_duration_column] = sr.get_length();
}
row[_list_duration_column] = sr.get_length ();
}
if(run() == RESPONSE_OK)
{
assert(_list_model->children());
if (run () == RESPONSE_OK)
{
assert (_list_model->children ());
History::LockNotify h_lock(history);
History::LockNotify h_lock (history);
// I know it's a bit hack-ish, but do you know an elegant alternative way?
for(Iseq<vector<SubRequest*>::iterator> it = iseq(subrequests); it; ++it)
history.remove(*(*it));
// I know it's a bit hack-ish, but do you know an elegant alternative way?
for (Iseq<vector<SubRequest *>::iterator> it = iseq (subrequests); it; ++it)
history.remove (*(*it));
history.edit_request(request, _instant_spin->get_value_as_int());
history.edit_request (request, _instant_spin->get_value_as_int ());
TreeNodeChildren sreq_container = _list_model->children();
TreeNodeChildren sreq_container = _list_model->children ();
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it)
history.add_subrequest(request, (*it)[_list_key_column], (*it)[_list_duration_column]);
}
for (Iseq<TreeIter> it = iseq (sreq_container); it; ++it)
history.add_subrequest (request, (*it)[_list_key_column], (*it)[_list_duration_column]);
}
hide();
hide ();
}
void
AddRequestDialog::update_combo()
AddRequestDialog::update_combo ()
{
typedef Environment::Resources::const_iterator ResourceIt;
typedef Environment::Resources::const_iterator ResourceIt;
const Environment::Resources& resources =
Simulation::get_instance().get_history().get_last_environment().get_resources();
const Environment::Resources &resources = Simulation::get_instance ().get_history ().get_last_environment ().get_resources ();
_combo_model->clear();
_combo_model->clear ();
for(Iseq<ResourceIt> it = iseq(resources); it; ++it)
{
TreeModel::Row row = *(_combo_model->append());
row[_combo_key_column] = it->first;
row[_combo_resource_column] = it->second->get_name();
}
for (Iseq<ResourceIt> it = iseq (resources); it; ++it)
{
TreeModel::Row row = *(_combo_model->append ());
row[_combo_key_column] = it->first;
row[_combo_resource_column] = it->second->get_name ();
}
Dialog::on_show();
Dialog::on_show ();
}
void
AddRequestDialog::_on_add()
AddRequestDialog::_on_add ()
{
TreeModel::iterator sel = _resource_combo->get_active();
TreeModel::iterator sel = _resource_combo->get_active ();
TreeModel::Row row = *(_list_model->append());
TreeModel::Row row = *(_list_model->append ());
const unsigned int key = (*sel)[_combo_key_column];
row[_list_key_column] = key;
const unsigned int key = (*sel)[_combo_key_column];
row[_list_key_column] = key;
const ustring resource = (*sel)[_combo_resource_column];
row[_list_resource_column] = resource;
const ustring resource = (*sel)[_combo_resource_column];
row[_list_resource_column] = resource;
const unsigned int duration = _duration_spin->get_value_as_int();
row[_list_duration_column] = duration;
const unsigned int duration = _duration_spin->get_value_as_int ();
row[_list_duration_column] = duration;
}
void
AddRequestDialog::_on_remove()
AddRequestDialog::_on_remove ()
{
TreeModel::iterator it = _list->get_selection()->get_selected();
_list_model->erase(it);
TreeModel::iterator it = _list->get_selection ()->get_selected ();
_list_model->erase (it);
}
void
AddRequestDialog::_on_list_selection_changed()
AddRequestDialog::_on_list_selection_changed ()
{
_remove_button->set_sensitive(
_list->get_selection()->count_selected_rows() > 0);
_remove_button->set_sensitive (_list->get_selection ()->count_selected_rows () > 0);
}
void
AddRequestDialog::_on_row_added(const Gtk::TreePath&, const Gtk::TreeIter&)
AddRequestDialog::_on_row_added (const Gtk::TreePath &, const Gtk::TreeIter &)
{
_ok_button->set_sensitive(true);
_ok_button->set_sensitive (true);
}
void
AddRequestDialog::_on_row_removed(const Gtk::TreePath&)
AddRequestDialog::_on_row_removed (const Gtk::TreePath &)
{
_ok_button->set_sensitive(static_cast<bool>(_list_model->children()));
_ok_button->set_sensitive (static_cast<bool> (_list_model->children ()));
}
void
AddRequestDialog::_on_combo_selection_changed()
AddRequestDialog::_on_combo_selection_changed ()
{
_add_button->set_sensitive(static_cast<bool>(_resource_combo->get_active()));
_add_button->set_sensitive (static_cast<bool> (_resource_combo->get_active ()));
}

View File

@ -23,31 +23,31 @@
namespace sgpem
{
class Request;
class Thread;
class AddRequestDialog;
}
class Request;
class Thread;
class AddRequestDialog;
} // namespace sgpem
#include <gtkmm/treeview.h>
#include <gtkmm/liststore.h>
#include <gtkmm/dialog.h>
#include <gtkmm/combobox.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/builder.h>
#include <gtkmm/combobox.h>
#include <gtkmm/dialog.h>
#include <gtkmm/liststore.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/treeview.h>
namespace sgpem
{
/** \brief A dialog derived from add-request-dialog.ui
/** \brief A dialog derived from add-request-dialog.ui
*
* Manages the list of subrequests, ensures only "nonempty" requests
* are created, and supports also editing.
*/
class AddRequestDialog : public Gtk::Dialog
{
public:
class AddRequestDialog : public Gtk::Dialog
{
public:
/** \brief Constructor required by gtkbuilder
*/
AddRequestDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& ui);
AddRequestDialog (BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &ui);
/** \brief Attemts to show the dialog, and constructs a new request
* if response is OK
@ -55,76 +55,76 @@ namespace sgpem
* \return A pointer to the created request, or nullptr if the request
* wasn't created
*/
Request* run_add(Thread& owner);
Request *run_add (Thread &owner);
/** \brief Attemts to show the dialog to modify an existing request
* \param request The request to modify
*/
void run_edit(Request& request);
void run_edit (Request &request);
private:
private:
/** \brief Fills the combo model with data from the latest
* Environment
*/
void update_combo();
void update_combo ();
/** \brief Called when the "add subrequest" button is pressed
*/
void _on_add();
void _on_add ();
/** \brief Called when the "remove subrequest" button is pressed
*/
void _on_remove();
void _on_remove ();
/** \brief Called when list selection changes
*
* Ensures the "remove subrequest" button is sensitive only
* if a subrequest is selected
*/
void _on_list_selection_changed();
void _on_list_selection_changed ();
/** \brief Called when a row is added to the subrequest list
*
* Ensures the OK button is sensitive since we are sure there is at
* least a subrequest
*/
void _on_row_added(const Gtk::TreePath& path, const Gtk::TreeIter& it);
void _on_row_added (const Gtk::TreePath &path, const Gtk::TreeIter &it);
/** \brief Called when a row is removed from the subrequest list
*
* Ensures the OK button is no more sensitive if the last item was removed
*/
void _on_row_removed(const Gtk::TreePath& path);
void _on_row_removed (const Gtk::TreePath &path);
/** \brief Called when the combo selection changes
*
* Ensures the "add subrequest" button is sensitive only
* if a resource is selected
*/
void _on_combo_selection_changed();
void _on_combo_selection_changed ();
Glib::RefPtr<Gtk::Builder> _ui;
Gtk::TreeView* _list;
Gtk::TreeView *_list;
Glib::RefPtr<Gtk::ListStore> _list_model;
Gtk::TreeModelColumnRecord _list_columns;
Gtk::TreeModelColumn<unsigned int> _list_key_column;
Gtk::TreeModelColumn<Glib::ustring> _list_resource_column;
Gtk::TreeModelColumn<unsigned int> _list_duration_column;
Gtk::Button* _add_button;
Gtk::Button* _remove_button;
Gtk::Button* _ok_button;
Gtk::SpinButton* _instant_spin;
Gtk::SpinButton* _duration_spin;
Gtk::Button *_add_button;
Gtk::Button *_remove_button;
Gtk::Button *_ok_button;
Gtk::SpinButton *_instant_spin;
Gtk::SpinButton *_duration_spin;
Gtk::ComboBox* _resource_combo;
Gtk::ComboBox *_resource_combo;
Glib::RefPtr<Gtk::ListStore> _combo_model;
Gtk::TreeModelColumnRecord _combo_columns;
Gtk::TreeModelColumn<unsigned int> _combo_key_column;
Gtk::TreeModelColumn<Glib::ustring> _combo_resource_column;
};
};
} //~ namespace sgpem
} // namespace sgpem
#endif //~ ADD_REQUEST_DIALOG_HH

View File

@ -36,182 +36,167 @@
using namespace sgpem;
using namespace std;
ConcreteEnvironment::ConcreteEnvironment()
ConcreteEnvironment::ConcreteEnvironment ()
{
// Nothing to do here. Really.
// Nothing to do here. Really.
}
ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment& ce) :
Environment(ce), _resources(ce._resources), _processes(), _sched_queue(), _sreq_queues(ce._sreq_queues)
ConcreteEnvironment::ConcreteEnvironment (const ConcreteEnvironment &ce)
: Environment (ce), _resources (ce._resources), _processes (), _sched_queue (), _sreq_queues (ce._sreq_queues)
{
// The ReadyQueue won't be copied. Pointers to objects contained into
// the ready queue _will_ have changed in the new one. The ready queue
// needs to be reset: it is Scheduler that builds it again from time to time.
// The ReadyQueue won't be copied. Pointers to objects contained into
// the ready queue _will_ have changed in the new one. The ready queue
// needs to be reset: it is Scheduler that builds it again from time to time.
// Update resource pointers in a way you won't like :-)
{
for (Resources::iterator it = _resources.begin(); it != _resources.end(); it++)
it->second = new DynamicResource(down_cast<const DynamicResource&>(*it->second));
}
// DynamicProcess object need to be copied.
// The deep copy is guaranteed by the DynamicProcess copy constructor
{
const Processes& ce_proc = ce._processes;
insert_iterator<Processes> dest(_processes, _processes.begin());
for (Iseq<Processes::const_iterator> orig = iseq(ce_proc); orig; orig++)
*dest++ = new DynamicProcess(down_cast<const DynamicProcess&>(**orig));
}
// Update the subrequest queues.
// for each subrequest
typedef Processes::const_iterator it1_t;
typedef std::vector<Thread*> v2_t;
typedef v2_t::const_iterator it2_t;
typedef std::vector<Request*> v3_t;
typedef v3_t::const_iterator it3_t;
typedef std::vector<SubRequest*> v4_t;
typedef v4_t::const_iterator it4_t;
typedef SubRequestQueue::iterator it5_t;
for (it1_t it1 = _processes.begin(); it1 != _processes.end(); it1++)
{
const v2_t& threads = (*it1)->get_threads();
for (it2_t it2 = threads.begin(); it2 != threads.end(); it2++)
// Update resource pointers in a way you won't like :-)
{
const v3_t& reqs = (*it2)->get_requests();
for (it3_t it3 = reqs.begin(); it3 != reqs.end(); it3++)
{
// an optimization here: there is no reason in iterating through
// future or exausted requests. (Do you know why?)
const v4_t& subr = (*it3)->get_subrequests();
for (it4_t it4 = subr.begin(); it4 != subr.end(); it4++)
{
SubRequest::state curr_state = (*it4)->get_state();
if (curr_state != Request::state_future && curr_state != Request::state_exhausted)
{
// the subrequest is the following queue:
SubRequestQueue & queue = get_request_queue((*it4)->get_resource_key());
// we must replace the old pointer:
bool found = false;
for (it5_t it5 = queue.begin(); !found && it5 != queue.end(); it5++)
{
DynamicSubRequest& _old = down_cast<DynamicSubRequest&>(**it5);
DynamicSubRequest& _new = down_cast<DynamicSubRequest&>(**it4);
if (&_old.get_core() == &_new.get_core())
{
found = true;
*it5 = *it4;
}
}
}
}
}
for (Resources::iterator it = _resources.begin (); it != _resources.end (); it++)
it->second = new DynamicResource (down_cast<const DynamicResource &> (*it->second));
}
// DynamicProcess object need to be copied.
// The deep copy is guaranteed by the DynamicProcess copy constructor
{
const Processes &ce_proc = ce._processes;
insert_iterator<Processes> dest (_processes, _processes.begin ());
for (Iseq<Processes::const_iterator> orig = iseq (ce_proc); orig; orig++)
*dest++ = new DynamicProcess (down_cast<const DynamicProcess &> (**orig));
}
}
// Update the subrequest queues.
// for each subrequest
typedef Processes::const_iterator it1_t;
typedef std::vector<Thread *> v2_t;
typedef v2_t::const_iterator it2_t;
typedef std::vector<Request *> v3_t;
typedef v3_t::const_iterator it3_t;
typedef std::vector<SubRequest *> v4_t;
typedef v4_t::const_iterator it4_t;
typedef SubRequestQueue::iterator it5_t;
for (it1_t it1 = _processes.begin (); it1 != _processes.end (); it1++)
{
const v2_t &threads = (*it1)->get_threads ();
for (it2_t it2 = threads.begin (); it2 != threads.end (); it2++)
{
const v3_t &reqs = (*it2)->get_requests ();
for (it3_t it3 = reqs.begin (); it3 != reqs.end (); it3++)
{
// an optimization here: there is no reason in iterating through
// future or exausted requests. (Do you know why?)
const v4_t &subr = (*it3)->get_subrequests ();
for (it4_t it4 = subr.begin (); it4 != subr.end (); it4++)
{
SubRequest::state curr_state = (*it4)->get_state ();
if (curr_state != Request::state_future && curr_state != Request::state_exhausted)
{
// the subrequest is the following queue:
SubRequestQueue &queue = get_request_queue ((*it4)->get_resource_key ());
// we must replace the old pointer:
bool found = false;
for (it5_t it5 = queue.begin (); !found && it5 != queue.end (); it5++)
{
DynamicSubRequest &_old = down_cast<DynamicSubRequest &> (**it5);
DynamicSubRequest &_new = down_cast<DynamicSubRequest &> (**it4);
if (&_old.get_core () == &_new.get_core ())
{
found = true;
*it5 = *it4;
}
}
}
}
}
}
}
}
const Environment::Processes&
ConcreteEnvironment::get_processes() const
const Environment::Processes &
ConcreteEnvironment::get_processes () const
{
return _processes;
return _processes;
}
ConcreteEnvironment::Processes&
ConcreteEnvironment::get_processes()
ConcreteEnvironment::Processes &
ConcreteEnvironment::get_processes ()
{
return _processes;
return _processes;
}
const Environment::Resources&
ConcreteEnvironment::get_resources() const
const Environment::Resources &
ConcreteEnvironment::get_resources () const
{
return _resources;
return _resources;
}
ConcreteEnvironment::Resources&
ConcreteEnvironment::get_resources()
ConcreteEnvironment::Resources &
ConcreteEnvironment::get_resources ()
{
return _resources;
return _resources;
}
const Environment::SubRequestQueue&
ConcreteEnvironment::get_request_queue(resource_key_t resource_key) const
const Environment::SubRequestQueue &
ConcreteEnvironment::get_request_queue (resource_key_t resource_key) const
{
// Should always return something...
return _sreq_queues.find(resource_key)->second;
// Should always return something...
return _sreq_queues.find (resource_key)->second;
}
Environment::SubRequestQueue&
ConcreteEnvironment::get_request_queue(resource_key_t resource_key)
Environment::SubRequestQueue &
ConcreteEnvironment::get_request_queue (resource_key_t resource_key)
{
// Inserts a new element in none is there!
return _sreq_queues[resource_key];
// Inserts a new element in none is there!
return _sreq_queues[resource_key];
}
ConcreteEnvironment::SubRequestQueues&
ConcreteEnvironment::get_subrequest_queues()
ConcreteEnvironment::SubRequestQueues &
ConcreteEnvironment::get_subrequest_queues ()
{
return _sreq_queues;
return _sreq_queues;
}
const ReadyQueue&
ConcreteEnvironment::get_sorted_queue() const
const ReadyQueue &
ConcreteEnvironment::get_sorted_queue () const
{
return _sched_queue;
return _sched_queue;
}
ReadyQueue&
ConcreteEnvironment::get_sorted_queue()
ReadyQueue &
ConcreteEnvironment::get_sorted_queue ()
{
return _sched_queue;
return _sched_queue;
}
ConcreteEnvironment::~ConcreteEnvironment()
ConcreteEnvironment::~ConcreteEnvironment ()
{
// This call will invoke the DynamicProcess virtual destructor
// Which will delete on cascade all DynamicThreads and so on.
for_each(_processes.begin(), _processes.end(),
[] (auto *p) { delete p; });
// This call will invoke the DynamicProcess virtual destructor
// Which will delete on cascade all DynamicThreads and so on.
for_each (_processes.begin (), _processes.end (), [](auto *p) { delete p; });
// We do the same with Resources.
for (Resources::iterator it = _resources.begin(); it != _resources.end(); it++)
delete it->second;
// We do the same with Resources.
for (Resources::iterator it = _resources.begin (); it != _resources.end (); it++)
delete it->second;
// After this, the destructor of _sched_queue is invoked (only invalid pointers)
// After that, the destructor of _processes is invoked (only invalid pointers)
// After that, the destructor of _resources is invoked (only invalid pointers)
// After this, the destructor of _sched_queue is invoked (only invalid pointers)
// After that, the destructor of _processes is invoked (only invalid pointers)
// After that, the destructor of _resources is invoked (only invalid pointers)
}
// -------------------------------- TO BE FIXED ----------------

View File

@ -23,48 +23,48 @@
namespace sgpem
{
class ConcreteEnvironment;
class SerializeVisitor;
}
class ConcreteEnvironment;
class SerializeVisitor;
} // namespace sgpem
#include "dynamic_process.hh"
#include "dynamic_request.hh"
#include <sgpemv2/environment.hh>
#include <sgpemv2/resource.hh>
#include <sgpemv2/ready_queue.hh>
#include <sgpemv2/resource.hh>
namespace sgpem
{
/// \brief An implementation of the Environment class.
///
/// Class ConcreteEnvironment implements the Environment
/// abstract class.
///
/// This implementation actually contains the collections
/// of snapshots accessed by the function members defined
/// in the Environment class.
///
/// \see Environment
class SG_DLLLOCAL ConcreteEnvironment : public Environment
{
public:
/// \brief An implementation of the Environment class.
///
/// Class ConcreteEnvironment implements the Environment
/// abstract class.
///
/// This implementation actually contains the collections
/// of snapshots accessed by the function members defined
/// in the Environment class.
///
/// \see Environment
class SG_DLLLOCAL ConcreteEnvironment : public Environment
{
public:
typedef std::map<resource_key_t, SubRequestQueue> SubRequestQueues;
/// \brief Standard constructor.
///
/// Builds an empty environment.
ConcreteEnvironment();
ConcreteEnvironment ();
/// \brief Copy constructor.
///
/// Performs a deep copy of all structures.
ConcreteEnvironment(const ConcreteEnvironment& c);
ConcreteEnvironment (const ConcreteEnvironment &c);
/// \brief The standard virtual destructor.
///
/// The standard virtual destructor.
virtual ~ConcreteEnvironment();
virtual ~ConcreteEnvironment ();
/// \brief Returns an indexed set of snapshots of the processes
///
@ -77,13 +77,13 @@ namespace sgpem
/// always safe.
///
/// \return a constant set of snapshots of processes
virtual const Processes& get_processes() const;
virtual const Processes &get_processes () const;
/// \brief Non-constant version of get_processes()
///
/// \return a set of snapshots of processes
/// \see get_processes()
virtual Processes& get_processes();
virtual Processes &get_processes ();
/// \brief Returns an indexed set of snapshots of the resources
///
@ -104,13 +104,13 @@ namespace sgpem
///
/// \return a indexed constant set of snapshot of resources.
/// \see DynamicSybrequest::get_resource()
virtual const Resources& get_resources() const;
virtual const Resources &get_resources () const;
/// \brief Non-constant version of get_resources()
///
/// \return an indexed set of snapshots of resources
/// \see get_resources()
virtual Resources& get_resources();
virtual Resources &get_resources ();
/// \brief Returns a snapshot of the current request queue for a resource.
///
@ -124,16 +124,16 @@ namespace sgpem
///
/// \param resource The resource the requests are for
/// \return The current ready requests queue.
virtual const SubRequestQueue& get_request_queue(resource_key_t resource_key) const;
virtual const SubRequestQueue &get_request_queue (resource_key_t resource_key) const;
SubRequestQueue& get_request_queue(resource_key_t resource_key);
SubRequestQueue &get_request_queue (resource_key_t resource_key);
/// \brief Returns the set of request queues.
///
/// Returns a reference to the map from resources to subreuqest queues.
/// It is needed by history to delete the queue associated to a deleted
/// resource.
SubRequestQueues& get_subrequest_queues();
SubRequestQueues &get_subrequest_queues ();
/// \brief Returns a snapshot of the current scheduler's ready queue.
///
@ -143,16 +143,15 @@ namespace sgpem
/// of the CPU.
///
/// \return the current ready queue (constant).
virtual const ReadyQueue& get_sorted_queue() const;
virtual const ReadyQueue &get_sorted_queue () const;
/// \brief Non-constant version of get_sorted_queue()
///
/// \return the current ready queue.
/// \see get_sorted_queue()
virtual ReadyQueue& get_sorted_queue();
private:
virtual ReadyQueue &get_sorted_queue ();
private:
/// \brief The container of all Resource objecs.
///
/// Actually contains only DynamicResource objects.
@ -172,8 +171,8 @@ namespace sgpem
SubRequestQueues _sreq_queues;
}; //~ class ConcreteEnvironment
}; //~ class ConcreteEnvironment
} //~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -18,19 +18,17 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include "dynamic_process.hh"
#include "dynamic_thread.hh"
#include "dynamic_resource.hh"
#include "dynamic_request.hh"
#include "dynamic_resource.hh"
#include "dynamic_sub_request.hh"
#include "dynamic_thread.hh"
#include "static_process.hh"
#include "static_thread.hh"
#include "static_resource.hh"
#include "static_request.hh"
#include "static_resource.hh"
#include "static_sub_request.hh"
#include "static_thread.hh"
#include "concrete_history.hh"
@ -54,496 +52,474 @@ using namespace std;
// For all you evil-doers on Earth, this is your mighty punishment!
// remove a template object from vector of pointers
template<typename T>
static bool deep_remove(std::vector<T*>& v, const T& obj)
template <typename T>
static bool
deep_remove (std::vector<T *> &v, const T &obj)
{
typedef typename std::vector<T*> Vector;
for (typename Vector::iterator it = v.begin(); it != v.end(); it++)
if (**it == obj)
{
delete *it;
v.erase(it);
return true;
}
return false;
typedef typename std::vector<T *> Vector;
for (typename Vector::iterator it = v.begin (); it != v.end (); it++)
if (**it == obj)
{
delete *it;
v.erase (it);
return true;
}
return false;
}
// find a template T object into a vector of T pointers
template<typename T>
static T* deep_find(const std::vector<T*>& v, const T& obj)
template <typename T>
static T *
deep_find (const std::vector<T *> &v, const T &obj)
{
typedef typename std::vector<T*> Vector;
for (typename Vector::const_iterator it = v.begin(); it != v.end(); it++)
if (**it == obj)
{
return *it;
}
return nullptr;
typedef typename std::vector<T *> Vector;
for (typename Vector::const_iterator it = v.begin (); it != v.end (); it++)
if (**it == obj)
{
return *it;
}
return nullptr;
}
// -----------------
ConcreteHistory::ConcreteHistory()
: History(), _snapshots(), _sealed(false)
ConcreteHistory::ConcreteHistory () : History (), _snapshots (), _sealed (false)
{
_snapshots.push_back(new ConcreteEnvironment());
_snapshots.push_back (new ConcreteEnvironment ());
}
ConcreteHistory::~ConcreteHistory()
ConcreteHistory::~ConcreteHistory ()
{
for_each(_snapshots.begin(), _snapshots.end(),
[] (auto *p) { delete p; });
for_each (_snapshots.begin (), _snapshots.end (), [](auto *p) { delete p; });
}
ConcreteHistory::ConcreteHistory(const ConcreteHistory& h) :
History(h), _sealed(h._sealed)
ConcreteHistory::ConcreteHistory (const ConcreteHistory &h) : History (h), _sealed (h._sealed)
{
typedef Snapshots::const_iterator SnapIt;
for (SnapIt it = h._snapshots.begin(); it != h._snapshots.end(); ++it)
_snapshots.push_back(new ConcreteEnvironment(*(*it)));
typedef Snapshots::const_iterator SnapIt;
for (SnapIt it = h._snapshots.begin (); it != h._snapshots.end (); ++it)
_snapshots.push_back (new ConcreteEnvironment (*(*it)));
}
void
ConcreteHistory::append_new_environment(ConcreteEnvironment* environment)
ConcreteHistory::append_new_environment (ConcreteEnvironment *environment)
{
_snapshots.push_back(environment);
notify_change();
_snapshots.push_back (environment);
notify_change ();
}
ConcreteHistory::size_t
ConcreteHistory::get_size() const
ConcreteHistory::get_size () const
{
return _snapshots.size();
return _snapshots.size ();
}
const ConcreteEnvironment&
ConcreteHistory::get_last_environment() const
const ConcreteEnvironment &
ConcreteHistory::get_last_environment () const
{
// Should always be true:
assert(_snapshots.size() > 0);
return get_environment_at(get_front());
// Should always be true:
assert (_snapshots.size () > 0);
return get_environment_at (get_front ());
}
const ConcreteEnvironment&
ConcreteHistory::get_environment_at(position index) const
const ConcreteEnvironment &
ConcreteHistory::get_environment_at (position index) const
{
return *_snapshots.at(index);
return *_snapshots.at (index);
}
void
ConcreteHistory::remove(resource_key_t resource_key)
ConcreteHistory::remove (resource_key_t resource_key)
{
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment& initial = *_snapshots.front();
ConcreteEnvironment::Resources& resources = initial.get_resources();
ConcreteEnvironment::Resources::iterator found = resources.find(resource_key);
if (found == resources.end())
return;
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment &initial = *_snapshots.front ();
ConcreteEnvironment::Resources &resources = initial.get_resources ();
ConcreteEnvironment::Resources::iterator found = resources.find (resource_key);
if (found == resources.end ())
return;
delete found->second;
resources.erase(found);
delete found->second;
resources.erase (found);
// Delete the queue associated with the resource.
ConcreteEnvironment::SubRequestQueues& srq = initial.get_subrequest_queues();
ConcreteEnvironment::SubRequestQueues::iterator qfound = srq.find(resource_key);
// There is always one!
assert(qfound != srq.end());
srq.erase(qfound);
// Delete the queue associated with the resource.
ConcreteEnvironment::SubRequestQueues &srq = initial.get_subrequest_queues ();
ConcreteEnvironment::SubRequestQueues::iterator qfound = srq.find (resource_key);
// There is always one!
assert (qfound != srq.end ());
srq.erase (qfound);
// Now search and erase subrequest that had a ref to the
// removed resource
// Now search and erase subrequest that had a ref to the
// removed resource
typedef std::vector<DynamicThread*> Threads;
typedef std::vector<DynamicRequest*> Requests;
typedef std::vector<DynamicSubRequest*> SubRequests;
typedef std::vector<DynamicThread *> Threads;
typedef std::vector<DynamicRequest *> Requests;
typedef std::vector<DynamicSubRequest *> SubRequests;
// Listening to "The Thing That Should Not Be"...
// all hail the cyclomatic complexity!
ConcreteEnvironment::Processes& processes = initial.get_processes();
typedef ConcreteEnvironment::Processes::iterator ProcIt;
for (ProcIt it1 = processes.begin(); it1 != processes.end(); it1++)
{
Threads& threads = down_cast<DynamicProcess&>(**it1).get_dynamic_threads();
for (Threads::iterator it2 = threads.begin(); it2 != threads.end(); it2++)
// Listening to "The Thing That Should Not Be"...
// all hail the cyclomatic complexity!
ConcreteEnvironment::Processes &processes = initial.get_processes ();
typedef ConcreteEnvironment::Processes::iterator ProcIt;
for (ProcIt it1 = processes.begin (); it1 != processes.end (); it1++)
{
Requests& reqs = (*it2)->get_dynamic_requests();
for (Requests::iterator it3 = reqs.begin(); it3 != reqs.end(); it3++)
{
SubRequests& subr = (*it3)->get_dynamic_subrequests();
SubRequests::iterator it4 = subr.begin();
while (it4 != subr.end())
if ((*it4)->get_resource_key() == resource_key)
{
delete *it4;
it4 = subr.erase(it4);
}
else
it4++;
}
}
} //~ end monstrous construct, "The Thing That Should Not Be"
// Chtulhu ftaghn. There are worse things in life. Mother-in-laws,
// for example. Or hangovers. Or being read poetry by a Vogon.
// Although the above construct really rates between the first tens.
Threads &threads = down_cast<DynamicProcess &> (**it1).get_dynamic_threads ();
for (Threads::iterator it2 = threads.begin (); it2 != threads.end (); it2++)
{
Requests &reqs = (*it2)->get_dynamic_requests ();
for (Requests::iterator it3 = reqs.begin (); it3 != reqs.end (); it3++)
{
SubRequests &subr = (*it3)->get_dynamic_subrequests ();
SubRequests::iterator it4 = subr.begin ();
while (it4 != subr.end ())
if ((*it4)->get_resource_key () == resource_key)
{
delete *it4;
it4 = subr.erase (it4);
}
else
it4++;
}
}
} //~ end monstrous construct, "The Thing That Should Not Be"
// Chtulhu ftaghn. There are worse things in life. Mother-in-laws,
// for example. Or hangovers. Or being read poetry by a Vogon.
// Although the above construct really rates between the first tens.
reset();
reset ();
}
void
ConcreteHistory::remove(Process& process)
ConcreteHistory::remove (Process &process)
{
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment& initial = *_snapshots.front();
ConcreteEnvironment::Processes& processes = initial.get_processes();
bool found = deep_remove<Process>(processes, process);
if (found)
reset();
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment &initial = *_snapshots.front ();
ConcreteEnvironment::Processes &processes = initial.get_processes ();
bool found = deep_remove<Process> (processes, process);
if (found)
reset ();
}
void
ConcreteHistory::remove(Thread& thread)
ConcreteHistory::remove (Thread &thread)
{
DynamicThread& dyn_thr = down_cast<DynamicThread&>(thread);
DynamicThread &dyn_thr = down_cast<DynamicThread &> (thread);
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment& initial = *_snapshots.front();
ConcreteEnvironment::Processes& processes = initial.get_processes();
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment &initial = *_snapshots.front ();
ConcreteEnvironment::Processes &processes = initial.get_processes ();
Process* found = deep_find<Process>(processes, dyn_thr.get_process());
Process *found = deep_find<Process> (processes, dyn_thr.get_process ());
if (found == nullptr)
return; // not found, just return.
if (found == nullptr)
return; // not found, just return.
DynamicProcess& dynamic_found = down_cast<DynamicProcess&>(*found);
bool removed = deep_remove<DynamicThread>(dynamic_found.get_dynamic_threads(), dyn_thr);
DynamicProcess &dynamic_found = down_cast<DynamicProcess &> (*found);
bool removed = deep_remove<DynamicThread> (dynamic_found.get_dynamic_threads (), dyn_thr);
if (removed)
reset();
if (removed)
reset ();
}
void
ConcreteHistory::remove(Request& request)
ConcreteHistory::remove (Request &request)
{
DynamicRequest& dyn_req = down_cast<DynamicRequest&>(request);
DynamicThread& dyn_thr = dyn_req.get_thread();
DynamicProcess& dyn_proc = dyn_thr.get_process();
DynamicRequest &dyn_req = down_cast<DynamicRequest &> (request);
DynamicThread &dyn_thr = dyn_req.get_thread ();
DynamicProcess &dyn_proc = dyn_thr.get_process ();
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment& initial = *_snapshots.front();
ConcreteEnvironment::Processes& processes = initial.get_processes();
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment &initial = *_snapshots.front ();
ConcreteEnvironment::Processes &processes = initial.get_processes ();
Process* proc_ref = deep_find<Process>(processes, dyn_proc);
DynamicProcess* dyn_proc_ref = down_cast<DynamicProcess*>(proc_ref);
if (dyn_proc_ref == nullptr)
return; // not found, just return.
DynamicThread* thr_ref = deep_find<DynamicThread>(dyn_proc_ref->get_dynamic_threads(), dyn_thr);
if (thr_ref == nullptr)
return; // not found, just return.
Process *proc_ref = deep_find<Process> (processes, dyn_proc);
DynamicProcess *dyn_proc_ref = down_cast<DynamicProcess *> (proc_ref);
if (dyn_proc_ref == nullptr)
return; // not found, just return.
DynamicThread *thr_ref = deep_find<DynamicThread> (dyn_proc_ref->get_dynamic_threads (), dyn_thr);
if (thr_ref == nullptr)
return; // not found, just return.
bool removed = deep_remove<DynamicRequest>(thr_ref->get_dynamic_requests(), dyn_req);
bool removed = deep_remove<DynamicRequest> (thr_ref->get_dynamic_requests (), dyn_req);
if (removed)
reset();
if (removed)
reset ();
}
void
ConcreteHistory::remove(SubRequest& subrequest)
ConcreteHistory::remove (SubRequest &subrequest)
{
// this function makes one relevant assumption:
// the initial environment does contain empty request queues only.
// this function makes one relevant assumption:
// the initial environment does contain empty request queues only.
DynamicSubRequest& dyn_sub = down_cast<DynamicSubRequest&>(subrequest);
DynamicRequest& dyn_req = dyn_sub.get_request();
DynamicThread& dyn_thr = dyn_req.get_thread();
DynamicProcess& dyn_proc = dyn_thr.get_process();
DynamicSubRequest &dyn_sub = down_cast<DynamicSubRequest &> (subrequest);
DynamicRequest &dyn_req = dyn_sub.get_request ();
DynamicThread &dyn_thr = dyn_req.get_thread ();
DynamicProcess &dyn_proc = dyn_thr.get_process ();
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment& initial = *_snapshots.front();
ConcreteEnvironment::Processes& processes = initial.get_processes();
// Pay attention that initial isn't deleted by reset()
ConcreteEnvironment &initial = *_snapshots.front ();
ConcreteEnvironment::Processes &processes = initial.get_processes ();
Process* proc_ref = deep_find<Process>(processes, dyn_proc);
DynamicProcess* dyn_proc_ref = down_cast<DynamicProcess*>(proc_ref);
if (dyn_proc_ref == nullptr)
return; // not found, just return.
DynamicThread* thr_ref = deep_find<DynamicThread>(dyn_proc_ref->get_dynamic_threads(), dyn_thr);
if (thr_ref == nullptr)
return; // not found, just return.
DynamicRequest* req_ref = deep_find<DynamicRequest>(thr_ref->get_dynamic_requests(), dyn_req);
if (req_ref == nullptr)
return; // not found, just return.
Process *proc_ref = deep_find<Process> (processes, dyn_proc);
DynamicProcess *dyn_proc_ref = down_cast<DynamicProcess *> (proc_ref);
if (dyn_proc_ref == nullptr)
return; // not found, just return.
DynamicThread *thr_ref = deep_find<DynamicThread> (dyn_proc_ref->get_dynamic_threads (), dyn_thr);
if (thr_ref == nullptr)
return; // not found, just return.
DynamicRequest *req_ref = deep_find<DynamicRequest> (thr_ref->get_dynamic_requests (), dyn_req);
if (req_ref == nullptr)
return; // not found, just return.
bool removed = deep_remove<DynamicSubRequest>(req_ref->get_dynamic_subrequests(), dyn_sub);
bool removed = deep_remove<DynamicSubRequest> (req_ref->get_dynamic_subrequests (), dyn_sub);
if (removed)
reset();
if (removed)
reset ();
}
void
ConcreteHistory::clear()
ConcreteHistory::clear ()
{
delete _snapshots.front();
_snapshots.front() = new ConcreteEnvironment();
reset();
delete _snapshots.front ();
_snapshots.front () = new ConcreteEnvironment ();
reset ();
}
ConcreteHistory::ResourcePair
ConcreteHistory::add_resource(const Glib::ustring& name,
bool /*preemptable*/,
size_t places,
size_t /*availability*/)
ConcreteHistory::add_resource (const Glib::ustring &name, bool /*preemptable*/, size_t places, size_t /*availability*/)
{
typedef ConcreteEnvironment::Resources Resources;
typedef ConcreteEnvironment::SubRequestQueue SubRequestQueue;
// And preemptable and availability?? FIXME!
typedef ConcreteEnvironment::Resources Resources;
typedef ConcreteEnvironment::SubRequestQueue SubRequestQueue;
// And preemptable and availability?? FIXME!
StaticResource* core = new StaticResource(name, places);
DynamicResource* resource = new DynamicResource(core);
StaticResource *core = new StaticResource (name, places);
DynamicResource *resource = new DynamicResource (core);
ConcreteEnvironment::Resources& resources = _snapshots.front()->get_resources();
ConcreteEnvironment::Resources &resources = _snapshots.front ()->get_resources ();
// alakazam! Black magic at work... get a unique index for this resource
resource_key_t index = 0;
while (resources.find(index) != resources.end())
index++;
// alakazam! Black magic at work... get a unique index for this resource
resource_key_t index = 0;
while (resources.find (index) != resources.end ())
index++;
// Found a hole in the map, fill it like little Hans,
// its finger and the spilling dam.
Resources::iterator temp = resources.insert(pair<resource_key_t, Resource*>(index, resource)).first;
// The same for request queues.
SubRequestQueue emptysrq;
_snapshots.front()->get_subrequest_queues().insert(pair<resource_key_t, SubRequestQueue>(index, emptysrq));
// Found a hole in the map, fill it like little Hans,
// its finger and the spilling dam.
Resources::iterator temp = resources.insert (pair<resource_key_t, Resource *> (index, resource)).first;
// The same for request queues.
SubRequestQueue emptysrq;
_snapshots.front ()->get_subrequest_queues ().insert (pair<resource_key_t, SubRequestQueue> (index, emptysrq));
reset();
reset ();
return *temp;
return *temp;
}
void
ConcreteHistory::edit_resource(Resource& resource,
const Glib::ustring& name,
bool /*preemptable*/,
size_t places,
size_t /*availability*/)
ConcreteHistory::edit_resource (Resource &resource, const Glib::ustring &name, bool /*preemptable*/, size_t places, size_t /*availability*/)
{
// And preemptable and availability?? FIXME!
// And preemptable and availability?? FIXME!
DynamicResource* res = down_cast<DynamicResource*>(&resource);
StaticResource& core = res->get_core();
core.set_name(name);
core.set_places(places);
DynamicResource *res = down_cast<DynamicResource *> (&resource);
StaticResource &core = res->get_core ();
core.set_name (name);
core.set_places (places);
reset();
reset ();
}
DynamicProcess&
ConcreteHistory::add_process(const Glib::ustring& name,
time_t arrival_time,
prio_t base_priority)
DynamicProcess &
ConcreteHistory::add_process (const Glib::ustring &name, time_t arrival_time, prio_t base_priority)
{
StaticProcess* core = new StaticProcess(name, arrival_time, base_priority);
DynamicProcess* proc = new DynamicProcess(core);
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);
ConcreteEnvironment::Processes &processes = _snapshots.front ()->get_processes ();
processes.push_back (proc);
reset();
reset ();
return *proc;
return *proc;
}
void
ConcreteHistory::edit_process(Process& process,
const Glib::ustring& name,
time_t arrival_time,
prio_t base_priority)
ConcreteHistory::edit_process (Process &process, const Glib::ustring &name, time_t arrival_time, prio_t base_priority)
{
DynamicProcess* proc = down_cast<DynamicProcess*>(&process);
StaticProcess& core = proc->get_core();
core.set_name(name);
core.set_arrival_time(arrival_time);
core.set_priority(base_priority);
DynamicProcess *proc = down_cast<DynamicProcess *> (&process);
StaticProcess &core = proc->get_core ();
core.set_name (name);
core.set_arrival_time (arrival_time);
core.set_priority (base_priority);
reset();
reset ();
}
DynamicThread&
ConcreteHistory::add_thread(const Glib::ustring& name,
Process& parent,
time_t cpu_time,
time_t arrival_time,
prio_t base_priority)
DynamicThread &
ConcreteHistory::add_thread (const Glib::ustring &name, Process &parent, time_t cpu_time, time_t arrival_time, prio_t base_priority)
{
ConcreteEnvironment::Processes& processes = _snapshots.front()->get_processes();
Process* p = deep_find<Process>(processes, parent);
if(!p) throw std::runtime_error(_("History::add_thread() : Parent process not part of this History"));
ConcreteEnvironment::Processes &processes = _snapshots.front ()->get_processes ();
Process *p = deep_find<Process> (processes, parent);
if (!p)
throw std::runtime_error (_ ("History::add_thread() : Parent process not part of this History"));
DynamicProcess& parent_process = down_cast<DynamicProcess&>(*p);
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);
DynamicProcess &parent_process = down_cast<DynamicProcess &> (*p);
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);
reset();
reset ();
return *thread;
return *thread;
}
void
ConcreteHistory::edit_thread(Thread& thread,
const Glib::ustring& name,
time_t cpu_time,
time_t arrival_time,
prio_t base_priority)
ConcreteHistory::edit_thread (Thread &thread, const Glib::ustring &name, time_t cpu_time, time_t arrival_time, prio_t base_priority)
{
DynamicThread* thre = down_cast<DynamicThread*>(&thread);
StaticThread& core = thre->get_core();
core.set_name(name);
core.set_total_cpu_time(cpu_time);
core.set_arrival_time(arrival_time);
core.set_priority(base_priority);
DynamicThread *thre = down_cast<DynamicThread *> (&thread);
StaticThread &core = thre->get_core ();
core.set_name (name);
core.set_total_cpu_time (cpu_time);
core.set_arrival_time (arrival_time);
core.set_priority (base_priority);
reset();
reset ();
}
DynamicRequest&
ConcreteHistory::add_request(Thread& owner,
time_t instant)
DynamicRequest &
ConcreteHistory::add_request (Thread &owner, time_t instant)
{
ConcreteEnvironment::Processes& processes = _snapshots.front()->get_processes();
ConcreteEnvironment::Processes &processes = _snapshots.front ()->get_processes ();
Process* p = deep_find(processes, owner.get_process());
if(!p) throw std::runtime_error(_("History::add_request() : Parent process not part of this History"));
Thread* t = deep_find(p->get_threads(), owner);
if(!t) throw std::runtime_error(_("History::add_request() : Parent thread not part of this History"));
Process *p = deep_find (processes, owner.get_process ());
if (!p)
throw std::runtime_error (_ ("History::add_request() : Parent process not part of this History"));
Thread *t = deep_find (p->get_threads (), owner);
if (!t)
throw std::runtime_error (_ ("History::add_request() : Parent thread not part of this History"));
DynamicThread& dyn_owner = down_cast<DynamicThread&>(*t);
StaticThread& owner_core = dyn_owner.get_core();
DynamicThread &dyn_owner = down_cast<DynamicThread &> (*t);
StaticThread &owner_core = dyn_owner.get_core ();
StaticRequest* core = new StaticRequest(&owner_core, instant);
DynamicRequest* req = new DynamicRequest(core, &dyn_owner);
StaticRequest *core = new StaticRequest (&owner_core, instant);
DynamicRequest *req = new DynamicRequest (core, &dyn_owner);
reset();
reset ();
return *req;
return *req;
}
void
ConcreteHistory::edit_request(Request& request,
time_t instant)
ConcreteHistory::edit_request (Request &request, time_t instant)
{
DynamicRequest* req = down_cast<DynamicRequest*>(&request);
StaticRequest& core = req->get_core();
core.set_instant(instant);
DynamicRequest *req = down_cast<DynamicRequest *> (&request);
StaticRequest &core = req->get_core ();
core.set_instant (instant);
reset();
reset ();
}
DynamicSubRequest&
ConcreteHistory::add_subrequest(Request& request,
resource_key_t resource_key,
time_t duration)
DynamicSubRequest &
ConcreteHistory::add_subrequest (Request &request, resource_key_t resource_key, time_t duration)
{
ConcreteEnvironment::Processes& processes = _snapshots.front()->get_processes();
ConcreteEnvironment::Processes &processes = _snapshots.front ()->get_processes ();
Process* p = deep_find(processes, request.get_thread().get_process());
if(!p) throw std::runtime_error(_("History::add_subrequest() : Parent process not part of this History"));
Thread* t = deep_find(p->get_threads(), request.get_thread());
if(!t) throw std::runtime_error(_("History::add_subrequest() : Parent thread not part of this History"));
Request* r = deep_find(t->get_requests(), request);
if(!r) throw std::runtime_error(_("History::add_subrequest() : Parent request not part of this History"));
Process *p = deep_find (processes, request.get_thread ().get_process ());
if (!p)
throw std::runtime_error (_ ("History::add_subrequest() : Parent process not part of this History"));
Thread *t = deep_find (p->get_threads (), request.get_thread ());
if (!t)
throw std::runtime_error (_ ("History::add_subrequest() : Parent thread not part of this History"));
Request *r = deep_find (t->get_requests (), request);
if (!r)
throw std::runtime_error (_ ("History::add_subrequest() : Parent request not part of this History"));
DynamicRequest& dyn_request = down_cast<DynamicRequest&>(*r);
DynamicRequest &dyn_request = down_cast<DynamicRequest &> (*r);
StaticSubRequest* core = new StaticSubRequest(resource_key, duration);
DynamicSubRequest* subreq = new DynamicSubRequest(core, &dyn_request);
StaticSubRequest *core = new StaticSubRequest (resource_key, duration);
DynamicSubRequest *subreq = new DynamicSubRequest (core, &dyn_request);
reset();
reset ();
return *subreq;
return *subreq;
}
void
ConcreteHistory::edit_subrequest(SubRequest& subrequest,
resource_key_t resource_key,
time_t duration)
ConcreteHistory::edit_subrequest (SubRequest &subrequest, resource_key_t resource_key, time_t duration)
{
DynamicSubRequest* sreq = down_cast<DynamicSubRequest*>(&subrequest);
StaticSubRequest& core = sreq->get_core();
core.set_resource_key(resource_key);
core.set_length(duration);
DynamicSubRequest *sreq = down_cast<DynamicSubRequest *> (&subrequest);
StaticSubRequest &core = sreq->get_core ();
core.set_resource_key (resource_key);
core.set_length (duration);
reset();
reset ();
}
void
ConcreteHistory::set_front(position p)
ConcreteHistory::set_front (position p)
{
position old_front = _front;
if (p > _snapshots.size() - 1)
{
_front = _snapshots.size() - 1;
}
else
{
_front = p;
}
position old_front = _front;
if (p > _snapshots.size () - 1)
{
_front = _snapshots.size () - 1;
}
else
{
_front = p;
}
if(old_front != _front)
notify_change();
if (old_front != _front)
notify_change ();
}
void
ConcreteHistory::reset()
ConcreteHistory::reset ()
{
#ifndef NDEBUG
static unsigned int n = 0;
std::cerr << "ConcreteHistory::reset() called for the " << ++n << "-th time." << std::endl;
static unsigned int n = 0;
std::cerr << "ConcreteHistory::reset() called for the " << ++n << "-th time." << std::endl;
#endif
assert(_snapshots.size() > 0);
Snapshots::iterator it = _snapshots.begin();
it++; // Skip first environment that we saved
assert (_snapshots.size () > 0);
Snapshots::iterator it = _snapshots.begin ();
it++; // Skip first environment that we saved
for_each(it, _snapshots.end(), [] (auto *p) { delete p; });
_snapshots.resize(1); // Truncate to keep only our "model"
_front = 0;
_sealed = false;
for_each (it, _snapshots.end (), [](auto *p) { delete p; });
_snapshots.resize (1); // Truncate to keep only our "model"
_front = 0;
_sealed = false;
notify_change();
notify_change ();
}
bool
ConcreteHistory::is_sealed() const
ConcreteHistory::is_sealed () const
{
return _sealed;
return _sealed;
}
bool
ConcreteHistory::seal()
ConcreteHistory::seal ()
{
bool t = _sealed;
_sealed = true;
return t;
bool t = _sealed;
_sealed = true;
return t;
}

View File

@ -23,7 +23,7 @@
namespace sgpem
{
class ConcreteHistory;
class ConcreteHistory;
}
#include "concrete_environment.hh"
@ -44,97 +44,72 @@ namespace sgpem
namespace sgpem
{
class SG_DLLLOCAL ConcreteHistory : public History
{
public:
ConcreteHistory();
ConcreteHistory(const ConcreteHistory&);
virtual ~ConcreteHistory();
class SG_DLLLOCAL ConcreteHistory : public History
{
public:
ConcreteHistory ();
ConcreteHistory (const ConcreteHistory &);
virtual ~ConcreteHistory ();
virtual void append_new_environment(ConcreteEnvironment* environment);
virtual size_t get_size() const;
virtual const ConcreteEnvironment& get_last_environment() const;
virtual const ConcreteEnvironment& get_environment_at(position index) const;
virtual void append_new_environment (ConcreteEnvironment *environment);
virtual size_t get_size () const;
virtual const ConcreteEnvironment &get_last_environment () const;
virtual const ConcreteEnvironment &get_environment_at (position index) const;
virtual void remove(resource_key_t resource_key);
virtual void remove(Process& process);
virtual void remove(Thread& thread);
virtual void remove(Request& request);
virtual void remove(SubRequest& subrequest);
virtual void remove (resource_key_t resource_key);
virtual void remove (Process &process);
virtual void remove (Thread &thread);
virtual void remove (Request &request);
virtual void remove (SubRequest &subrequest);
virtual void clear();
virtual void clear ();
virtual ResourcePair add_resource(const Glib::ustring& name,
bool preemptable = false,
size_t places = 1,
size_t availability = 0);
virtual ResourcePair
add_resource (const Glib::ustring &name, bool preemptable = false, size_t places = 1, size_t availability = 0);
virtual void edit_resource(Resource& resource,
const Glib::ustring& name,
bool preemptable = false,
size_t places = 1,
size_t availability = 0);
virtual void edit_resource (Resource &resource, const Glib::ustring &name, bool preemptable = false,
size_t places = 1, size_t availability = 0);
virtual DynamicProcess& add_process(const Glib::ustring& name,
time_t arrival_time,
prio_t base_priority = 0);
virtual DynamicProcess &add_process (const Glib::ustring &name, time_t arrival_time, prio_t base_priority = 0);
virtual void edit_process(Process& process,
const Glib::ustring& name,
time_t arrival_time,
prio_t base_priority = 0);
virtual void edit_process (Process &process, const Glib::ustring &name, time_t arrival_time, prio_t base_priority = 0);
virtual DynamicThread& add_thread(const Glib::ustring& name,
Process& parent,
time_t cpu_time,
time_t arrival_time = 0,
prio_t base_priority = 0);
virtual DynamicThread &add_thread (const Glib::ustring &name, Process &parent, time_t cpu_time,
time_t arrival_time = 0, prio_t base_priority = 0);
virtual void edit_thread(Thread& thread,
const Glib::ustring& name,
time_t cpu_time,
time_t arrival_time = 0,
prio_t base_priority = 0);
virtual void edit_thread (Thread &thread, const Glib::ustring &name, time_t cpu_time, time_t arrival_time = 0,
prio_t base_priority = 0);
virtual DynamicRequest& add_request(Thread& owner,
time_t instant);
virtual DynamicRequest &add_request (Thread &owner, time_t instant);
virtual void edit_request(Request& request,
time_t instant);
virtual void edit_request (Request &request, time_t instant);
virtual DynamicSubRequest& add_subrequest(Request& request,
resource_key_t resource_key,
time_t duration);
virtual DynamicSubRequest &add_subrequest (Request &request, resource_key_t resource_key, time_t duration);
virtual void edit_subrequest(SubRequest& subrequest,
resource_key_t resource_key,
time_t duration);
virtual void edit_subrequest (SubRequest &subrequest, resource_key_t resource_key, time_t duration);
// sets the front to position p
virtual void set_front(position p);
virtual void set_front (position p);
bool is_sealed() const;
bool is_sealed () const;
// (Returns if the History was sealed before this call)
bool seal();
bool seal ();
void reset(); // Implements a virtual method
void reset (); // Implements a virtual method
protected:
typedef std::vector<ConcreteEnvironment*> Snapshots;
protected:
typedef std::vector<ConcreteEnvironment *> Snapshots;
Snapshots _snapshots;
private:
private:
// Disable assignment, implement it only if needed
ConcreteHistory& operator=(const ConcreteHistory& op2);
ConcreteHistory &operator= (const ConcreteHistory &op2);
bool _sealed;
}
; //~ class ConcreteHistory
}; //~ class ConcreteHistory
}//~ namespace sgpem
} // namespace sgpem
#endif //~ CONCRETE_HISTORY_HH

View File

@ -20,11 +20,11 @@
#include "concrete_process_statistics.hh"
#include "concrete_thread_statistics.hh"
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/thread.hh>
#include <iostream>
@ -41,167 +41,165 @@ using namespace sgpem;
\param _threads_stats The statistics of the threads belonging to "core"
*/
ConcreteProcessStatistics::ConcreteProcessStatistics(const Process* core, const int& instant):
_core(core)
ConcreteProcessStatistics::ConcreteProcessStatistics (const Process *core, const int &instant) : _core (core)
{
//retrieve threads statistics necessary to calculate "core"'s statistics
vector<const Thread*> threads = core->get_threads();
for (unsigned int i_t = 0; i_t < threads.size(); i_t++)
_threads_stats.push_back(ConcreteThreadStatistics(threads[i_t], instant));
//retrieve threads statistics necessary to calculate "core"'s statistics
vector<const Thread *> threads = core->get_threads ();
for (unsigned int i_t = 0; i_t < threads.size (); i_t++)
_threads_stats.push_back (ConcreteThreadStatistics (threads[i_t], instant));
//inizialize variables
_total_inactivity = 0;
_execution_time = 0;
_response_time = -1;
_turn_around = 0;
_resource_usage_time = 0;
_resource_waitings_time = 0;
_average_response_time = 0;
int min_reponse = -1; //useful for _response_time
int arrived_threads = 0; //useful for _average_response_time
bool someone_began = false; //useful for _response_time
//inizialize variables
_total_inactivity = 0;
_execution_time = 0;
_response_time = -1;
_turn_around = 0;
_resource_usage_time = 0;
_resource_waitings_time = 0;
_average_response_time = 0;
int min_reponse = -1; //useful for _response_time
int arrived_threads = 0; //useful for _average_response_time
bool someone_began = false; //useful for _response_time
//iterate through threads statistics
vector<ConcreteThreadStatistics>::const_iterator i;
for(i = _threads_stats.begin(); i != _threads_stats.end(); i++)
{
Thread* t = const_cast<Thread*>((*i).get_core());
if (t->get_process() == *core)
{ //found a thread belonging to "core"
//iterate through threads statistics
vector<ConcreteThreadStatistics>::const_iterator i;
for (i = _threads_stats.begin (); i != _threads_stats.end (); i++)
{
Thread *t = const_cast<Thread *> ((*i).get_core ());
if (t->get_process () == *core)
{ //found a thread belonging to "core"
_execution_time += (*i).get_execution_time();
_resource_usage_time += (*i).get_resource_usage_time();
_execution_time += (*i).get_execution_time ();
_resource_usage_time += (*i).get_resource_usage_time ();
if ((*i).get_response_time() != -1)
{
_average_response_time += (*i).get_response_time();
arrived_threads++;
}
if ((*i).get_response_time () != -1)
{
_average_response_time += (*i).get_response_time ();
arrived_threads++;
}
if ((*i).get_response_time() != -1 && someone_began == false)
{
someone_began = true;
min_reponse = (*i).get_response_time();
}
if ((*i).get_response_time () != -1 && someone_began == false)
{
someone_began = true;
min_reponse = (*i).get_response_time ();
}
if(someone_began && (*i).get_response_time() != -1 && (*i).get_response_time() + (*i).get_real_arrival_time() < min_reponse)
min_reponse = (*i).get_response_time() + (*i).get_real_arrival_time();
if (someone_began && (*i).get_response_time () != -1 && (*i).get_response_time () + (*i).get_real_arrival_time () < min_reponse)
min_reponse = (*i).get_response_time () + (*i).get_real_arrival_time ();
if ((*i).get_real_arrival_time() + (*i).get_execution_time() + (*i).get_total_inactivity() > _turn_around)
_turn_around = (*i).get_real_arrival_time() + (*i).get_execution_time() + (*i).get_total_inactivity();
}
}
if ((*i).get_real_arrival_time () + (*i).get_execution_time () + (*i).get_total_inactivity () > _turn_around)
_turn_around = (*i).get_real_arrival_time () + (*i).get_execution_time () + (*i).get_total_inactivity ();
}
}
//******* AAARRRGGHH!!!
//We have to iterate the whole History ONLY to retreive _resource_waitings_time !!
//
const History& hist = Simulation::get_instance().get_history();
for (int time=0; time < instant; time++)
{
const Environment& env = hist.get_environment_at(time);
const vector<Process*> procs = env.get_processes();
//******* AAARRRGGHH!!!
//We have to iterate the whole History ONLY to retreive _resource_waitings_time !!
//
const History &hist = Simulation::get_instance ().get_history ();
for (int time = 0; time < instant; time++)
{
const Environment &env = hist.get_environment_at (time);
const vector<Process *> procs = env.get_processes ();
for (unsigned int i_p=0; i_p < procs.size(); i_p++)
if (*procs[i_p] == *core && procs[i_p]->get_state() == Schedulable::state_blocked)
_resource_waitings_time++;
}
for (unsigned int i_p = 0; i_p < procs.size (); i_p++)
if (*procs[i_p] == *core && procs[i_p]->get_state () == Schedulable::state_blocked)
_resource_waitings_time++;
}
//set other variables
if (core->get_total_cpu_time () != 0)
_execution_progress = (_execution_time * 100) / core->get_total_cpu_time ();
else
_execution_progress = 0;
//set other variables
if(core->get_total_cpu_time() != 0)
_execution_progress = (_execution_time*100) / core->get_total_cpu_time();
else
_execution_progress = 0;
_total_inactivity = _turn_around - _execution_time;
_total_inactivity = _turn_around - _execution_time;
if (_turn_around == 0)
_efficiency = -1;
else
_efficiency = (_execution_time * 100) / _turn_around;
if (_turn_around == 0)
_efficiency = -1;
else
_efficiency = (_execution_time*100)/_turn_around;
_response_time = min_reponse;
_response_time = min_reponse;
if (arrived_threads != 0)
_average_response_time = (float)((int)((_average_response_time/arrived_threads)*100))/100;
if (arrived_threads != 0)
_average_response_time = (float) ((int) ((_average_response_time / arrived_threads) * 100)) / 100;
}
ConcreteProcessStatistics::~ConcreteProcessStatistics()
ConcreteProcessStatistics::~ConcreteProcessStatistics ()
{
}
int
ConcreteProcessStatistics::get_execution_time() const
ConcreteProcessStatistics::get_execution_time () const
{
return _execution_time;
return _execution_time;
}
int
ConcreteProcessStatistics::get_execution_progress() const
ConcreteProcessStatistics::get_execution_progress () const
{
return _execution_progress;
return _execution_progress;
}
int
ConcreteProcessStatistics::get_total_inactivity() const
ConcreteProcessStatistics::get_total_inactivity () const
{
return _total_inactivity;
return _total_inactivity;
}
int
ConcreteProcessStatistics::get_response_time() const
ConcreteProcessStatistics::get_response_time () const
{
return _response_time;
return _response_time;
}
int
ConcreteProcessStatistics::get_turn_around() const
ConcreteProcessStatistics::get_turn_around () const
{
return _turn_around;
return _turn_around;
}
int
ConcreteProcessStatistics::get_efficiency() const
ConcreteProcessStatistics::get_efficiency () const
{
return _efficiency;
return _efficiency;
}
int
ConcreteProcessStatistics::get_resource_usage_time() const
ConcreteProcessStatistics::get_resource_usage_time () const
{
return _resource_usage_time;
return _resource_usage_time;
}
int
ConcreteProcessStatistics::get_resource_waitings_time() const
ConcreteProcessStatistics::get_resource_waitings_time () const
{
return _resource_waitings_time;
return _resource_waitings_time;
}
float
ConcreteProcessStatistics::get_average_response_time() const
ConcreteProcessStatistics::get_average_response_time () const
{
return _average_response_time;
return _average_response_time;
}
const Process*
ConcreteProcessStatistics::get_core() const
const Process *
ConcreteProcessStatistics::get_core () const
{
return _core;
return _core;
}
/**
\warning Don't delete these pointers!!
\warning These pointers are not valid anymore after the destruction of "this"
*/
vector<const ThreadStatistics*>
ConcreteProcessStatistics::get_threads_statistics() const
vector<const ThreadStatistics *>
ConcreteProcessStatistics::get_threads_statistics () const
{
vector<const ThreadStatistics*> rit;
for (unsigned int i=0; i < _threads_stats.size(); i++)
rit.push_back(&_threads_stats[i]);
return rit;
vector<const ThreadStatistics *> rit;
for (unsigned int i = 0; i < _threads_stats.size (); i++)
rit.push_back (&_threads_stats[i]);
return rit;
}

View File

@ -22,47 +22,47 @@
#define CONCRETE_PROCESS_STATISTICS_HH 1
#include "concrete_thread_statistics.hh"
#include <sgpemv2/process_statistics.hh>
#include <sgpemv2/thread_statistics.hh>
#include "concrete_thread_statistics.hh"
namespace sgpem
{
class ConcreteStatistics;
class ConcreteStatistics;
/** \brief Represents the statistics of a Process
/** \brief Represents the statistics of a Process
This class is a direct subclass of the abstract class ProcessStatistics.
For the documentation af all methods refere to it.
*/
class SG_DLLLOCAL ConcreteProcessStatistics : public ProcessStatistics
{
public:
friend class ConcreteStatistics;
~ConcreteProcessStatistics ();
class SG_DLLLOCAL ConcreteProcessStatistics : public ProcessStatistics
{
public:
friend class ConcreteStatistics;
~ConcreteProcessStatistics ();
int get_execution_time() const;
int get_execution_progress() const;
int get_total_inactivity() const;
int get_response_time() const;
float get_average_response_time() const;
int get_turn_around() const;
int get_efficiency() const;
int get_resource_usage_time() const;
int get_resource_waitings_time() const;
int get_execution_time () const;
int get_execution_progress () const;
int get_total_inactivity () const;
int get_response_time () const;
float get_average_response_time () const;
int get_turn_around () const;
int get_efficiency () const;
int get_resource_usage_time () const;
int get_resource_waitings_time () const;
const Process* get_core() const;
const Process *get_core () const;
std::vector<const ThreadStatistics*> get_threads_statistics() const;
private:
ConcreteProcessStatistics (const Process* core, const int& instant);
std::vector<const ThreadStatistics *> get_threads_statistics () const;
const Process* _core;
float _average_response_time;
std::vector<ConcreteThreadStatistics> _threads_stats;
};
}
private:
ConcreteProcessStatistics (const Process *core, const int &instant);
const Process *_core;
float _average_response_time;
std::vector<ConcreteThreadStatistics> _threads_stats;
};
} // namespace sgpem
#endif

View File

@ -20,248 +20,247 @@
#include "concrete_simulation.hh"
#include <sgpemv2/simulation_observer.hh>
#include <sgpemv2/scheduler.hh>
#include <sgpemv2/cpu_policies_gatekeeper.hh>
#include <sgpemv2/resource_policies_gatekeeper.hh>
#include <sgpemv2/scheduler.hh>
#include <sgpemv2/simulation_observer.hh>
#include <cassert>
#include <algorithm>
#include <cassert>
#include <functional>
#include <string>
#include <iostream>
#include <string>
using namespace sgpem;
ConcreteSimulation::ConcreteSimulation() :
Simulation(), _state(state_stopped),
_mode(mode_continuous), _policy(NULL), _resource_policy(NULL)
ConcreteSimulation::ConcreteSimulation ()
: Simulation (), _state (state_stopped), _mode (mode_continuous), _policy (NULL), _resource_policy (NULL)
{
}
void
ConcreteSimulation::set_mode(const mode new_mode)
ConcreteSimulation::set_mode (const mode new_mode)
{
_mode = new_mode;
_mode = new_mode;
}
Simulation::mode
ConcreteSimulation::get_mode() const
ConcreteSimulation::get_mode () const
{
return _mode;
return _mode;
}
void
ConcreteSimulation::jump_to(History::position p)
ConcreteSimulation::jump_to (History::position p)
{
switch (_state)
{
case state_running:
// pauses the simulation (done below)
switch (_state)
{
case state_running:
// pauses the simulation (done below)
break;
case state_stopped:
_history.set_front(0);
break;
default:
break;
}
case state_stopped:
_history.set_front (0);
break;
default:
break;
}
// Disable momentarily updates for registered observers on
// sgpem::Simulation and sgpem::History.
History::LockNotify h_lock(_history);
Simulation::LockNotify s_lock(*this);
// Disable momentarily updates for registered observers on
// sgpem::Simulation and sgpem::History.
History::LockNotify h_lock (_history);
Simulation::LockNotify s_lock (*this);
pause();
pause ();
bool yet_to_finish = true;
History::position increment = 0;
while (yet_to_finish && p > _history.get_front() + increment)
{
yet_to_finish = step();
increment++;
}
get_history().set_front(std::min(p, _history.get_size()));
bool yet_to_finish = true;
History::position increment = 0;
while (yet_to_finish && p > _history.get_front () + increment)
{
yet_to_finish = step ();
increment++;
}
get_history ().set_front (std::min (p, _history.get_size ()));
if (!yet_to_finish)
stop();
stop ();
}
void
ConcreteSimulation::pause()
ConcreteSimulation::pause ()
{
if(_state != state_paused)
if (_state != state_paused)
{
_state = state_paused;
notify_change();
_state = state_paused;
notify_change ();
}
}
void
ConcreteSimulation::stop()
ConcreteSimulation::stop ()
{
if(_state != state_stopped)
if (_state != state_stopped)
{
_state = state_stopped;
notify_change();
_state = state_stopped;
notify_change ();
}
}
void
ConcreteSimulation::run()
ConcreteSimulation::run ()
{
switch (_state)
{
case state_stopped:
_history.set_front(0);
break;
default:
break;
}
_state = state_running;
//step forward
bool yet_to_finish = step();
_history.set_front(_history.get_front() + 1);
if (yet_to_finish)
switch (_state)
{
if(_mode == mode_step_by_step)
pause();
else
// We remain in running state, and we notify everybody!
// This is non-trivial, and we must do so since we
// put the state to running inconditionally. Don't
// touch this if you don't provide another way to tell
// a SimulationObserver that the simulation advanced
// and *yet* it is in running state!
notify_change();
case state_stopped:
_history.set_front (0);
break;
default:
break;
}
else
// Simulation ended
stop();
_state = state_running;
//step forward
bool yet_to_finish = step ();
_history.set_front (_history.get_front () + 1);
if (yet_to_finish)
{
if (_mode == mode_step_by_step)
pause ();
else
// We remain in running state, and we notify everybody!
// This is non-trivial, and we must do so since we
// put the state to running inconditionally. Don't
// touch this if you don't provide another way to tell
// a SimulationObserver that the simulation advanced
// and *yet* it is in running state!
notify_change ();
}
else
// Simulation ended
stop ();
}
bool
ConcreteSimulation::step()
ConcreteSimulation::step ()
{
if (get_policy() == nullptr)
if (get_policy () == nullptr)
{
stop();
throw NullPolicyException("no CPU policy selected");
stop ();
throw NullPolicyException ("no CPU policy selected");
}
if (get_resource_policy() == nullptr)
if (get_resource_policy () == nullptr)
{
stop();
throw NullPolicyException("no resource policy selected");
stop ();
throw NullPolicyException ("no resource policy selected");
}
try
try
{
// step forward
bool yet_to_finish = true;
if (_history.get_front() == _history.get_size() - 1)
{
if(!_history.is_sealed())
yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy(), *get_resource_policy());
else
yet_to_finish = false;
}
// step forward
bool yet_to_finish = true;
if (_history.get_front () == _history.get_size () - 1)
{
if (!_history.is_sealed ())
yet_to_finish = Scheduler::get_instance ().step_forward (_history, *get_policy (), *get_resource_policy ());
else
yet_to_finish = false;
}
if (!yet_to_finish) _history.seal();
if (!yet_to_finish)
_history.seal ();
// since the simulation expects to be notified
// of simulation termination when reaching the last environment
// and the front will be updated just out of this method,
// we have to make this horrible thing
if (_history.get_front() == _history.get_size() - 2 && _history.is_sealed())
yet_to_finish = false;
// since the simulation expects to be notified
// of simulation termination when reaching the last environment
// and the front will be updated just out of this method,
// we have to make this horrible thing
if (_history.get_front () == _history.get_size () - 2 && _history.is_sealed ())
yet_to_finish = false;
return yet_to_finish;
return yet_to_finish;
}
catch (const CPUPolicyException& e)
catch (const CPUPolicyException &e)
{
stop();
throw;
stop ();
throw;
}
}
Simulation::state
ConcreteSimulation::get_state() const
ConcreteSimulation::get_state () const
{
return _state;
return _state;
}
ConcreteHistory&
ConcreteSimulation::get_history()
ConcreteHistory &
ConcreteSimulation::get_history ()
{
return _history;
return _history;
}
const ConcreteHistory&
ConcreteSimulation::get_history() const
const ConcreteHistory &
ConcreteSimulation::get_history () const
{
return _history;
return _history;
}
void
ConcreteSimulation::set_policy(CPUPolicy* p)
ConcreteSimulation::set_policy (CPUPolicy *p)
{
stop();
stop ();
try
{
CPUPoliciesGatekeeper::get_instance().activate_policy(&_history, p);
_policy = p;
}
catch(const CPUPolicyException& e1)
{
try
{
// this is a no-op if _policy is nullptr
CPUPoliciesGatekeeper::get_instance().activate_policy(&_history, _policy);
CPUPoliciesGatekeeper::get_instance ().activate_policy (&_history, p);
_policy = p;
}
catch(const CPUPolicyException& e2)
catch (const CPUPolicyException &e1)
{
_policy = nullptr;
try
{
// this is a no-op if _policy is nullptr
CPUPoliciesGatekeeper::get_instance ().activate_policy (&_history, _policy);
}
catch (const CPUPolicyException &e2)
{
_policy = nullptr;
std::string msg = _("unable to change policy and to restore the previous: ");
msg += e2.what();
std::string msg = _ ("unable to change policy and to restore the previous: ");
msg += e2.what ();
throw CPUPolicyException(msg);
throw CPUPolicyException (msg);
}
std::string msg = _ ("unable to change policy: ");
msg += e1.what ();
throw CPUPolicyException (msg);
}
std::string msg = _("unable to change policy: ");
msg+= e1.what();
throw CPUPolicyException(msg);
}
}
CPUPolicy*
ConcreteSimulation::get_policy()
CPUPolicy *
ConcreteSimulation::get_policy ()
{
return _policy;
return _policy;
}
void
ConcreteSimulation::set_resource_policy(ResourcePolicy* p)
ConcreteSimulation::set_resource_policy (ResourcePolicy *p)
{
stop();
ResourcePoliciesGatekeeper::get_instance().activate_policy(&_history, p);
_resource_policy = p;
stop ();
ResourcePoliciesGatekeeper::get_instance ().activate_policy (&_history, p);
_resource_policy = p;
}
ResourcePolicy*
ConcreteSimulation::get_resource_policy()
ResourcePolicy *
ConcreteSimulation::get_resource_policy ()
{
return _resource_policy;
return _resource_policy;
}

View File

@ -22,8 +22,8 @@
#define CONCRETE_SIMULATION_HH 1
#include <sgpemv2/simulation.hh>
#include "concrete_history.hh"
#include <sgpemv2/simulation.hh>
#include <map>
#include <stdexcept>
@ -32,12 +32,12 @@
namespace sgpem
{
class ConcreteSimulation;
class ConcreteSimulation;
class SG_DLLLOCAL ConcreteSimulation : public Simulation
{
public:
ConcreteSimulation();
class SG_DLLLOCAL ConcreteSimulation : public Simulation
{
public:
ConcreteSimulation ();
/**
* \brief Runs the simulation.
@ -45,7 +45,7 @@ namespace sgpem
* Advances the simulation by one or more steps, depending on the
* actual state and on the value set with set_mode().
*/
void run();
void run ();
/**
\brief Pauses a running simulation.
@ -54,7 +54,7 @@ namespace sgpem
Calling again run() will cause the simulation to start from the current
simulation step.
*/
void pause();
void pause ();
/**
\brief Jumps the simulation to the specified instant
@ -62,7 +62,7 @@ namespace sgpem
Pauses the simulation and jumps to the specified instant
\throw UserInterruptException, NullPolicyException, MalformedPolicyException
*/
void jump_to(History::position p);
void jump_to (History::position p);
/**
\brief Stops the simulation.
@ -70,7 +70,7 @@ namespace sgpem
Behaves in the same way as pause(), except that the next call to run()
will cause the simulation to start from the beginning.
*/
void stop();
void stop ();
/**
\brief This methods allows to change the way the simulation progresses.
@ -81,62 +81,61 @@ namespace sgpem
waiting the time defined with set_timer() between each step, until all
processes have terminated, or some error happens.
*/
void set_mode(mode new_mode);
void set_mode (mode new_mode);
/**
\return The simulation advancement mode: 0 if step-to-step, 1 if
continue.
*/
mode get_mode() const;
mode get_mode () const;
/**
\return The curent simulation state.
\see Simulation::state
*/
state get_state() const;
state get_state () const;
/**
\throw An instance of CPUPolicyException, \b not a derived class!!!
*/
void set_policy(CPUPolicy*);
void set_policy (CPUPolicy *);
/**
\brief Setup the resource policy to be used by the system.
*/
void set_resource_policy(ResourcePolicy*);
void set_resource_policy (ResourcePolicy *);
/**
\return A reference to the ConcreteHistory associated with this simulation.
*/
ConcreteHistory& get_history();
ConcreteHistory &get_history ();
/**
\return A const reference to the ConcreteHistory associated with this simulation.
*/
const ConcreteHistory& get_history() const;
const ConcreteHistory &get_history () const;
/**
\return The CPU policy currently in use.
*/
CPUPolicy* get_policy();
CPUPolicy *get_policy ();
/**
\return The resource policy currently in use.
*/
ResourcePolicy * get_resource_policy();
ResourcePolicy *get_resource_policy ();
private:
state _state;
mode _mode;
private:
state _state;
mode _mode;
ConcreteHistory _history;
CPUPolicy* _policy;
ResourcePolicy* _resource_policy;
CPUPolicy *_policy;
ResourcePolicy *_resource_policy;
bool step();
};
bool step ();
};
}
} // namespace sgpem
#endif

View File

@ -19,10 +19,10 @@
#include "concrete_simulation_statistics.hh"
#include <sgpemv2/statistics.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/statistics.hh>
#include <iostream>
#include <math.h>
@ -30,147 +30,141 @@
using namespace std;
using namespace sgpem;
ConcreteSimulationStatistics::~ConcreteSimulationStatistics()
ConcreteSimulationStatistics::~ConcreteSimulationStatistics ()
{
}
ConcreteSimulationStatistics::ConcreteSimulationStatistics(const std::vector<ConcreteProcessStatistics>& proc_stats, const int& instant)
ConcreteSimulationStatistics::ConcreteSimulationStatistics (const std::vector<ConcreteProcessStatistics> &proc_stats, const int &instant)
{
_average_inactivity_time = 0;
_average_turn_around = 0;
_average_response_time = 0;
_average_efficiency = 0;
_terminated_processes = 0;
_terminated_threads = 0;
_average_execution_progress = 0 ;
_average_processes_throughput = 0;
_average_threads_throughput = 0;
_average_inactivity_time = 0;
_average_turn_around = 0;
_average_response_time = 0;
_average_efficiency = 0;
_terminated_processes = 0;
_terminated_threads = 0;
_average_execution_progress = 0;
_average_processes_throughput = 0;
_average_threads_throughput = 0;
int started_schedulables_count = 0; //useful for stats thath can be -1
int started_schedulables_count = 0; //useful for stats thath can be -1
if (instant == -1)
return;
if (instant == -1)
return;
//get infos that don't depend on the Processes statistics
//but on the current environment:
//get infos that don't depend on the Processes statistics
//but on the current environment:
//iterate through all processes
vector<Process*> procs = Simulation::get_instance().get_history().get_environment_at(instant).get_processes();
for (unsigned int i=0; i < procs.size(); i++)
{
if (procs[i]->get_state() == Schedulable::state_terminated)
_terminated_processes++;
vector<Thread*> threads = procs[i]->get_threads();
//iterate through all threads of this process
for (unsigned int ii=0; ii < threads.size(); ii++)
if (threads[ii]->get_state() == Schedulable::state_terminated)
_terminated_threads++;
}
//Examinate processes and threads statistics:
//SUM all values from processes and threads
vector<ConcreteProcessStatistics>::const_iterator p;
for (p = proc_stats.begin(); p != proc_stats.end(); p++)
{
if (p->get_response_time() != -1)
//iterate through all processes
vector<Process *> procs = Simulation::get_instance ().get_history ().get_environment_at (instant).get_processes ();
for (unsigned int i = 0; i < procs.size (); i++)
{
started_schedulables_count++;
_average_response_time += p->get_response_time();
_average_efficiency += p->get_efficiency();
_average_inactivity_time += p->get_total_inactivity();
_average_turn_around += p->get_turn_around();
_average_execution_progress += p->get_execution_progress();
if (procs[i]->get_state () == Schedulable::state_terminated)
_terminated_processes++;
vector<Thread *> threads = procs[i]->get_threads ();
//iterate through all threads of this process
for (unsigned int ii = 0; ii < threads.size (); ii++)
if (threads[ii]->get_state () == Schedulable::state_terminated)
_terminated_threads++;
}
//iterate through all threads of this process
vector<const ThreadStatistics*> thread_stats = p->get_threads_statistics();
vector<const ThreadStatistics*>::const_iterator t;
for (t=thread_stats.begin(); t != thread_stats.end(); t++)
if ((*t)->get_response_time() != -1)
{
started_schedulables_count++;
_average_response_time += (*t)->get_response_time();
_average_efficiency += (*t)->get_efficiency();
_average_inactivity_time += (*t)->get_total_inactivity();
_average_turn_around += (*t)->get_turn_around();
_average_execution_progress += (*t)->get_execution_progress();
}
//Examinate processes and threads statistics:
//SUM all values from processes and threads
}
vector<ConcreteProcessStatistics>::const_iterator p;
for (p = proc_stats.begin (); p != proc_stats.end (); p++)
{
if (p->get_response_time () != -1)
{
started_schedulables_count++;
_average_response_time += p->get_response_time ();
_average_efficiency += p->get_efficiency ();
_average_inactivity_time += p->get_total_inactivity ();
_average_turn_around += p->get_turn_around ();
_average_execution_progress += p->get_execution_progress ();
}
//make the AVERAGE and ROUND the values
if (started_schedulables_count != 0)
{
modff(((_average_response_time / started_schedulables_count) * 100.0f) / 100.0f, &_average_response_time);
modff(((_average_efficiency / started_schedulables_count) * 100.0f) / 100.0f, &_average_efficiency);
modff(((_average_inactivity_time / started_schedulables_count) * 100.0f) / 100.0f, &_average_inactivity_time);
modff(((_average_turn_around / started_schedulables_count) * 100.0f) / 100.0f, &_average_turn_around);
modff(((_average_execution_progress / started_schedulables_count) * 100.0f) / 100.0f, &_average_execution_progress);
}
if (instant != 0)
{
modff((((float)_terminated_processes / (float)instant) * 1000.0f) / 1000.0f, &_average_processes_throughput);
modff((((float)_terminated_threads / (float)instant) * 1000.0f) / 1000.0f, &_average_threads_throughput);
}
//iterate through all threads of this process
vector<const ThreadStatistics *> thread_stats = p->get_threads_statistics ();
vector<const ThreadStatistics *>::const_iterator t;
for (t = thread_stats.begin (); t != thread_stats.end (); t++)
if ((*t)->get_response_time () != -1)
{
started_schedulables_count++;
_average_response_time += (*t)->get_response_time ();
_average_efficiency += (*t)->get_efficiency ();
_average_inactivity_time += (*t)->get_total_inactivity ();
_average_turn_around += (*t)->get_turn_around ();
_average_execution_progress += (*t)->get_execution_progress ();
}
}
//make the AVERAGE and ROUND the values
if (started_schedulables_count != 0)
{
modff (((_average_response_time / started_schedulables_count) * 100.0f) / 100.0f, &_average_response_time);
modff (((_average_efficiency / started_schedulables_count) * 100.0f) / 100.0f, &_average_efficiency);
modff (((_average_inactivity_time / started_schedulables_count) * 100.0f) / 100.0f, &_average_inactivity_time);
modff (((_average_turn_around / started_schedulables_count) * 100.0f) / 100.0f, &_average_turn_around);
modff (((_average_execution_progress / started_schedulables_count) * 100.0f) / 100.0f, &_average_execution_progress);
}
if (instant != 0)
{
modff ((((float) _terminated_processes / (float) instant) * 1000.0f) / 1000.0f, &_average_processes_throughput);
modff ((((float) _terminated_threads / (float) instant) * 1000.0f) / 1000.0f, &_average_threads_throughput);
}
}
float
ConcreteSimulationStatistics::get_average_inactivity_time() const
ConcreteSimulationStatistics::get_average_inactivity_time () const
{
return _average_inactivity_time;
return _average_inactivity_time;
}
float
ConcreteSimulationStatistics::get_average_execution_progress() const
ConcreteSimulationStatistics::get_average_execution_progress () const
{
return _average_execution_progress;
return _average_execution_progress;
}
float
ConcreteSimulationStatistics::get_average_turn_around() const
ConcreteSimulationStatistics::get_average_turn_around () const
{
return _average_turn_around;
return _average_turn_around;
}
float
ConcreteSimulationStatistics::get_average_response_time() const
ConcreteSimulationStatistics::get_average_response_time () const
{
return _average_response_time;
return _average_response_time;
}
float
ConcreteSimulationStatistics::get_average_efficiency() const
ConcreteSimulationStatistics::get_average_efficiency () const
{
return _average_efficiency;
return _average_efficiency;
}
int
ConcreteSimulationStatistics::get_terminated_processes() const
ConcreteSimulationStatistics::get_terminated_processes () const
{
return _terminated_processes;
return _terminated_processes;
}
int
ConcreteSimulationStatistics::get_terminated_threads() const
ConcreteSimulationStatistics::get_terminated_threads () const
{
return _terminated_threads;
return _terminated_threads;
}
float
ConcreteSimulationStatistics::get_average_processes_throughput() const
ConcreteSimulationStatistics::get_average_processes_throughput () const
{
return _average_processes_throughput;
return _average_processes_throughput;
}
float
ConcreteSimulationStatistics::get_average_threads_throughput() const
ConcreteSimulationStatistics::get_average_threads_throughput () const
{
return _average_threads_throughput;
return _average_threads_throughput;
}

View File

@ -22,54 +22,50 @@
#define CONCRETE_SIMULATION_STATISTICS_HH 1
#include <sgpemv2/simulation_statistics.hh>
#include "concrete_process_statistics.hh"
#include <sgpemv2/simulation_statistics.hh>
namespace sgpem
{
class ConcreteStatistics;
class ConcreteStatistics;
/** \brief Represents the statistics of a Simulation
/** \brief Represents the statistics of a Simulation
This class is a direct subclass of the abstract class SimulationStatistics.
For the documentation af all methods refere to it.
*/
class SG_DLLLOCAL ConcreteSimulationStatistics : public SimulationStatistics
{
public:
friend class ConcreteStatistics;
class SG_DLLLOCAL ConcreteSimulationStatistics : public SimulationStatistics
{
public:
friend class ConcreteStatistics;
~ConcreteSimulationStatistics();
~ConcreteSimulationStatistics ();
float get_average_inactivity_time() const ;
float get_average_execution_progress() const;
float get_average_turn_around() const ;
float get_average_response_time() const ;
float get_average_efficiency() const ;
int get_terminated_processes() const ;
int get_terminated_threads() const ;
float get_average_processes_throughput() const ;
float get_average_threads_throughput() const ;
float get_average_inactivity_time () const;
float get_average_execution_progress () const;
float get_average_turn_around () const;
float get_average_response_time () const;
float get_average_efficiency () const;
int get_terminated_processes () const;
int get_terminated_threads () const;
float get_average_processes_throughput () const;
float get_average_threads_throughput () const;
protected:
ConcreteSimulationStatistics(const std::vector<ConcreteProcessStatistics>& proc_stats, const int& instant);
protected:
ConcreteSimulationStatistics (const std::vector<ConcreteProcessStatistics> &proc_stats, const int &instant);
float _average_inactivity_time ;
float _average_execution_progress ;
float _average_turn_around ;
float _average_response_time ;
float _average_efficiency ;
int _terminated_processes ;
int _terminated_threads ;
float _average_processes_throughput ;
float _average_threads_throughput ;
};
}
float _average_inactivity_time;
float _average_execution_progress;
float _average_turn_around;
float _average_response_time;
float _average_efficiency;
int _terminated_processes;
int _terminated_threads;
float _average_processes_throughput;
float _average_threads_throughput;
};
} // namespace sgpem
#endif

View File

@ -19,14 +19,14 @@
#include "concrete_statistics.hh"
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/thread.hh>
#include "concrete_thread_statistics.hh"
#include "concrete_process_statistics.hh"
#include "concrete_thread_statistics.hh"
#include <sgpemv2/environment.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/thread.hh>
#include <iostream>
@ -34,46 +34,43 @@ using namespace sgpem;
using namespace std;
ConcreteStatistics::ConcreteStatistics(): _sim_stats(0)
ConcreteStatistics::ConcreteStatistics () : _sim_stats (0)
{
calculateStatisticsAt(-1);
calculateStatisticsAt (-1);
}
void
ConcreteStatistics::calculateStatisticsAt(const int& instant)
ConcreteStatistics::calculateStatisticsAt (const int &instant)
{
//retrieve all processes
vector<Process*> procs = Simulation::get_instance().get_history().get_environment_at(0).get_processes();
//retrieve all processes
vector<Process *> procs = Simulation::get_instance ().get_history ().get_environment_at (0).get_processes ();
//create all process statistics (which themselves create their thread statistics)
_proc_stats.clear();
for (unsigned int p = 0; p < procs.size(); p++)
_proc_stats.push_back(ConcreteProcessStatistics(procs[p], instant));
//create all process statistics (which themselves create their thread statistics)
_proc_stats.clear ();
for (unsigned int p = 0; p < procs.size (); p++)
_proc_stats.push_back (ConcreteProcessStatistics (procs[p], instant));
if (_sim_stats)
delete _sim_stats;
//create simulation statistics using just obtained process statistics
_sim_stats = new ConcreteSimulationStatistics(_proc_stats, instant);
if (_sim_stats)
delete _sim_stats;
//create simulation statistics using just obtained process statistics
_sim_stats = new ConcreteSimulationStatistics (_proc_stats, instant);
}
const SimulationStatistics*
ConcreteStatistics::get_simulation_statistics() const
const SimulationStatistics *
ConcreteStatistics::get_simulation_statistics () const
{
return _sim_stats;
return _sim_stats;
}
/**
\warning Don't delete these pointers!!
\warning These pointers are not valid anymore AFTER a call to calculateStatisticsAt
*/
std::vector<const ProcessStatistics*>
ConcreteStatistics::get_process_statistics() const
std::vector<const ProcessStatistics *>
ConcreteStatistics::get_process_statistics () const
{
vector<const ProcessStatistics*> rit;
for (unsigned int i=0; i < _proc_stats.size(); i++)
rit.push_back(&_proc_stats[i]);
return rit;
vector<const ProcessStatistics *> rit;
for (unsigned int i = 0; i < _proc_stats.size (); i++)
rit.push_back (&_proc_stats[i]);
return rit;
}

View File

@ -22,39 +22,34 @@
#define CONCRETE_STATISTICS_HH 1
#include <sgpemv2/statistics.hh>
#include "concrete_process_statistics.hh"
#include "concrete_simulation_statistics.hh"
#include <sgpemv2/statistics.hh>
#include <glibmm/ustring.h>
#include <vector>
namespace sgpem
{
/** \brief Implements the abstract class Statistics
/** \brief Implements the abstract class Statistics
This class is a direct subclass of the abstract class Statistics.
For the documentation af all methods refere to it.
*/
class SG_DLLLOCAL ConcreteStatistics : public Statistics
{
public:
ConcreteStatistics();
class SG_DLLLOCAL ConcreteStatistics : public Statistics
{
public:
ConcreteStatistics ();
void calculateStatisticsAt(const int& instant);
void calculateStatisticsAt (const int &instant);
const SimulationStatistics* get_simulation_statistics() const;
std::vector<const ProcessStatistics*> get_process_statistics() const;
const SimulationStatistics *get_simulation_statistics () const;
std::vector<const ProcessStatistics *> get_process_statistics () const;
private:
ConcreteSimulationStatistics* _sim_stats;
std::vector<ConcreteProcessStatistics> _proc_stats;
};
}
private:
ConcreteSimulationStatistics *_sim_stats;
std::vector<ConcreteProcessStatistics> _proc_stats;
};
} // namespace sgpem
#endif

View File

@ -19,15 +19,15 @@
#include "concrete_thread_statistics.hh"
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/thread.hh>
#include <sgpemv2/resource.hh>
#include <sgpemv2/request.hh>
#include <iostream>
#include <sgpemv2/environment.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/request.hh>
#include <sgpemv2/resource.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/thread.hh>
using namespace std;
using namespace sgpem;
@ -37,159 +37,157 @@ using namespace sgpem;
or the whole History
*/
ConcreteThreadStatistics::ConcreteThreadStatistics(const Thread* core, const int& instant): _core(core)
ConcreteThreadStatistics::ConcreteThreadStatistics (const Thread *core, const int &instant) : _core (core)
{
//initializations
_total_inactivity = 0;
_execution_time = 0;
_response_time = -1;
_real_arrival_time = -1;
_turn_around = 0;
_resource_usage_time = 0;
_resource_waitings_time = 0;
//initializations
_total_inactivity = 0;
_execution_time = 0;
_response_time = -1;
_real_arrival_time = -1;
_turn_around = 0;
_resource_usage_time = 0;
_resource_waitings_time = 0;
bool iniziato = false; //useful for _response_time
bool iniziato = false; //useful for _response_time
const History& hist = Simulation::get_instance().get_history(); //prendo la lista delle risorse
const map<Environment::resource_key_t, Resource*> res = hist.get_environment_at(0).get_resources();
const History &hist = Simulation::get_instance ().get_history (); //prendo la lista delle risorse
const map<Environment::resource_key_t, Resource *> res = hist.get_environment_at (0).get_resources ();
//****** iterate through HISTORY to retreive informations
for (int time=0; time < instant; time++)
{
const Environment& env = hist.get_environment_at(time);
const vector<Process*> procs = env.get_processes();
//****** iterate through HISTORY to retreive informations
for (int time = 0; time < instant; time++)
{
const Environment &env = hist.get_environment_at (time);
const vector<Process *> procs = env.get_processes ();
//looks for the process that owns this thread
for (unsigned int i_p=0; i_p < procs.size(); i_p++)
{
const vector<Thread*> threads = procs[i_p]->get_threads();
//looks for the thread "core"
for (unsigned int i_t = 0; i_t < threads.size(); i_t++)
{
if ( (*threads[i_t]) == (*core) ) //FOUND!!
{
if (threads[i_t]->get_state() == Schedulable::state_running)
{
iniziato = true;
if( _response_time == -1) //arrives and runs immediately
{
_response_time = 0;
_real_arrival_time = time - procs[i_p]->get_arrival_time() -1;
}
_execution_time++;
}
if (threads[i_t]->get_state() != Schedulable::state_future &&
threads[i_t]->get_state() != Schedulable::state_terminated)
{
_turn_around++;
if (!iniziato && _response_time == -1) //arrives and doesn't run
{
_response_time = 0;
_real_arrival_time = time - procs[i_p]->get_arrival_time() -1;
}
}
if (threads[i_t]->get_state() == Schedulable::state_blocked
|| threads[i_t]->get_state() == Schedulable::state_ready)
{
_total_inactivity++;
if (!iniziato && _response_time != -1)
_response_time++;
//looks for the process that owns this thread
for (unsigned int i_p = 0; i_p < procs.size (); i_p++)
{
const vector<Thread *> threads = procs[i_p]->get_threads ();
//looks for the thread "core"
for (unsigned int i_t = 0; i_t < threads.size (); i_t++)
{
if ((*threads[i_t]) == (*core)) //FOUND!!
{
if (threads[i_t]->get_state () == Schedulable::state_running)
{
iniziato = true;
if (_response_time == -1) //arrives and runs immediately
{
_response_time = 0;
_real_arrival_time = time - procs[i_p]->get_arrival_time () - 1;
}
_execution_time++;
}
if (threads[i_t]->get_state () != Schedulable::state_future && threads[i_t]->get_state () != Schedulable::state_terminated)
{
_turn_around++;
if (!iniziato && _response_time == -1) //arrives and doesn't run
{
_response_time = 0;
_real_arrival_time = time - procs[i_p]->get_arrival_time () - 1;
}
}
if (threads[i_t]->get_state () == Schedulable::state_blocked || threads[i_t]->get_state () == Schedulable::state_ready)
{
_total_inactivity++;
if (!iniziato && _response_time != -1)
_response_time++;
if (threads[i_t]->get_state() == Schedulable::state_blocked)
_resource_waitings_time++;
}
}
} //threads
} //procs
if (threads[i_t]->get_state () == Schedulable::state_blocked)
_resource_waitings_time++;
}
}
} //threads
} //procs
//for each resource check requests at this istant:
//if the request of this thread is allocated then increase _resource_usage_time
Environment::Resources::const_iterator res_iter = res.begin();
while(res_iter != res.end())
{
Environment::resource_key_t key = (*res_iter).first;
vector<SubRequest*> req = env.get_request_queue(key);
for (unsigned int i_r=0; i_r < req.size(); i_r++)
if( (*req[i_r]).get_request().get_thread() == (*core) && (*req[i_r]).get_state() == Request::state_allocated)
_resource_usage_time++;
//for each resource check requests at this istant:
//if the request of this thread is allocated then increase _resource_usage_time
Environment::Resources::const_iterator res_iter = res.begin ();
while (res_iter != res.end ())
{
Environment::resource_key_t key = (*res_iter).first;
vector<SubRequest *> req = env.get_request_queue (key);
for (unsigned int i_r = 0; i_r < req.size (); i_r++)
if ((*req[i_r]).get_request ().get_thread () == (*core) && (*req[i_r]).get_state () == Request::state_allocated)
_resource_usage_time++;
res_iter++;
}
res_iter++;
}
}//istants
} //istants
//set other variables
if (core->get_total_cpu_time() != 0)
_execution_progress = (100*_execution_time)/core->get_total_cpu_time();
//set other variables
if (core->get_total_cpu_time () != 0)
_execution_progress = (100 * _execution_time) / core->get_total_cpu_time ();
if (_turn_around == 0)
_efficiency = -1;
else
_efficiency = (_execution_time*100)/_turn_around;
if (_turn_around == 0)
_efficiency = -1;
else
_efficiency = (_execution_time * 100) / _turn_around;
}
ConcreteThreadStatistics::~ConcreteThreadStatistics()
ConcreteThreadStatistics::~ConcreteThreadStatistics ()
{
}
int
ConcreteThreadStatistics::get_execution_time() const
ConcreteThreadStatistics::get_execution_time () const
{
return _execution_time;
return _execution_time;
}
int
ConcreteThreadStatistics::get_execution_progress() const
ConcreteThreadStatistics::get_execution_progress () const
{
return _execution_progress;
return _execution_progress;
}
int
ConcreteThreadStatistics::get_total_inactivity() const
ConcreteThreadStatistics::get_total_inactivity () const
{
return _total_inactivity;
return _total_inactivity;
}
int
ConcreteThreadStatistics::get_response_time() const
ConcreteThreadStatistics::get_response_time () const
{
return _response_time;
return _response_time;
}
int
ConcreteThreadStatistics::get_turn_around() const
ConcreteThreadStatistics::get_turn_around () const
{
return _turn_around;
return _turn_around;
}
int
ConcreteThreadStatistics::get_efficiency() const
ConcreteThreadStatistics::get_efficiency () const
{
return _efficiency;
return _efficiency;
}
int
ConcreteThreadStatistics::get_resource_usage_time() const
ConcreteThreadStatistics::get_resource_usage_time () const
{
return _resource_usage_time;
return _resource_usage_time;
}
int
ConcreteThreadStatistics::get_resource_waitings_time() const
ConcreteThreadStatistics::get_resource_waitings_time () const
{
return _resource_waitings_time;
return _resource_waitings_time;
}
int
ConcreteThreadStatistics::get_real_arrival_time() const
ConcreteThreadStatistics::get_real_arrival_time () const
{
return _real_arrival_time;
return _real_arrival_time;
}
const Thread*
ConcreteThreadStatistics::get_core() const
const Thread *
ConcreteThreadStatistics::get_core () const
{
return _core;
return _core;
}

View File

@ -22,7 +22,6 @@
#define CONCRETE_THREAD_STATISTICS_HH 1
#include <sgpemv2/thread_statistics.hh>
#include <glibmm/ustring.h>
@ -30,38 +29,38 @@
namespace sgpem
{
class ConcreteProcessStatistics;
class ConcreteProcessStatistics;
/** \brief Represents the statistics of a Thread
/** \brief Represents the statistics of a Thread
This class is a direct subclass of the abstract class ThreadStatistics.
For the documentation af all methods refere to it.
*/
class SG_DLLLOCAL ConcreteThreadStatistics : public ThreadStatistics
{
public:
friend class ConcreteProcessStatistics;
~ConcreteThreadStatistics();
class SG_DLLLOCAL ConcreteThreadStatistics : public ThreadStatistics
{
public:
friend class ConcreteProcessStatistics;
~ConcreteThreadStatistics ();
int get_execution_time() const;
int get_execution_progress() const;
int get_total_inactivity() const;
int get_response_time() const;
int get_turn_around() const;
int get_efficiency() const;
int get_resource_usage_time() const;
int get_resource_waitings_time() const;
int get_execution_time () const;
int get_execution_progress () const;
int get_total_inactivity () const;
int get_response_time () const;
int get_turn_around () const;
int get_efficiency () const;
int get_resource_usage_time () const;
int get_resource_waitings_time () const;
const Thread* get_core() const;
const Thread *get_core () const;
int get_real_arrival_time() const; //useful for ProcessStatistics
int get_real_arrival_time () const; //useful for ProcessStatistics
private:
ConcreteThreadStatistics(const Thread* core, const int& instant);
const Thread* _core;
int _real_arrival_time;
};
}
private:
ConcreteThreadStatistics (const Thread *core, const int &instant);
const Thread *_core;
int _real_arrival_time;
};
} // namespace sgpem
#endif

View File

@ -18,10 +18,9 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include "cpp_resource_policy_manager.hh"
#include "resource_policy_lifo.hh"
#include "resource_policy_fifo.hh"
#include "resource_policy_lifo.hh"
#include "resource_policy_priority.hh"
#include "resource_policy_priority_inheritance.hh"
@ -33,24 +32,24 @@ using namespace sgpem;
CppResourcePolicyManager CppResourcePolicyManager::_default_instance;
CppResourcePolicyManager::CppResourcePolicyManager()
CppResourcePolicyManager::CppResourcePolicyManager ()
{
ResourcePoliciesGatekeeper::get_instance().register_manager(this);
// Includes default policies.
_policies.push_back(new ResourcePolicyLiFo());
_policies.push_back(new ResourcePolicyFiFo());
_policies.push_back(new ResourcePolicyPriority());
_policies.push_back(new ResourcePolicyPriorityInheritance());
ResourcePoliciesGatekeeper::get_instance ().register_manager (this);
// Includes default policies.
_policies.push_back (new ResourcePolicyLiFo ());
_policies.push_back (new ResourcePolicyFiFo ());
_policies.push_back (new ResourcePolicyPriority ());
_policies.push_back (new ResourcePolicyPriorityInheritance ());
}
CppResourcePolicyManager::~CppResourcePolicyManager()
CppResourcePolicyManager::~CppResourcePolicyManager ()
{
ResourcePoliciesGatekeeper::get_instance().unregister_manager(this);
ResourcePoliciesGatekeeper::get_instance ().unregister_manager (this);
}
const std::vector<ResourcePolicy*>&
CppResourcePolicyManager::get_avail_policies() const
const std::vector<ResourcePolicy *> &
CppResourcePolicyManager::get_avail_policies () const
{
return _policies;
return _policies;
}

View File

@ -23,7 +23,7 @@
namespace sgpem
{
class ResourcePolicy;
class ResourcePolicy;
}
#include <sgpemv2/resource_policy_manager.hh>
@ -32,33 +32,32 @@ namespace sgpem
namespace sgpem
{
class CppResourcePolicyManager;
class CppResourcePolicyManager;
/**
/**
ResourcePolicyManager is the Abstract Factory for \ref ResourcePolicy objects.
*/
class SG_DLLLOCAL CppResourcePolicyManager : public ResourcePolicyManager
{
public:
class SG_DLLLOCAL CppResourcePolicyManager : public ResourcePolicyManager
{
public:
/** \brief CppResourcePolicyManager constructor
*
* Registers itself to the ResourcePoliciesGatekeeper singleton.
*/
CppResourcePolicyManager();
CppResourcePolicyManager ();
virtual ~CppResourcePolicyManager();
virtual ~CppResourcePolicyManager ();
virtual const std::vector<ResourcePolicy*>& get_avail_policies() const;
virtual const std::vector<ResourcePolicy *> &get_avail_policies () const;
private:
std::vector<ResourcePolicy*> _policies;
private:
std::vector<ResourcePolicy *> _policies;
// an Instance of this class is created by default and it is registered to
// the ResourcePolicyGateKeeper
static CppResourcePolicyManager _default_instance;
};
};
} //~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -18,12 +18,10 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/cpu_policies_gatekeeper.hh>
#include <sgpemv2/cpu_policy_manager.hh>
#include <sgpemv2/cpu_policy.hh>
#include "concrete_history.hh"
#include <sgpemv2/cpu_policies_gatekeeper.hh>
#include <sgpemv2/cpu_policy.hh>
#include <sgpemv2/cpu_policy_manager.hh>
// Include full template definition only in implementation files:
#include <sgpemv2/templates/singleton.tcc>
@ -34,136 +32,136 @@
#include <cassert>
#include <iostream>
using std::vector;
using std::map;
using std::find;
using std::map;
using std::runtime_error;
using std::vector;
using namespace sgpem;
// Explicit template instantiation to allow to export symbols from the DSO.
template class sgpem::Singleton<CPUPoliciesGatekeeper>;
typedef vector<CPUPolicyManager*>::iterator ManagerIterator;
typedef map<History*, CPUPolicy*>::iterator ActiveIterator;
typedef vector<CPUPolicyManager *>::iterator ManagerIterator;
typedef map<History *, CPUPolicy *>::iterator ActiveIterator;
vector<CPUPolicyManager*>
CPUPoliciesGatekeeper::get_registered() const
vector<CPUPolicyManager *>
CPUPoliciesGatekeeper::get_registered () const
{
return _registered;
return _registered;
}
void
CPUPoliciesGatekeeper::register_manager(CPUPolicyManager* manager)
CPUPoliciesGatekeeper::register_manager (CPUPolicyManager *manager)
{
assert(manager != nullptr);
assert (manager != nullptr);
ManagerIterator end = _registered.end();
ManagerIterator end = _registered.end ();
if (find(_registered.begin(), end, manager) == end)
_registered.push_back(manager);
if (find (_registered.begin (), end, manager) == end)
_registered.push_back (manager);
}
void
CPUPoliciesGatekeeper::unregister_manager(CPUPolicyManager* manager)
CPUPoliciesGatekeeper::unregister_manager (CPUPolicyManager *manager)
{
assert(manager != nullptr);
assert (manager != nullptr);
ManagerIterator end = _registered.end();
ManagerIterator pos = find(_registered.begin(), end, manager);
ManagerIterator end = _registered.end ();
ManagerIterator pos = find (_registered.begin (), end, manager);
if (pos != end)
{
deactivate_policies(*pos);
_registered.erase(pos);
}
}
CPUPolicy*
CPUPoliciesGatekeeper::get_current_policy(History* history)
{
assert(history != nullptr);
ActiveIterator policy = _active_policies.find(history);
if (policy == _active_policies.end())
throw runtime_error("No active policy associated with this "
"history is available.");
return policy->second;
}
void
CPUPoliciesGatekeeper::activate_policy(History *history, CPUPolicy* policy)
{
assert(history != nullptr);
ActiveIterator end = _active_policies.end();
ActiveIterator pos = _active_policies.find(history);
// deactivate the policy, if necessary
if (pos != end)
{
// nothing to do in this case
if(pos->second == policy)
return;
pos->second->deactivate();
}
// if policy is nullptr, simply erase the entry and return, since we are sure the policy is
// not active due to the previous lines
if(policy == nullptr)
{
// this is a no-op if history is not a key used in the map
_active_policies.erase(history);
return;
}
try
{
policy->activate();
_active_policies[history] = policy;
// the content of history (if any) is not vaild any more.
down_cast<ConcreteHistory*>(history)->reset();
}
catch(const CPUPolicyException& e)
{
// the caller need to know if it failed
throw;
}
}
CPUPoliciesGatekeeper::CPUPoliciesGatekeeper()
{}
void
CPUPoliciesGatekeeper::deactivate_policies(CPUPolicyManager* manager)
{
typedef vector<CPUPolicy*>::iterator CPUPolicyIterator;
vector<CPUPolicy*> avail_policies = manager->get_avail_policies();
CPUPolicyIterator avail_it = avail_policies.begin();
CPUPolicyIterator avail_end = avail_policies.end();
for (; avail_it != avail_end; ++avail_it)
{
ActiveIterator act_it = _active_policies.begin();
while (act_it != _active_policies.end())
if (pos != end)
{
if (act_it->second == *avail_it)
{
act_it->second->deactivate();
// Please note the postfix increment
// (operating on the old, now invalidated by
// erase, iterator object):
_active_policies.erase(act_it++);
}
else
++act_it;
deactivate_policies (*pos);
_registered.erase (pos);
}
} //~ for(avail_it)
}
CPUPolicy *
CPUPoliciesGatekeeper::get_current_policy (History *history)
{
assert (history != nullptr);
ActiveIterator policy = _active_policies.find (history);
if (policy == _active_policies.end ())
throw runtime_error (
"No active policy associated with this "
"history is available.");
return policy->second;
}
void
CPUPoliciesGatekeeper::activate_policy (History *history, CPUPolicy *policy)
{
assert (history != nullptr);
ActiveIterator end = _active_policies.end ();
ActiveIterator pos = _active_policies.find (history);
// deactivate the policy, if necessary
if (pos != end)
{
// nothing to do in this case
if (pos->second == policy)
return;
pos->second->deactivate ();
}
// if policy is nullptr, simply erase the entry and return, since we are sure the policy is
// not active due to the previous lines
if (policy == nullptr)
{
// this is a no-op if history is not a key used in the map
_active_policies.erase (history);
return;
}
try
{
policy->activate ();
_active_policies[history] = policy;
// the content of history (if any) is not vaild any more.
down_cast<ConcreteHistory *> (history)->reset ();
}
catch (const CPUPolicyException &e)
{
// the caller need to know if it failed
throw;
}
}
CPUPoliciesGatekeeper::CPUPoliciesGatekeeper ()
{
}
void
CPUPoliciesGatekeeper::deactivate_policies (CPUPolicyManager *manager)
{
typedef vector<CPUPolicy *>::iterator CPUPolicyIterator;
vector<CPUPolicy *> avail_policies = manager->get_avail_policies ();
CPUPolicyIterator avail_it = avail_policies.begin ();
CPUPolicyIterator avail_end = avail_policies.end ();
for (; avail_it != avail_end; ++avail_it)
{
ActiveIterator act_it = _active_policies.begin ();
while (act_it != _active_policies.end ())
{
if (act_it->second == *avail_it)
{
act_it->second->deactivate ();
// Please note the postfix increment
// (operating on the old, now invalidated by
// erase, iterator object):
_active_policies.erase (act_it++);
}
else
++act_it;
}
} //~ for(avail_it)
}

View File

@ -24,32 +24,33 @@ using namespace sgpem;
// Static member data
CPUPolicy* CPUPolicy::_callback_policy = nullptr;
CPUPolicy *CPUPolicy::_callback_policy = nullptr;
CPUPolicy::~CPUPolicy()
{}
PolicyParameters&
CPUPolicy::get_parameters()
CPUPolicy::~CPUPolicy ()
{
return _parameters;
}
CPUPolicy*
CPUPolicy::callback_get_policy()
PolicyParameters &
CPUPolicy::get_parameters ()
{
if(_callback_policy == nullptr)
throw std::runtime_error("CPUPolicy::callback_get_policy() not used as a callback method. nullptr ptr returned.");
return _callback_policy;
return _parameters;
}
CPUPolicy *
CPUPolicy::callback_get_policy ()
{
if (_callback_policy == nullptr)
throw std::runtime_error (
"CPUPolicy::callback_get_policy() not used as a callback method. nullptr ptr returned.");
return _callback_policy;
}
void
CPUPolicy::set_callback_policy(CPUPolicy* ptr)
CPUPolicy::set_callback_policy (CPUPolicy *ptr)
{
_callback_policy = ptr;
_callback_policy = ptr;
}

View File

@ -25,7 +25,6 @@
#include <sgpemv2/malformed_policy_exception.hh>
using namespace sgpem;
CPUPolicyException::CPUPolicyException(const std::string& msg)
: std::runtime_error(msg)
{}
CPUPolicyException::CPUPolicyException (const std::string &msg) : std::runtime_error (msg)
{
}

View File

@ -18,20 +18,18 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/cpu_policy_manager.hh>
#include <sgpemv2/cpu_policies_gatekeeper.hh>
#include <sgpemv2/cpu_policy_manager.hh>
using namespace sgpem;
CPUPolicyManager::CPUPolicyManager()
CPUPolicyManager::CPUPolicyManager ()
{
CPUPoliciesGatekeeper::get_instance().register_manager(this);
CPUPoliciesGatekeeper::get_instance ().register_manager (this);
}
CPUPolicyManager::~CPUPolicyManager()
CPUPolicyManager::~CPUPolicyManager ()
{
CPUPoliciesGatekeeper::get_instance().unregister_manager(this);
CPUPoliciesGatekeeper::get_instance ().unregister_manager (this);
}

View File

@ -19,188 +19,182 @@
#include "dynamic_process.hh"
#include "static_process.hh"
#include "dynamic_thread.hh"
#include "static_process.hh"
#include <sgpemv2/serialize_visitor.hh>
#include <sgpemv2/templates/sequences.tcc>
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <cassert>
using namespace sgpem;
using namespace std;
typedef std::vector<DynamicThread*>::const_iterator ConstThreadIt;
typedef std::vector<DynamicThread*>::iterator ThreadIt;
typedef std::vector<DynamicThread *>::const_iterator ConstThreadIt;
typedef std::vector<DynamicThread *>::iterator ThreadIt;
DynamicProcess::DynamicProcess(StaticProcess* core) :
DynamicSchedulable(), _core(core)
DynamicProcess::DynamicProcess (StaticProcess *core) : DynamicSchedulable (), _core (core)
{
assert(core != nullptr);
assert (core != nullptr);
}
DynamicProcess::DynamicProcess(const DynamicProcess &other) :
Schedulable(), DynamicSchedulable(other), Process(),
_core(other._core)
DynamicProcess::DynamicProcess (const DynamicProcess &other)
: Schedulable (), DynamicSchedulable (other), Process (), _core (other._core)
{
for (Iseq<ConstThreadIt> seq = iseq(other._dynamic_threads); seq; ++seq)
new DynamicThread(*(*seq), this);
for (Iseq<ConstThreadIt> seq = iseq (other._dynamic_threads); seq; ++seq)
new DynamicThread (*(*seq), this);
}
DynamicProcess::~DynamicProcess()
DynamicProcess::~DynamicProcess ()
{
for_each(_dynamic_threads.begin(),
_dynamic_threads.end(),
[] (auto *p) { delete p; });
for_each (_dynamic_threads.begin (), _dynamic_threads.end (), [](auto *p) { delete p; });
}
std::vector<Thread*>
DynamicProcess::get_threads()
std::vector<Thread *>
DynamicProcess::get_threads ()
{
return vector<Thread*>(_dynamic_threads.begin(), _dynamic_threads.end());
return vector<Thread *> (_dynamic_threads.begin (), _dynamic_threads.end ());
}
std::vector<const Thread*>
DynamicProcess::get_threads() const
std::vector<const Thread *>
DynamicProcess::get_threads () const
{
return vector<const Thread*>(_dynamic_threads.begin(), _dynamic_threads.end());
return vector<const Thread *> (_dynamic_threads.begin (), _dynamic_threads.end ());
}
Schedulable::state
DynamicProcess::get_state() const
DynamicProcess::get_state () const
{
const int uninitialized = -1;
const int uninitialized = -1;
state result = state_terminated;
int next_thread_starts_at = uninitialized;
state result = state_terminated;
int next_thread_starts_at = uninitialized;
// This is the logic behind the code:
// If there is at least one running thread, the result is
// running. If not, it may be either blocked, ready, future or terminated.
// This is the logic behind the code:
// If there is at least one running thread, the result is
// running. If not, it may be either blocked, ready, future or terminated.
// We have these cases (a state takes precedence over some other one):
// (a) if a thread is running, return immediately state_running
// (b) if a thread is ready, puts unconditionally result as state_ready,
// and continue iterating (to see if there's a running thread)
// (c) if a thread is blocked, and result is not state_ready, result
// becomes state_blocked, and continue iterating (to see if there are
// ready or running threads)
// (d) if a thread is future, and result is not state_ready or
// state_blocked, put result as state_future, and remember
// when the next thread will start (d1) (see at the end of this
// method for the rationale (d2)). Then continue iterating.
// (e) else (if all threads are state_terminated) put result as
// state_terminated.
// We have these cases (a state takes precedence over some other one):
// (a) if a thread is running, return immediately state_running
// (b) if a thread is ready, puts unconditionally result as state_ready,
// and continue iterating (to see if there's a running thread)
// (c) if a thread is blocked, and result is not state_ready, result
// becomes state_blocked, and continue iterating (to see if there are
// ready or running threads)
// (d) if a thread is future, and result is not state_ready or
// state_blocked, put result as state_future, and remember
// when the next thread will start (d1) (see at the end of this
// method for the rationale (d2)). Then continue iterating.
// (e) else (if all threads are state_terminated) put result as
// state_terminated.
for(Iseq<ConstThreadIt> seq = iseq(_dynamic_threads); seq; ++seq)
{
const state thread_state = (*seq)->get_state();
switch(thread_state)
for (Iseq<ConstThreadIt> seq = iseq (_dynamic_threads); seq; ++seq)
{
case state_running: // (a)
return state_running;
case state_ready: // (b)
result = state_ready;
continue;
case state_blocked: // (c)
if((result & state_ready) == 0)
result = state_blocked;
continue;
case state_future: // (d)
if((result & (state_ready|state_blocked)) == 0)
const state thread_state = (*seq)->get_state ();
switch (thread_state)
{
result = state_future;
int thread_starts_at = (*seq)->get_arrival_time();
if(next_thread_starts_at == uninitialized) // (d1)
next_thread_starts_at = thread_starts_at;
else
next_thread_starts_at = std::min(thread_starts_at, next_thread_starts_at);
case state_running: // (a)
return state_running;
case state_ready: // (b)
result = state_ready;
continue;
case state_blocked: // (c)
if ((result & state_ready) == 0)
result = state_blocked;
continue;
case state_future: // (d)
if ((result & (state_ready | state_blocked)) == 0)
{
result = state_future;
int thread_starts_at = (*seq)->get_arrival_time ();
if (next_thread_starts_at == uninitialized) // (d1)
next_thread_starts_at = thread_starts_at;
else
next_thread_starts_at = std::min (thread_starts_at, next_thread_starts_at);
}
continue;
case state_terminated: // (e)
// already put into terminated state as the default value
continue;
}
continue;
case state_terminated: // (e)
// already put into terminated state as the default value
continue;
}
} //~ "for" iterating over threads
} //~ "for" iterating over threads
// (d2) Now check if a "hole" happens: if all other threads are terminated
// the next thread to start, e.g. the one with the least arrival_time,
// has start time greater than the current process elapsed time, then
// pass from state_future to state_terminated:
if (result == state_future &&
next_thread_starts_at > static_cast<int>(get_elapsed_time()))
return state_terminated;
// (d2) Now check if a "hole" happens: if all other threads are terminated
// the next thread to start, e.g. the one with the least arrival_time,
// has start time greater than the current process elapsed time, then
// pass from state_future to state_terminated:
if (result == state_future && next_thread_starts_at > static_cast<int> (get_elapsed_time ()))
return state_terminated;
return result;
return result;
}
void
DynamicProcess::serialize(SerializeVisitor& translator) const
DynamicProcess::serialize (SerializeVisitor &translator) const
{
translator.from_process(*this);
translator.from_process (*this);
}
StaticProcess&
DynamicProcess::get_core()
StaticProcess &
DynamicProcess::get_core ()
{
return *_core;
return *_core;
}
const StaticProcess&
DynamicProcess::get_core() const
const StaticProcess &
DynamicProcess::get_core () const
{
return *_core;
return *_core;
}
std::vector<DynamicThread*>&
DynamicProcess::get_dynamic_threads()
std::vector<DynamicThread *> &
DynamicProcess::get_dynamic_threads ()
{
return _dynamic_threads;
return _dynamic_threads;
}
unsigned int
DynamicProcess::get_elapsed_time() const
DynamicProcess::get_elapsed_time () const
{
unsigned int result = 0;
for (Iseq<ConstThreadIt> seq = iseq(_dynamic_threads); seq; ++seq)
{
result += (*seq)->get_elapsed_time();
}
return result;
unsigned int result = 0;
for (Iseq<ConstThreadIt> seq = iseq (_dynamic_threads); seq; ++seq)
{
result += (*seq)->get_elapsed_time ();
}
return result;
}
int
DynamicProcess::get_last_acquisition() const
DynamicProcess::get_last_acquisition () const
{
int result = -1;
for (Iseq<ConstThreadIt> seq = iseq(_dynamic_threads); seq; ++seq)
{
int acq = (*seq)->get_last_acquisition();
if (result < acq)
result = acq;
}
return result;
int result = -1;
for (Iseq<ConstThreadIt> seq = iseq (_dynamic_threads); seq; ++seq)
{
int acq = (*seq)->get_last_acquisition ();
if (result < acq)
result = acq;
}
return result;
}
int
DynamicProcess::get_last_release() const
DynamicProcess::get_last_release () const
{
int result = -1;
for (Iseq<ConstThreadIt> seq = iseq(_dynamic_threads); seq; ++seq)
{
int acq = (*seq)->get_last_release();
if (result < acq)
result = acq;
}
return result;
int result = -1;
for (Iseq<ConstThreadIt> seq = iseq (_dynamic_threads); seq; ++seq)
{
int acq = (*seq)->get_last_release ();
if (result < acq)
result = acq;
}
return result;
}

View File

@ -24,9 +24,9 @@
#include "gettext.h"
#include <sgpemv2/process.hh>
#include "dynamic_schedulable.hh"
#include "static_process.hh"
#include <sgpemv2/process.hh>
#include <glibmm/ustring.h>
@ -35,40 +35,40 @@
namespace sgpem
{
class DynamicProcess;
class StaticProcess;
class DynamicThread;
class Thread;
class DynamicProcess;
class StaticProcess;
class DynamicThread;
class Thread;
class SG_DLLLOCAL DynamicProcess : public DynamicSchedulable, public Process
{
public:
DynamicProcess(StaticProcess* core);
DynamicProcess(const DynamicProcess &other);
virtual ~DynamicProcess();
class SG_DLLLOCAL DynamicProcess : public DynamicSchedulable, public Process
{
public:
DynamicProcess (StaticProcess *core);
DynamicProcess (const DynamicProcess &other);
virtual ~DynamicProcess ();
std::vector<Thread*> get_threads();
std::vector<const Thread*> get_threads() const;
std::vector<Thread *> get_threads ();
std::vector<const Thread *> get_threads () const;
state get_state() const;
state get_state () const;
void serialize(SerializeVisitor& translator) const;
void serialize (SerializeVisitor &translator) const;
int get_last_acquisition() const;
int get_last_release() const;
unsigned int get_elapsed_time() const;
int get_last_acquisition () const;
int get_last_release () const;
unsigned int get_elapsed_time () const;
virtual StaticProcess& get_core();
virtual const StaticProcess& get_core() 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();
std::vector<DynamicThread *> &get_dynamic_threads ();
private:
private:
std::shared_ptr<StaticProcess> _core;
std::vector<DynamicThread*> _dynamic_threads;
};
std::vector<DynamicThread *> _dynamic_threads;
};
}
} // namespace sgpem
#endif

View File

@ -19,152 +19,150 @@
#include "dynamic_request.hh"
#include "static_request.hh"
#include "dynamic_sub_request.hh"
#include "dynamic_thread.hh"
#include "static_request.hh"
#include <sgpemv2/serialize_visitor.hh>
#include <sgpemv2/templates/down_cast.tcc>
#include <algorithm>
#include <functional>
#include <cassert>
#include <functional>
using namespace sgpem;
using namespace std;
DynamicRequest::DynamicRequest(StaticRequest *core,
DynamicThread* owner) :
_static_request(core), _dynamic_thread(owner)
DynamicRequest::DynamicRequest (StaticRequest *core, DynamicThread *owner)
: _static_request (core), _dynamic_thread (owner)
{
assert(core != nullptr);
assert(owner != nullptr);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicRequest*>& siblings = owner->get_dynamic_requests();
siblings.push_back(this);
assert (core != nullptr);
assert (owner != nullptr);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicRequest *> &siblings = owner->get_dynamic_requests ();
siblings.push_back (this);
}
DynamicRequest::DynamicRequest(const DynamicRequest& other, DynamicThread* owner) :
_static_request(other._static_request), _dynamic_thread(owner)
DynamicRequest::DynamicRequest (const DynamicRequest &other, DynamicThread *owner)
: _static_request (other._static_request), _dynamic_thread (owner)
{
typedef vector<DynamicSubRequest*> SubReqVec;
typedef vector<DynamicSubRequest *> SubReqVec;
assert(owner != nullptr);
assert (owner != nullptr);
const SubReqVec& other_subs = other._dynamic_subrequests;
const SubReqVec &other_subs = other._dynamic_subrequests;
// Not sure of this, but the constructor of DynamicSubRequest should take care
// of adding itself to the vector of sub requests. This is only my opinion,
// but I think this is a complicated way of doing things...
for (SubReqVec::const_iterator it = other_subs.begin(); it != other_subs.end(); ++it)
new DynamicSubRequest(*(*it), this);
// Not sure of this, but the constructor of DynamicSubRequest should take care
// of adding itself to the vector of sub requests. This is only my opinion,
// but I think this is a complicated way of doing things...
for (SubReqVec::const_iterator it = other_subs.begin (); it != other_subs.end (); ++it)
new DynamicSubRequest (*(*it), this);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicRequest*>& siblings = owner->get_dynamic_requests();
siblings.push_back(this);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicRequest *> &siblings = owner->get_dynamic_requests ();
siblings.push_back (this);
}
DynamicRequest::~DynamicRequest()
DynamicRequest::~DynamicRequest ()
{
for_each(_dynamic_subrequests.begin(), _dynamic_subrequests.end(),
[] (auto *p) { delete p; });
for_each (_dynamic_subrequests.begin (), _dynamic_subrequests.end (), [](auto *p) { delete p; });
}
bool
DynamicRequest::operator==(const Request& op2) const
DynamicRequest::operator== (const Request &op2) const
{
return _static_request == down_cast<const DynamicRequest&>(op2)._static_request;
return _static_request == down_cast<const DynamicRequest &> (op2)._static_request;
}
vector<SubRequest*>
DynamicRequest::get_subrequests()
vector<SubRequest *>
DynamicRequest::get_subrequests ()
{
return std::vector<SubRequest*>(_dynamic_subrequests.begin(), _dynamic_subrequests.end());
return std::vector<SubRequest *> (_dynamic_subrequests.begin (), _dynamic_subrequests.end ());
}
vector<DynamicSubRequest*>&
DynamicRequest::get_dynamic_subrequests()
vector<DynamicSubRequest *> &
DynamicRequest::get_dynamic_subrequests ()
{
return _dynamic_subrequests;
return _dynamic_subrequests;
}
DynamicThread&
DynamicRequest::get_thread()
DynamicThread &
DynamicRequest::get_thread ()
{
return *_dynamic_thread;
return *_dynamic_thread;
}
unsigned int
DynamicRequest::get_instant() const
DynamicRequest::get_instant () const
{
return _static_request->get_instant();
return _static_request->get_instant ();
}
Request::state
DynamicRequest::get_state() const
DynamicRequest::get_state () const
{
typedef std::vector<DynamicSubRequest*> SubReqs;
typedef std::vector<DynamicSubRequest *> SubReqs;
state result = state_future;
state result = state_future;
#ifndef NDEBUG
// Only for debug:
bool at_least_once = false;
// Only for debug:
bool at_least_once = false;
#endif // ~NDEBUG
const SubReqs& sreqs = _dynamic_subrequests;
for (SubReqs::const_iterator it = sreqs.begin(); it != sreqs.end(); it++)
{
SubRequest& cur = **it;
switch (cur.get_state())
const SubReqs &sreqs = _dynamic_subrequests;
for (SubReqs::const_iterator it = sreqs.begin (); it != sreqs.end (); it++)
{
case state_allocated:
return state_allocated;
case state_unallocable:
return state_unallocable;
default:
SubRequest &cur = **it;
switch (cur.get_state ())
{
case state_allocated:
return state_allocated;
case state_unallocable:
return state_unallocable;
default:
#ifndef NDEBUG
// We want to be sure that all subrequests
// have the same state since state_allocable,
// state_terminated and state_future are mutually
// exclusive
if (at_least_once)
assert(result == cur.get_state());
at_least_once = true;
// We want to be sure that all subrequests
// have the same state since state_allocable,
// state_terminated and state_future are mutually
// exclusive
if (at_least_once)
assert (result == cur.get_state ());
at_least_once = true;
#endif //~ NDEBUG
result = cur.get_state();
result = cur.get_state ();
}
}
}
return result;
return result;
}
void
DynamicRequest::serialize(SerializeVisitor& translator) const
DynamicRequest::serialize (SerializeVisitor &translator) const
{
translator.from_request(*this);
translator.from_request (*this);
}
StaticRequest&
DynamicRequest::get_core()
StaticRequest &
DynamicRequest::get_core ()
{
return *_static_request;
return *_static_request;
}
const StaticRequest&
DynamicRequest::get_core() const
const StaticRequest &
DynamicRequest::get_core () const
{
return *_static_request;
return *_static_request;
}

View File

@ -23,14 +23,14 @@
namespace sgpem
{
class DynamicRequest;
class SerializeVisitor;
class SubRequest;
class DynamicSubRequest;
}
class DynamicRequest;
class SerializeVisitor;
class SubRequest;
class DynamicSubRequest;
} // namespace sgpem
#include "static_request.hh"
#include "dynamic_thread.hh"
#include "static_request.hh"
#include <sgpemv2/request.hh>
@ -39,46 +39,45 @@ namespace sgpem
namespace sgpem
{
/** \brief A "dynamic" request, which represents the state
/** \brief A "dynamic" request, which represents the state
* of a request at a particular temporal instant
*/
class SG_DLLLOCAL DynamicRequest : public Request
{
public:
DynamicRequest(StaticRequest *core, DynamicThread* owner);
DynamicRequest(const DynamicRequest& other, DynamicThread* owner);
~DynamicRequest();
class SG_DLLLOCAL DynamicRequest : public Request
{
public:
DynamicRequest (StaticRequest *core, DynamicThread *owner);
DynamicRequest (const DynamicRequest &other, DynamicThread *owner);
~DynamicRequest ();
virtual bool operator==(const Request& op2) const;
virtual bool operator== (const Request &op2) const;
virtual std::vector<SubRequest*> get_subrequests();
virtual std::vector<SubRequest *> get_subrequests ();
DynamicThread& get_thread();
DynamicThread &get_thread ();
unsigned int get_instant() const;
unsigned int get_instant () const;
state get_state() const;
state get_state () const;
void serialize(SerializeVisitor& translator) const;
void serialize (SerializeVisitor &translator) const;
StaticRequest& get_core();
const StaticRequest& get_core() const;
StaticRequest &get_core ();
const StaticRequest &get_core () const;
/// \internal 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();
std::vector<DynamicSubRequest *> &get_dynamic_subrequests ();
private:
private:
// Undefined
DynamicRequest(const DynamicRequest& other);
DynamicRequest (const DynamicRequest &other);
std::shared_ptr<StaticRequest> _static_request;
DynamicThread* _dynamic_thread;
std::vector<DynamicSubRequest*> _dynamic_subrequests;
};
DynamicThread *_dynamic_thread;
std::vector<DynamicSubRequest *> _dynamic_subrequests;
};
}
} // namespace sgpem
#endif

View File

@ -29,44 +29,44 @@
using namespace sgpem;
DynamicResource::DynamicResource(StaticResource *core) :
_static_resource(core)
{}
DynamicResource::DynamicResource (StaticResource *core) : _static_resource (core)
{
}
bool
DynamicResource::operator==(const Resource& op2) const
DynamicResource::operator== (const Resource &op2) const
{
return _static_resource == down_cast<const DynamicResource&>(op2)._static_resource;
return _static_resource == down_cast<const DynamicResource &> (op2)._static_resource;
}
Glib::ustring
DynamicResource::get_name() const
DynamicResource::get_name () const
{
return _static_resource->get_name();
return _static_resource->get_name ();
}
unsigned int
DynamicResource::get_places() const
DynamicResource::get_places () const
{
return _static_resource->get_places();
return _static_resource->get_places ();
}
void
DynamicResource::serialize(SerializeVisitor& translator) const
DynamicResource::serialize (SerializeVisitor &translator) const
{
translator.from_resource(*this);
translator.from_resource (*this);
}
StaticResource&
DynamicResource::get_core()
StaticResource &
DynamicResource::get_core ()
{
return *_static_resource;
return *_static_resource;
}
const StaticResource&
DynamicResource::get_core() const
const StaticResource &
DynamicResource::get_core () const
{
return *_static_resource;
return *_static_resource;
}

View File

@ -23,76 +23,73 @@
#include "glibmm/ustring.h"
#include <sgpemv2/resource.hh>
#include "static_resource.hh"
#include <sgpemv2/resource.hh>
#include <memory>
namespace sgpem
{
/// \brief Desribes the state of a resource entity in a particular moment
/// of the simulation.
///
/// Contains part of the information used by the scheduling policies to
/// perform scheduling.
/// DynamicResource objects may be created by the system
/// via the Scheduler.step_forward() method (which then inserts them into a
/// ::ConcreteEnvironment), or by the user on a resetted ::History by creating
/// one of them anew.
///
/// Actually this class does not provide any information to the system, nor it
/// does play any particular role. It is here for the puropose of extensibility
/// and beauty in general.
///
/// These objects may be destroyed only by resetting an ::History, or via one
/// of its methods.
class DynamicResource;
class SerializeVisitor;
class SG_DLLLOCAL DynamicResource : public Resource
{
public:
DynamicResource (StaticResource *core);
/// \brief Desribes the state of a resource entity in a particular moment
/// of the simulation.
///
/// Contains part of the information used by the scheduling policies to
/// perform scheduling.
/// DynamicResource objects may be created by the system
/// via the Scheduler.step_forward() method (which then inserts them into a
/// ::ConcreteEnvironment), or by the user on a resetted ::History by creating
/// one of them anew.
///
/// Actually this class does not provide any information to the system, nor it
/// does play any particular role. It is here for the puropose of extensibility
/// and beauty in general.
///
/// These objects may be destroyed only by resetting an ::History, or via one
/// of its methods.
class DynamicResource;
class SerializeVisitor;
class SG_DLLLOCAL DynamicResource : public Resource
{
public:
DynamicResource(StaticResource *core);
virtual bool operator==(const Resource& op2) const;
virtual bool operator== (const Resource &op2) const;
/// \brief Returns the name of the Resource.
///
/// Returns the name of the Resource.
/// \return the name of the Resource.
Glib::ustring get_name() const;
Glib::ustring get_name () const;
/// \brief Returns the number of places of the Resource.
///
/// Returns the number of places of the Resource.
/// \return the number of places of the Resource.
unsigned int get_places() const;
unsigned int get_places () const;
/// \brief Serializes this object via the provided translator.
///
/// Calls translator->from_resource(this).
void serialize(SerializeVisitor& translator) const;
void serialize (SerializeVisitor &translator) const;
/// \brief Returns a reference to the static resource object.
///
/// This function returns a reference to the actual schedable object
/// represented, along with its status, by this instance.
StaticResource& get_core();
StaticResource &get_core ();
/// \brief Returns a constant reference to the static schedulable object.
///
/// This function returns a constant reference to the actual schedable object
/// represented, along with its status, by this instance.
const StaticResource& get_core() const;
const StaticResource &get_core () const;
private:
private:
std::shared_ptr<StaticResource> _static_resource;
};
};
}
} // namespace sgpem
#endif

View File

@ -27,56 +27,56 @@
using namespace sgpem;
using namespace std;
DynamicSchedulable::DynamicSchedulable()
: _priority_push(0)
{}
DynamicSchedulable::DynamicSchedulable () : _priority_push (0)
{
}
bool
DynamicSchedulable::operator==(const Schedulable& op2) const
DynamicSchedulable::operator== (const Schedulable &op2) const
{
return &get_core() == &(down_cast<const DynamicSchedulable&>(op2).get_core());
return &get_core () == &(down_cast<const DynamicSchedulable &> (op2).get_core ());
}
Glib::ustring
DynamicSchedulable::get_name() const
DynamicSchedulable::get_name () const
{
return get_core().get_name();
return get_core ().get_name ();
}
unsigned int
DynamicSchedulable::get_arrival_time() const
DynamicSchedulable::get_arrival_time () const
{
return get_core().get_arrival_time();
return get_core ().get_arrival_time ();
}
int
DynamicSchedulable::get_base_priority() const
DynamicSchedulable::get_base_priority () const
{
return get_core().get_priority();
return get_core ().get_priority ();
}
unsigned int
DynamicSchedulable::get_total_cpu_time() const
DynamicSchedulable::get_total_cpu_time () const
{
return get_core().get_total_cpu_time();
return get_core ().get_total_cpu_time ();
}
int
DynamicSchedulable::set_priority_push(int new_value)
DynamicSchedulable::set_priority_push (int new_value)
{
int old_priority_push = _priority_push;
_priority_push = new_value;
return old_priority_push;
int old_priority_push = _priority_push;
_priority_push = new_value;
return old_priority_push;
}
int
DynamicSchedulable::get_priority_push() const
DynamicSchedulable::get_priority_push () const
{
return _priority_push;
return _priority_push;
}
int
DynamicSchedulable::get_current_priority() const
DynamicSchedulable::get_current_priority () const
{
return get_base_priority() + get_priority_push();
return get_base_priority () + get_priority_push ();
}

View File

@ -22,31 +22,30 @@
#define DYNAMIC_SCHEDULABLE_HH 1
#include <sgpemv2/schedulable.hh>
#include "static_schedulable.hh"
#include <sgpemv2/schedulable.hh>
namespace sgpem
{
/// \brief Desribes the state of a schedulable entity in a particular moment
/// of the simulation.
///
/// Contains part of the information used by the scheduling policies to
/// perform scheduling.
/// Objects of subclasses of ::DynamicSchedulable may be created by the system
/// via the Scheduler.step_forward() method (which then inserts them into a
/// ::ConcreteEnvironment), or by the user on a resetted ::History by creating
/// one of them anew.
///
/// These objects may be destroyed only by resetting an ::History, or via one
/// of its methods.
class DynamicSchedulable;
/// \brief Desribes the state of a schedulable entity in a particular moment
/// of the simulation.
///
/// Contains part of the information used by the scheduling policies to
/// perform scheduling.
/// Objects of subclasses of ::DynamicSchedulable may be created by the system
/// via the Scheduler.step_forward() method (which then inserts them into a
/// ::ConcreteEnvironment), or by the user on a resetted ::History by creating
/// one of them anew.
///
/// These objects may be destroyed only by resetting an ::History, or via one
/// of its methods.
class DynamicSchedulable;
class SG_DLLLOCAL DynamicSchedulable : public virtual Schedulable
{
public:
class SG_DLLLOCAL DynamicSchedulable : public virtual Schedulable
{
public:
/** \brief Object constructor */
DynamicSchedulable();
DynamicSchedulable ();
//DynamicSchedulable(const DynamicSchedulable& obj); //copy constructor
@ -56,14 +55,14 @@ namespace sgpem
* actual represented process is the same, and if the status is also the
* same.
*/
virtual bool operator==(const Schedulable&) const;
virtual bool operator== (const Schedulable &) const;
/// \brief Returns the name of the Schedulable.
///
/// Returns the name of the Schedulable.
/// It is fetched from the associated ::StaticSchedulable object.
/// \return the name of the Schedulable.
virtual Glib::ustring get_name() const;
virtual Glib::ustring get_name () const;
/// \brief Returns the arrival time of the Schedulable.
///
@ -75,7 +74,7 @@ namespace sgpem
/// The arrival time is a static (respect to the simulation) property.
/// It is fetched from the associated ::StaticSchedulable object.
/// \return the arrival time of the Schedulable.
virtual unsigned int get_arrival_time() const;
virtual unsigned int get_arrival_time () const;
/// \brief Returns the base priority of the Schedulable.
///
@ -90,7 +89,7 @@ namespace sgpem
/// The base priority is a static (respect to the simulation) property.
/// It is fetched from the associated ::StaticSchedulable object.
/// \return the base priority of the Schedulable.
virtual int get_base_priority() const;
virtual int get_base_priority () const;
/// \brief Returns the total required CPU time of the Schedulable.
///
@ -104,7 +103,7 @@ namespace sgpem
/// The total required CPU time is a static (respect to the simulation) property.
/// It is fetched from the associated ::StaticSchedulable object.
/// \return the total required CPU time of the Schedulable.
virtual unsigned int get_total_cpu_time() const;
virtual unsigned int get_total_cpu_time () const;
/// \brief Returns the current priority push of the Schedulable.
///
@ -118,7 +117,7 @@ namespace sgpem
///
/// The priority push is a dynamic (respect to the simulation) property.
/// \return the current priority push of the Schedulable.
virtual int get_priority_push() const;
virtual int get_priority_push () const;
/// \brief Sets the priority push of the Schedulable, returning the old one.
///
@ -133,7 +132,7 @@ namespace sgpem
/// The priority push is a dynamic (respect to the simulation) property.
/// \param new_value the new push to be set.
/// \return the old priority push of the Schedulable.
virtual int set_priority_push(int new_value = 0);
virtual int set_priority_push (int new_value = 0);
/// \brief Returns the current priority of the Schedulable.
///
@ -147,7 +146,7 @@ namespace sgpem
///
/// The current priority is a dynamic (respect to the simulation) property.
/// \return the dynamic priority of the Schedulable.
virtual int get_current_priority() const;
virtual int get_current_priority () const;
/// \brief Returns the elapsed time of the Schedulable.
///
@ -157,23 +156,23 @@ namespace sgpem
///
/// The elapsed time is a dynamic (respect to the simulation) property.
/// \return the elapsed time of the Schedulable.
virtual unsigned int get_elapsed_time() const = 0;
virtual unsigned int get_elapsed_time () const = 0;
/// \brief Returns a reference to the static schedulable object.
///
/// This function returns a reference to the actual schedable object.
/// represented, along with its status, by this instance.
virtual StaticSchedulable& get_core() = 0;
virtual StaticSchedulable &get_core () = 0;
/// \brief Returns a constant reference to the static schedulable object.
///
/// This function returns a constant reference to the actual schedable object.
/// represented, along with its status, by this instance.
virtual const StaticSchedulable& get_core() const = 0;
virtual const StaticSchedulable &get_core () const = 0;
private:
private:
int _priority_push;
};
}
};
} // namespace sgpem
#endif

View File

@ -30,129 +30,128 @@
using namespace sgpem;
DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core,
DynamicRequest* owner) :
_static_subrequest(core), _owner(owner),
_queue_position(-1), _ran_for(0), _state(Request::state_future)
DynamicSubRequest::DynamicSubRequest (StaticSubRequest *core, DynamicRequest *owner)
: _static_subrequest (core), _owner (owner), _queue_position (-1), _ran_for (0), _state (Request::state_future)
{
assert(core != nullptr);
assert(owner != nullptr);
assert (core != nullptr);
assert (owner != nullptr);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicSubRequest*>& siblings = owner->get_dynamic_subrequests();
siblings.push_back(this);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicSubRequest *> &siblings = owner->get_dynamic_subrequests ();
siblings.push_back (this);
}
DynamicSubRequest::DynamicSubRequest(const DynamicSubRequest& other,
DynamicRequest* owner) :
_static_subrequest(other._static_subrequest), _owner(owner),
_queue_position(other._queue_position), _ran_for(other._ran_for),
_state(other._state)
DynamicSubRequest::DynamicSubRequest (const DynamicSubRequest &other, DynamicRequest *owner)
: _static_subrequest (other._static_subrequest),
_owner (owner),
_queue_position (other._queue_position),
_ran_for (other._ran_for),
_state (other._state)
{
assert(owner != nullptr);
assert (owner != nullptr);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicSubRequest*>& siblings = owner->get_dynamic_subrequests();
siblings.push_back(this);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicSubRequest *> &siblings = owner->get_dynamic_subrequests ();
siblings.push_back (this);
}
DynamicSubRequest::~DynamicSubRequest()
{}
DynamicSubRequest::~DynamicSubRequest ()
{
}
bool
DynamicSubRequest::operator==(const SubRequest& op2) const
DynamicSubRequest::operator== (const SubRequest &op2) const
{
return _static_subrequest ==
down_cast<const DynamicSubRequest&>(op2)._static_subrequest;
return _static_subrequest == down_cast<const DynamicSubRequest &> (op2)._static_subrequest;
}
SubRequest::resource_key_t
DynamicSubRequest::get_resource_key() const
DynamicSubRequest::get_resource_key () const
{
return _static_subrequest->get_resource_key();
return _static_subrequest->get_resource_key ();
}
unsigned int
DynamicSubRequest::get_length() const
DynamicSubRequest::get_length () const
{
return _static_subrequest->get_length();
return _static_subrequest->get_length ();
}
int
DynamicSubRequest::get_queue_position() const
DynamicSubRequest::get_queue_position () const
{
return _queue_position;
return _queue_position;
}
void
DynamicSubRequest::set_queue_position(int position)
DynamicSubRequest::set_queue_position (int position)
{
_queue_position = position;
_queue_position = position;
}
DynamicRequest&
DynamicSubRequest::get_request()
DynamicRequest &
DynamicSubRequest::get_request ()
{
return *_owner;
return *_owner;
}
DynamicSubRequest::state
DynamicSubRequest::get_state() const
DynamicSubRequest::get_state () const
{
return _state;
return _state;
}
DynamicSubRequest::state
DynamicSubRequest::set_state(state new_state)
DynamicSubRequest::set_state (state new_state)
{
state temp = _state;
_state = new_state;
return temp;
state temp = _state;
_state = new_state;
return temp;
}
unsigned int
DynamicSubRequest::get_remaining_time() const
DynamicSubRequest::get_remaining_time () const
{
return _static_subrequest->get_length() - _ran_for;
return _static_subrequest->get_length () - _ran_for;
}
unsigned int
DynamicSubRequest::decrease_remaining_time()
DynamicSubRequest::decrease_remaining_time ()
{
assert(_state == Request::state_allocated);
assert (_state == Request::state_allocated);
unsigned int temp = get_remaining_time();
if (temp > 0)
_ran_for++;
unsigned int temp = get_remaining_time ();
if (temp > 0)
_ran_for++;
return temp;
return temp;
}
void
DynamicSubRequest::serialize(SerializeVisitor& translator) const
DynamicSubRequest::serialize (SerializeVisitor &translator) const
{
translator.from_subrequest(*this);
translator.from_subrequest (*this);
}
StaticSubRequest&
DynamicSubRequest::get_core()
StaticSubRequest &
DynamicSubRequest::get_core ()
{
return *_static_subrequest;
return *_static_subrequest;
}
const StaticSubRequest&
DynamicSubRequest::get_core() const
const StaticSubRequest &
DynamicSubRequest::get_core () const
{
return *_static_subrequest;
return *_static_subrequest;
}

View File

@ -23,11 +23,11 @@
namespace sgpem
{
class DynamicSubRequest;
class SerializeVisitor;
class Resource;
class StaticSubRequest;
}
class DynamicSubRequest;
class SerializeVisitor;
class Resource;
class StaticSubRequest;
} // namespace sgpem
#include "dynamic_request.hh"
#include "dynamic_resource.hh"
@ -40,74 +40,74 @@ namespace sgpem
namespace sgpem
{
/** \brief Represents the dynamic status of a subrequest
/** \brief Represents the dynamic status of a subrequest
*/
class SG_DLLLOCAL DynamicSubRequest : public SubRequest
{
public:
class SG_DLLLOCAL DynamicSubRequest : public SubRequest
{
public:
/** \brief Constructor
*
* Only ::History knows how to use this :-).
*/
DynamicSubRequest(StaticSubRequest* core, DynamicRequest* owner);
DynamicSubRequest (StaticSubRequest *core, DynamicRequest *owner);
/** \brief "Special" copy constructor, which copies everything except owner
* \param owner The owner of the new DynamicSubRequest
*/
DynamicSubRequest(const DynamicSubRequest& other, DynamicRequest* owner);
DynamicSubRequest (const DynamicSubRequest &other, DynamicRequest *owner);
virtual ~DynamicSubRequest();
virtual ~DynamicSubRequest ();
/** \brief Tells if this object equals another of the same type
*
* \return true If they own a reference to the same Static object
* \return false Otherwise
*/
virtual bool operator==(const SubRequest& op2) const;
virtual bool operator== (const SubRequest &op2) const;
/** \brief Returns the key to the DynamicResource that was requested
*
* The correct ::Resource object can be obtained via
* Environment.get_resources(), using the returned value as a key
*/
resource_key_t get_resource_key() const;
resource_key_t get_resource_key () const;
/** \brief Returns the time the resource is needed
*
* This time is meant relative to a process executed time.
*/
unsigned int get_length() const;
unsigned int get_length () const;
int get_queue_position() const;
void set_queue_position(int position);
int get_queue_position () const;
void set_queue_position (int position);
virtual DynamicRequest& get_request();
virtual DynamicRequest &get_request ();
state get_state() const;
state set_state(state new_state);
state get_state () const;
state set_state (state new_state);
unsigned int get_remaining_time() const;
unsigned int get_remaining_time () const;
/** \brief Decreases remaining time by 1
*/
unsigned int decrease_remaining_time();
unsigned int decrease_remaining_time ();
void serialize(SerializeVisitor& translator) const;
void serialize (SerializeVisitor &translator) const;
StaticSubRequest& get_core();
const StaticSubRequest& get_core() const;
StaticSubRequest &get_core ();
const StaticSubRequest &get_core () const;
private:
private:
// Undefined
DynamicSubRequest(const DynamicSubRequest&);
DynamicSubRequest (const DynamicSubRequest &);
std::shared_ptr<StaticSubRequest> _static_subrequest;
DynamicRequest* _owner;
int _queue_position;
unsigned int _ran_for;
state _state;
};
DynamicRequest *_owner;
int _queue_position;
unsigned int _ran_for;
state _state;
};
}
} // namespace sgpem
#endif

View File

@ -19,146 +19,148 @@
#include "dynamic_thread.hh"
#include "static_thread.hh"
#include "dynamic_request.hh"
#include "static_thread.hh"
#include <sgpemv2/serialize_visitor.hh>
#include <algorithm>
#include <functional>
#include <cassert>
#include <functional>
using namespace sgpem;
DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent)
: DynamicSchedulable(), _core(core), _state(state_future), _parent(parent),
_ran_for(0), _last_acquisition(-1), _last_release(-1)
DynamicThread::DynamicThread (StaticThread *core, DynamicProcess *parent)
: DynamicSchedulable (), _core (core), _state (state_future), _parent (parent), _ran_for (0), _last_acquisition (-1), _last_release (-1)
{
assert(core != nullptr);
assert(parent != nullptr);
assert (core != nullptr);
assert (parent != nullptr);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicThread*>& siblings = parent->get_dynamic_threads();
siblings.push_back(this);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicThread *> &siblings = parent->get_dynamic_threads ();
siblings.push_back (this);
}
DynamicThread::DynamicThread(const DynamicThread &other, DynamicProcess* parent) :
Schedulable(), DynamicSchedulable(other), Thread(),
_core(other._core), _state(other._state), _parent(parent),
_ran_for(other._ran_for), _last_acquisition(other._last_acquisition),
_last_release(other._last_release)
DynamicThread::DynamicThread (const DynamicThread &other, DynamicProcess *parent)
: Schedulable (),
DynamicSchedulable (other),
Thread (),
_core (other._core),
_state (other._state),
_parent (parent),
_ran_for (other._ran_for),
_last_acquisition (other._last_acquisition),
_last_release (other._last_release)
{
typedef std::vector<DynamicRequest*>::const_iterator ReqIt;
typedef std::vector<DynamicRequest *>::const_iterator ReqIt;
assert(parent != nullptr);
assert (parent != nullptr);
const std::vector<DynamicRequest*>& other_req = other._dynamic_requests;
const std::vector<DynamicRequest *> &other_req = other._dynamic_requests;
for (ReqIt it = other_req.begin(); it != other_req.end(); ++it)
new DynamicRequest(*(*it), this);
for (ReqIt it = other_req.begin (); it != other_req.end (); ++it)
new DynamicRequest (*(*it), this);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicThread*>& siblings = parent->get_dynamic_threads();
siblings.push_back(this);
// Leave this line: it helps us with a compiler warning if
// the get_dynamic* method signature changes:
std::vector<DynamicThread *> &siblings = parent->get_dynamic_threads ();
siblings.push_back (this);
}
DynamicThread::~DynamicThread()
DynamicThread::~DynamicThread ()
{
for_each(_dynamic_requests.begin(), _dynamic_requests.end(),
[] (auto *p) { delete p; });
for_each (_dynamic_requests.begin (), _dynamic_requests.end (), [](auto *p) { delete p; });
}
DynamicProcess&
DynamicThread::get_process()
DynamicProcess &
DynamicThread::get_process ()
{
return *_parent;
return *_parent;
}
Schedulable::state
DynamicThread::get_state() const
DynamicThread::get_state () const
{
return _state;
return _state;
}
Schedulable::state
DynamicThread::set_state(state new_state)
DynamicThread::set_state (state new_state)
{
state old_state = _state;
_state = new_state;
state old_state = _state;
_state = new_state;
return old_state;
return old_state;
}
std::vector<Request*>
DynamicThread::get_requests()
std::vector<Request *>
DynamicThread::get_requests ()
{
return std::vector<Request*>(_dynamic_requests.begin(), _dynamic_requests.end());
return std::vector<Request *> (_dynamic_requests.begin (), _dynamic_requests.end ());
}
void
DynamicThread::serialize(SerializeVisitor& translator) const
DynamicThread::serialize (SerializeVisitor &translator) const
{
translator.from_thread(*this);
translator.from_thread (*this);
}
StaticThread&
DynamicThread::get_core()
StaticThread &
DynamicThread::get_core ()
{
return *_core;
return *_core;
}
const StaticThread&
DynamicThread::get_core() const
const StaticThread &
DynamicThread::get_core () const
{
return *_core;
return *_core;
}
std::vector<DynamicRequest*>&
DynamicThread::get_dynamic_requests()
std::vector<DynamicRequest *> &
DynamicThread::get_dynamic_requests ()
{
return _dynamic_requests;
return _dynamic_requests;
}
unsigned int
DynamicThread::get_elapsed_time() const
DynamicThread::get_elapsed_time () const
{
return _ran_for;
return _ran_for;
}
void
DynamicThread::decrease_remaining_time()
DynamicThread::decrease_remaining_time ()
{
// strict check for us to better debug scheduler
assert(_ran_for < get_total_cpu_time());
if (_ran_for < get_total_cpu_time())
_ran_for++;
// strict check for us to better debug scheduler
assert (_ran_for < get_total_cpu_time ());
if (_ran_for < get_total_cpu_time ())
_ran_for++;
}
int
DynamicThread::get_last_acquisition() const
DynamicThread::get_last_acquisition () const
{
return _last_acquisition;
return _last_acquisition;
}
void
DynamicThread::set_last_acquisition(int instant)
DynamicThread::set_last_acquisition (int instant)
{
_last_acquisition = instant;
_last_acquisition = instant;
}
int
DynamicThread::get_last_release() const
DynamicThread::get_last_release () const
{
return _last_release;
return _last_release;
}
void
DynamicThread::set_last_release(int instant)
DynamicThread::set_last_release (int instant)
{
_last_release = instant;
_last_release = instant;
}

View File

@ -26,60 +26,60 @@
#include "glibmm/ustring.h"
#include <vector>
#include <sgpemv2/thread.hh>
#include "dynamic_process.hh"
#include "dynamic_schedulable.hh"
#include <sgpemv2/thread.hh>
#include <memory>
namespace sgpem
{
class DynamicThread;
class DynamicProcess;
class StaticThread;
class Request;
class DynamicRequest;
class DynamicThread;
class DynamicProcess;
class StaticThread;
class Request;
class DynamicRequest;
class SG_DLLLOCAL DynamicThread : public DynamicSchedulable, public Thread
{
public:
class SG_DLLLOCAL DynamicThread : public DynamicSchedulable, public Thread
{
public:
/**
\brief Constructor.
\param core The static counterpart to this object.
\param parent The parent process that spawned this thread.
*/
DynamicThread(StaticThread* core, DynamicProcess* parent);
DynamicThread (StaticThread *core, DynamicProcess *parent);
/**
\brief Copy constructor.
\param other The dynamic thread to clone.
\param parent The parent process that spawned this thread.
*/
DynamicThread(const DynamicThread &other, DynamicProcess* parent);
DynamicThread (const DynamicThread &other, DynamicProcess *parent);
/**
\brief Destructor.
*/
virtual ~DynamicThread();
virtual ~DynamicThread ();
/**
\brief Gets the owning process.
\return A reference to the DynamicProcess that owns this thread.
*/
DynamicProcess& get_process();
DynamicProcess &get_process ();
/**
\brief Gets this thread's state.
\return The current Schedulable::state of this object.
*/
state get_state() const;
state get_state () const;
/**
\brief Sets/gets this thread's state.
\param new_state The desired Schedulable::state of this object.
\return The previous state.
*/
state set_state(state new_state);
state set_state (state new_state);
/**
\brief Gets the last istant this schedulable has
@ -87,7 +87,7 @@ namespace sgpem
\return Current value of last_acquisition.
*/
int get_last_acquisition() const;
int get_last_acquisition () const;
/**
\brief Sets/gets the last istant this schedulable
@ -96,7 +96,7 @@ namespace sgpem
\param instant New value for last_acquisition.
\return Previous value of last_acquisition.
*/
void set_last_acquisition(int instant);
void set_last_acquisition (int instant);
/**
\brief Gets the last instant this schedulable has changed its state
@ -104,7 +104,7 @@ namespace sgpem
\return Current value of last_release.
*/
int get_last_release() const;
int get_last_release () const;
/**
\brief Sets/gets the last instant this schedulable has changed
@ -113,38 +113,37 @@ namespace sgpem
\param instant New value for last_release.
\return Previous value of last_release.
*/
void set_last_release(int instant);
void set_last_release (int instant);
/**
\brief Gets total running time of this thread.
\return Current value of _run_for.
*/
unsigned int get_elapsed_time() const;
unsigned int get_elapsed_time () const;
/**
\brief Decreases the schedulable remaining time by one unit.
*/
void decrease_remaining_time();
void decrease_remaining_time ();
/**
\brief Serializes this object via the provided visitor.
Calls translator->from_thread(this).
*/
void serialize(SerializeVisitor& translator) const;
void serialize (SerializeVisitor &translator) const;
/**
\brief Gets a reference to static counterpart of this object.
\return A reference to static counterpart of this object.
*/
virtual StaticThread& get_core();
virtual StaticThread &get_core ();
/**
\brief Gets a const reference to static counterpart of this object.
\return A const reference to static counterpart of this object.
*/
virtual const StaticThread& get_core() const;
virtual const StaticThread &get_core () const;
/**
@ -155,7 +154,7 @@ namespace sgpem
Does also the job of "add_request" and "remove_request"
\return A reference to the DynamicRequests pointers vector.
*/
std::vector<Request*> get_requests();
std::vector<Request *> get_requests ();
/**
\brief Returns ::DynamicRequest pointers this ::Thread did to some ::Resource.
@ -165,14 +164,14 @@ namespace sgpem
Does also the job of "add_request" and "remove_request"
\return A reference to the DynamicRequests pointers vector.
*/
std::vector<DynamicRequest*>& get_dynamic_requests();
std::vector<DynamicRequest *> &get_dynamic_requests ();
private:
private:
/**
\brief Private copy constructor; avoids public construction of
DynamicThread without owning process.
*/
DynamicThread(const DynamicThread &other);
DynamicThread (const DynamicThread &other);
/**
\brief Pointer to static counterpart of this object.
@ -189,12 +188,12 @@ namespace sgpem
/**
\brief Container with this thread's requests.
*/
std::vector<DynamicRequest*> _dynamic_requests;
std::vector<DynamicRequest *> _dynamic_requests;
/**
\brief Pointer to this thread parent.
*/
DynamicProcess* _parent;
DynamicProcess *_parent;
/**
\brief Total running time of this thread
@ -211,9 +210,8 @@ namespace sgpem
from running to something else.
*/
int _last_release;
};
};
}
} // namespace sgpem
#endif

View File

@ -23,6 +23,6 @@
using namespace sgpem;
Environment::~Environment()
{}
Environment::~Environment ()
{
}

View File

@ -23,7 +23,7 @@
#if ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
#include <libintl.h>
#else
@ -34,17 +34,17 @@
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#include <cstdlib>
#if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
#include <libintl.h>
#endif
#endif
/* Disabled NLS.
@ -52,18 +52,16 @@
for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# define gettext(Msgid) ((const char *) (Msgid))
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
# define ngettext(Msgid1, Msgid2, N) \
#define gettext(Msgid) ((const char *) (Msgid))
#define dgettext(Domainname, Msgid) ((const char *) (Msgid))
#define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
#define ngettext(Msgid1, Msgid2, N) ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#define dngettext(Domainname, Msgid1, Msgid2, N) ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
#define textdomain(Domainname) ((const char *) (Domainname))
#define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
#define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
#endif
@ -77,7 +75,7 @@
#define gettext_noop(String) String
/* Commodity macros -- added by Matteo Settenvini 2006-01-13 */
#define _(x) (gettext(x))
#define N_(x) (gettext_noop(x))
#define _(x) (gettext (x))
#define N_(x) (gettext_noop (x))
#endif /* _LIBGETTEXT_H */

View File

@ -34,7 +34,7 @@
#include <sstream>
#ifdef _MSC_VER
#include <shlobj.h>
#include <shlobj.h>
#endif
using namespace sgpem;
@ -42,290 +42,281 @@ using namespace sgpem;
// Explicit template instantiation to allow to export symbols from the DSO.
template class sgpem::Singleton<GlobalPreferences>;
GlobalPreferences::GlobalPreferences()
: _mod_dirs(1, PLUGDIR), _pol_dirs(1, POLDIR), _speed(1000)
{}
GlobalPreferences::GlobalPreferences () : _mod_dirs (1, PLUGDIR), _pol_dirs (1, POLDIR), _speed (1000)
{
}
Glib::ustring
GlobalPreferences::get_preferences_dir() const
GlobalPreferences::get_preferences_dir () const
{
using namespace Glib;
// windows-specific part, i don't use ifdef WIN32 since I'm not sure how
// it will behave on MinGW/Cygwin...
using namespace Glib;
// windows-specific part, i don't use ifdef WIN32 since I'm not sure how
// it will behave on MinGW/Cygwin...
#ifdef _MSC_VER
TCHAR raw_path[MAX_PATH];
TCHAR raw_path[MAX_PATH];
if(SUCCEEDED(SHGetFolderPath(NULL,
CSIDL_APPDATA,
nullptr,
SHGFP_TYPE_CURRENT,
raw_path)))
{
// if UNICODE, characters are 16bit, otherwise plain bytes
# ifdef UNICODE
std::wstring path(raw_path);
# else
std::string path(raw_path);
# endif
if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, raw_path)))
{
// if UNICODE, characters are 16bit, otherwise plain bytes
#ifdef UNICODE
std::wstring path (raw_path);
#else
std::string path (raw_path);
#endif
path += TEXT("\\sgpemv2");
path += TEXT ("\\sgpemv2");
// Create "Application Data\sgpemv2". if not present,
// otherwise it is a no-op
CreateDirectory(path.c_str(), nullptr);
// Create "Application Data\sgpemv2". if not present,
// otherwise it is a no-op
CreateDirectory (path.c_str (), nullptr);
// if UNICODE, we need to convert to utf-8
// I'm not sure if this part is OK, anyway...
# ifdef UNICODE
char raw_path_utf[MAX_PATH];
// if UNICODE, we need to convert to utf-8
// I'm not sure if this part is OK, anyway...
#ifdef UNICODE
char raw_path_utf[MAX_PATH];
WideCharToMultiByte(CP_UTF8, 0, path.c_str(), -1, raw_path_utf, MAX_PATH, nullptr, nullptr);
WideCharToMultiByte (CP_UTF8, 0, path.c_str (), -1, raw_path_utf, MAX_PATH, nullptr, nullptr);
return Glib::ustring(raw_path_utf);
# else
// no UNICODE, simply return plain string
return path;
# endif //~UNICODE
return Glib::ustring (raw_path_utf);
#else
// no UNICODE, simply return plain string
return path;
#endif //~UNICODE
}
else
throw FileError(FileError::FAILED, _("Unable to obtain Application Data directory"));
throw FileError (FileError::FAILED, _ ("Unable to obtain Application Data directory"));
#else
const ustring dir = get_home_dir() + G_DIR_SEPARATOR_S + ".sgpemv2";
if(!file_test(dir, FILE_TEST_IS_DIR))
const ustring dir = get_home_dir () + G_DIR_SEPARATOR_S + ".sgpemv2";
if (!file_test (dir, FILE_TEST_IS_DIR))
{
const int err = g_mkdir(dir.c_str(), 0755);
if(err != 0)
throw FileError(FileError::FAILED, g_strerror(err));
const int err = g_mkdir (dir.c_str (), 0755);
if (err != 0)
throw FileError (FileError::FAILED, g_strerror (err));
}
return dir;
return dir;
#endif //~_MSC_VER
}
Glib::ustring
GlobalPreferences::get_config_filename() const
GlobalPreferences::get_config_filename () const
{
const Glib::ustring filename = get_preferences_dir() + G_DIR_SEPARATOR_S + Glib::ustring("sgpemrc");
return filename;
const Glib::ustring filename = get_preferences_dir () + G_DIR_SEPARATOR_S + Glib::ustring ("sgpemrc");
return filename;
}
GlobalPreferences::DirVector&
GlobalPreferences::get_policy_dirs()
GlobalPreferences::DirVector &
GlobalPreferences::get_policy_dirs ()
{
return _pol_dirs;
return _pol_dirs;
}
GlobalPreferences::DirVector&
GlobalPreferences::get_plugin_dirs()
GlobalPreferences::DirVector &
GlobalPreferences::get_plugin_dirs ()
{
return _mod_dirs;
return _mod_dirs;
}
int
GlobalPreferences::get_speed()
GlobalPreferences::get_speed ()
{
return _speed;
return _speed;
}
int
GlobalPreferences::set_speed(int new_speed)
GlobalPreferences::set_speed (int new_speed)
{
int old_speed = _speed;
_speed = new_speed;
return old_speed;
int old_speed = _speed;
_speed = new_speed;
return old_speed;
}
const Glib::ustring
GlobalPreferences::get_schedulable_color(Schedulable::state st) const
GlobalPreferences::get_schedulable_color (Schedulable::state st) const
{
switch(st)
{
case Schedulable::state_running:
return "ForestGreen";
case Schedulable::state_ready:
return "GoldenRod";
case Schedulable::state_blocked:
return "red";
case Schedulable::state_terminated:
return "DarkSlateGray";
case Schedulable::state_future:
return "Gray";
default:
return "black";
}
switch (st)
{
case Schedulable::state_running:
return "ForestGreen";
case Schedulable::state_ready:
return "GoldenRod";
case Schedulable::state_blocked:
return "red";
case Schedulable::state_terminated:
return "DarkSlateGray";
case Schedulable::state_future:
return "Gray";
default:
return "black";
}
}
const Glib::ustring
GlobalPreferences::get_request_color(Request::state st) const
GlobalPreferences::get_request_color (Request::state st) const
{
switch(st)
{
case Request::state_allocated:
return "ForestGreen";
case Request::state_allocable:
return "GoldenRod";
case Request::state_unallocable:
return "red";
case Request::state_exhausted:
return "DarkSlateGray";
case Request::state_future:
return "Gray";
default:
return "black";
}
}
void
GlobalPreferences::write_configrc()
{
KeyFile kf;
key_file_write(kf);
kf.file_write(get_config_filename());
}
void
GlobalPreferences::load_configrc()
{
KeyFile kf;
kf.file_read(get_config_filename());
key_file_read(kf);
}
void
GlobalPreferences::key_file_read(KeyFile& kf)
{
_mod_dirs.clear();
_pol_dirs.clear();
std::vector<Glib::ustring> old_mod_dirs(1, PLUGDIR);
std::vector<Glib::ustring> old_pol_dirs(1, POLDIR);
_mod_dirs = old_mod_dirs;
_pol_dirs = old_pol_dirs;
// read speed
{
int new_speed = 1000; // use a default value
const Glib::ustring* val = kf.search_value(Glib::ustring("speed"));
if (val)
switch (st)
{
new_speed = string_to<int>(*val);
set_speed(new_speed);
case Request::state_allocated:
return "ForestGreen";
case Request::state_allocable:
return "GoldenRod";
case Request::state_unallocable:
return "red";
case Request::state_exhausted:
return "DarkSlateGray";
case Request::state_future:
return "Gray";
default:
return "black";
}
}
// read modules directories
{
const Glib::ustring* val = kf.search_value(Glib::ustring("modules-dir-number"));
if (val)
}
void
GlobalPreferences::write_configrc ()
{
KeyFile kf;
key_file_write (kf);
kf.file_write (get_config_filename ());
}
void
GlobalPreferences::load_configrc ()
{
KeyFile kf;
kf.file_read (get_config_filename ());
key_file_read (kf);
}
void
GlobalPreferences::key_file_read (KeyFile &kf)
{
_mod_dirs.clear ();
_pol_dirs.clear ();
std::vector<Glib::ustring> old_mod_dirs (1, PLUGDIR);
std::vector<Glib::ustring> old_pol_dirs (1, POLDIR);
_mod_dirs = old_mod_dirs;
_pol_dirs = old_pol_dirs;
// read speed
{
std::istringstream istr(*val);
int n;
istr >> n;
for (int i = 1; i <= n; i++)
{
std::ostringstream ostr;
ostr << "modules-dir-" << i;
Glib::ustring key(ostr.str());
val = kf.search_value(key);
if (val && *val != _mod_dirs[0])
int new_speed = 1000; // use a default value
const Glib::ustring *val = kf.search_value (Glib::ustring ("speed"));
if (val)
{
// add_modules_dir(*val);
_mod_dirs.push_back(*val);
new_speed = string_to<int> (*val);
set_speed (new_speed);
}
}
}
}
// read policies directories
{
const Glib::ustring* val = kf.search_value(Glib::ustring("policies-dir-number"));
if (val)
// read modules directories
{
std::istringstream istr(*val);
int n;
istr >> n;
for (int i = 1; i <= n; i++)
{
std::ostringstream ostr;
ostr << "policies-dir-" << i;
Glib::ustring key(ostr.str().c_str());
val = kf.search_value(key);
if (val && *val != _pol_dirs[0])
const Glib::ustring *val = kf.search_value (Glib::ustring ("modules-dir-number"));
if (val)
{
// add_policies_dir(*val);
_pol_dirs.push_back(*val);
std::istringstream istr (*val);
int n;
istr >> n;
for (int i = 1; i <= n; i++)
{
std::ostringstream ostr;
ostr << "modules-dir-" << i;
Glib::ustring key (ostr.str ());
val = kf.search_value (key);
if (val && *val != _mod_dirs[0])
{
// add_modules_dir(*val);
_mod_dirs.push_back (*val);
}
}
}
}
}
}
// read policies directories
{
const Glib::ustring *val = kf.search_value (Glib::ustring ("policies-dir-number"));
if (val)
{
std::istringstream istr (*val);
int n;
istr >> n;
for (int i = 1; i <= n; i++)
{
std::ostringstream ostr;
ostr << "policies-dir-" << i;
Glib::ustring key (ostr.str ().c_str ());
val = kf.search_value (key);
if (val && *val != _pol_dirs[0])
{
// add_policies_dir(*val);
_pol_dirs.push_back (*val);
}
}
}
}
}
void
GlobalPreferences::key_file_write(KeyFile& kf)
GlobalPreferences::key_file_write (KeyFile &kf)
{
// write speed
{
Glib::ustring key("speed");
Glib::ustring value;
to_string<int>(_speed, value);
kf.insert_key_value(key, value);
}
// write speed
{
Glib::ustring key ("speed");
Glib::ustring value;
to_string<int> (_speed, value);
kf.insert_key_value (key, value);
}
// add modules directories
{
/*
// add modules directories
{
/*
GlobalPreferences::dir_iterator iter=_globalPreferences.modules_dir_begin();
*/
DirVectorConstIt iter = _mod_dirs.begin();
DirVectorConstIt end = _mod_dirs.end();
int n = 0;
while (iter != end)
{
std::ostringstream ostr;
n++;
ostr << "modules-dir-" << n; // << std::ends;
Glib::ustring key(ostr.str().c_str());
kf.insert_key_value(key, (*iter));
++iter;
DirVectorConstIt iter = _mod_dirs.begin ();
DirVectorConstIt end = _mod_dirs.end ();
int n = 0;
while (iter != end)
{
std::ostringstream ostr;
n++;
ostr << "modules-dir-" << n; // << std::ends;
Glib::ustring key (ostr.str ().c_str ());
kf.insert_key_value (key, (*iter));
++iter;
}
Glib::ustring key ("modules-dir-number");
std::ostringstream ostr;
ostr << n << std::ends;
Glib::ustring value (ostr.str ().c_str ());
kf.insert_key_value (key, value);
}
Glib::ustring key("modules-dir-number");
std::ostringstream ostr;
ostr << n << std::ends;
Glib::ustring value(ostr.str().c_str());
kf.insert_key_value(key, value);
}
// add policies directories
{
/*
// add policies directories
{
/*
GlobalPreferences::dir_iterator iter=_globalPreferences.policies_dir_begin();
*/
DirVectorConstIt iter = _pol_dirs.begin();
DirVectorConstIt end = _pol_dirs.end();
int n = 0;
while (iter != end)
{
std::ostringstream ostr;
n++;
ostr << "policies-dir-" << n; // << std::ends;
Glib::ustring key(ostr.str().c_str());
kf.insert_key_value(key, (*iter));
++iter;
DirVectorConstIt iter = _pol_dirs.begin ();
DirVectorConstIt end = _pol_dirs.end ();
int n = 0;
while (iter != end)
{
std::ostringstream ostr;
n++;
ostr << "policies-dir-" << n; // << std::ends;
Glib::ustring key (ostr.str ().c_str ());
kf.insert_key_value (key, (*iter));
++iter;
}
Glib::ustring key ("policies-dir-number");
std::ostringstream ostr;
ostr << n << std::ends;
Glib::ustring value (ostr.str ().c_str ());
kf.insert_key_value (key, value);
}
Glib::ustring key("policies-dir-number");
std::ostringstream ostr;
ostr << n << std::ends;
Glib::ustring value(ostr.str().c_str());
kf.insert_key_value(key, value);
}
}

View File

@ -26,37 +26,36 @@
namespace sgpem
{
class GlobalPreferencesSerializer;
class GlobalPreferencesSerializer;
/** \brief Save and retrieve global preferences formatted as key=value rows.
/** \brief Save and retrieve global preferences formatted as key=value rows.
*
* This class handles files to store and retrieve global preferences
* in the form of: key=value rows.
*
*/
class SG_DLLLOCAL GlobalPreferencesSerializer : public KeyFile
{
public:
class SG_DLLLOCAL GlobalPreferencesSerializer : public KeyFile
{
public:
/** \brief Object constructor */
GlobalPreferencesSerializer(GlobalPreferences &gp);
GlobalPreferencesSerializer (GlobalPreferences &gp);
/** \brief Read a file into this object.
*
* \param filename The file to read from.
*/
void file_read(const Glib::ustring& filename);
void file_read (const Glib::ustring &filename);
/** \brief Write a file from this object.
*
* \param filename The file to write to.
*/
void file_write(const Glib::ustring& filename);
private:
GlobalPreferences& _globalPreferences;
};
}
void file_write (const Glib::ustring &filename);
private:
GlobalPreferences &_globalPreferences;
};
} // namespace sgpem
#endif

View File

@ -18,8 +18,6 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/history.hh>
#include <sgpemv2/history_observer.hh>
@ -29,71 +27,68 @@
using namespace sgpem;
History::History()
: _front(0), _notify(true)
History::History () : _front (0), _notify (true)
{
}
History::~History()
History::~History ()
{
}
void
History::attach(HistoryObserver& observer)
History::attach (HistoryObserver &observer)
{
_observers.push_back(&observer);
_observers.push_back (&observer);
}
void
History::detach(const HistoryObserver& observer)
History::detach (const HistoryObserver &observer)
{
_observers.erase(std::find(_observers.begin(),
_observers.end(),
&observer));
_observers.erase (std::find (_observers.begin (), _observers.end (), &observer));
}
void
History::notify_change()
History::notify_change ()
{
if (!_notify) return;
if (!_notify)
return;
for (RegisteredObservers::iterator it = _observers.begin();
it != _observers.end(); it++)
(*it)->update(*this);
for (RegisteredObservers::iterator it = _observers.begin (); it != _observers.end (); it++)
(*it)->update (*this);
}
unsigned int History::get_front() const
unsigned int
History::get_front () const
{
return _front;
return _front;
}
bool
History::set_notify_enabled(bool enabled)
History::set_notify_enabled (bool enabled)
{
bool old_value = _notify;
_notify = enabled;
bool old_value = _notify;
_notify = enabled;
// Force notify if we re-enable it
if (old_value == false && _notify == true)
notify_change();
// Force notify if we re-enable it
if (old_value == false && _notify == true)
notify_change ();
return old_value;
return old_value;
}
// --------- History::LockNotify ---------------
History::LockNotify::LockNotify(History& history)
: _h(history), _was_enabled(_h.set_notify_enabled(false))
History::LockNotify::LockNotify (History &history) : _h (history), _was_enabled (_h.set_notify_enabled (false))
{
}
History::LockNotify::~LockNotify()
History::LockNotify::~LockNotify ()
{
_h.set_notify_enabled(_was_enabled);
_h.set_notify_enabled (_was_enabled);
}

View File

@ -20,6 +20,8 @@
#include <sgpemv2/history_observer.hh>
sgpem::HistoryObserver::~HistoryObserver() {}
sgpem::HistoryObserver::~HistoryObserver ()
{
}
// Pure abstract class. Nothing else to put here.

View File

@ -18,12 +18,10 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/invalid_plugin_exception.hh>
using namespace sgpem;
InvalidPluginException::InvalidPluginException(const std::string& what) :
std::runtime_error(what)
{}
InvalidPluginException::InvalidPluginException (const std::string &what) : std::runtime_error (what)
{
}

View File

@ -18,9 +18,8 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/key_file.hh>
#include <fstream>
#include <sgpemv2/key_file.hh>
#include <string.h>
#include <iostream>
@ -29,106 +28,106 @@ using namespace std;
namespace sgpem
{
KeyFile::KeyFile()
{}
KeyFile::KeyFile ()
{
}
KeyFile::elements_iterator
KeyFile::elements_begin() const
{
return _elements.begin();
}
KeyFile::elements_iterator
KeyFile::elements_begin () const
{
return _elements.begin ();
}
KeyFile::elements_iterator
KeyFile::elements_end() const
{
return _elements.end();
}
KeyFile::elements_iterator
KeyFile::elements_end () const
{
return _elements.end ();
}
void
KeyFile::insert_key_value(const Glib::ustring& key, const Glib::ustring& value)
{
std::map<Glib::ustring, Glib::ustring>::value_type val_pair(key, value);
_elements.insert(val_pair);
}
void
KeyFile::insert_key_value (const Glib::ustring &key, const Glib::ustring &value)
{
std::map<Glib::ustring, Glib::ustring>::value_type val_pair (key, value);
_elements.insert (val_pair);
}
const Glib::ustring*
KeyFile::search_value(const Glib::ustring& key)
{
const Glib::ustring* ret = 0;
elements_iterator cur = _elements.find(key);
if (cur != elements_end())
const Glib::ustring *
KeyFile::search_value (const Glib::ustring &key)
{
const Glib::ustring *ret = 0;
elements_iterator cur = _elements.find (key);
if (cur != elements_end ())
{
ret = &((*cur).second);
ret = &((*cur).second);
}
return ret;
}
}
void
KeyFile::file_read(const Glib::ustring& filename)
{
std::ifstream ifs(filename.c_str());
void
KeyFile::file_read (const Glib::ustring &filename)
{
std::ifstream ifs (filename.c_str ());
if (ifs)
{
file_read(ifs);
file_read (ifs);
} // end - if(ifs)
}
}
void
KeyFile::file_read(std::istream& is)
{
void
KeyFile::file_read (std::istream &is)
{
const unsigned int KEY_FILE_BUF_LEN = 1000;
if (is)
{
_elements.clear(); // erase all elements
char buff[KEY_FILE_BUF_LEN]; //
while (is)
{
is.getline(buff, (KEY_FILE_BUF_LEN), '\n');
// if not a comment line...
if (*buff != '\0' && *buff != '#')
_elements.clear (); // erase all elements
char buff[KEY_FILE_BUF_LEN]; //
while (is)
{
char* pos = strchr(buff, '=');
if (pos != 0)
{
*pos = '\0';
const Glib::ustring key(buff);
const Glib::ustring value(pos + 1);
insert_key_value(key, value);
}
} // end - if not a comment line...
is.getline (buff, (KEY_FILE_BUF_LEN), '\n');
// if not a comment line...
} // end - while(ifs))
if (*buff != '\0' && *buff != '#')
{
char *pos = strchr (buff, '=');
if (pos != 0)
{
*pos = '\0';
const Glib::ustring key (buff);
const Glib::ustring value (pos + 1);
insert_key_value (key, value);
}
} // end - if not a comment line...
} // end - while(ifs))
} // end - if(ifs)
}
}
void
KeyFile::file_write(const Glib::ustring& filename)
{
std::ofstream ofs(filename.c_str());
void
KeyFile::file_write (const Glib::ustring &filename)
{
std::ofstream ofs (filename.c_str ());
if (ofs)
{
file_write(ofs);
file_write (ofs);
} // end - if(ofs)
}
}
void
KeyFile::file_write(std::ostream& os)
{
void
KeyFile::file_write (std::ostream &os)
{
if (os)
{
elements_iterator iter;
for (iter = elements_begin(); iter != elements_end(); iter++)
{
os << (*iter).first << "=" << (*iter).second << std::endl;
}
elements_iterator iter;
for (iter = elements_begin (); iter != elements_end (); iter++)
{
os << (*iter).first << "=" << (*iter).second << std::endl;
}
} // end - if(ofs)
}
}
} // namespace sgpem

View File

@ -25,7 +25,6 @@
#include <sgpemv2/malformed_policy_exception.hh>
using namespace sgpem;
MalformedPolicyException::MalformedPolicyException(const std::string& msg)
: CPUPolicyException(msg)
{}
MalformedPolicyException::MalformedPolicyException (const std::string &msg) : CPUPolicyException (msg)
{
}

View File

@ -21,72 +21,72 @@
using namespace sgpem;
Module::Module(const Glib::ustring& identifier) :
Glib::Module(identifier),
_enabled(false),
_id(identifier),
on_init_ptr(NULL),
on_exit_ptr(NULL),
describe_ptr(NULL),
get_name_ptr(NULL),
get_author_ptr(NULL),
get_version_ptr(NULL)
Module::Module (const Glib::ustring &identifier)
: Glib::Module (identifier),
_enabled (false),
_id (identifier),
on_init_ptr (NULL),
on_exit_ptr (NULL),
describe_ptr (NULL),
get_name_ptr (NULL),
get_author_ptr (NULL),
get_version_ptr (NULL)
{
if (!*this) throw InvalidPluginException(Module::get_last_error());
if (!*this)
throw InvalidPluginException (Module::get_last_error ());
// Type-safeness here is an optional, as always. :-)
std::string prefix = "sgpem__Plugin__";
if (!(get_symbol(prefix + "on_init", reinterpret_cast<void*&>(on_init_ptr)) &&
get_symbol(prefix + "on_exit", reinterpret_cast<void*&>(on_exit_ptr)) &&
get_symbol(prefix + "describe", reinterpret_cast<void*&>(describe_ptr)) &&
get_symbol(prefix + "get_name", reinterpret_cast<void*&>(get_name_ptr)) &&
get_symbol(prefix + "get_author", reinterpret_cast<void*&>(get_author_ptr)) &&
get_symbol(prefix + "get_version", reinterpret_cast<void*&>(get_version_ptr))))
throw InvalidPluginException("incomplete/wrong exported interface");
// Type-safeness here is an optional, as always. :-)
std::string prefix = "sgpem__Plugin__";
if (!(get_symbol (prefix + "on_init", reinterpret_cast<void *&> (on_init_ptr)) &&
get_symbol (prefix + "on_exit", reinterpret_cast<void *&> (on_exit_ptr)) &&
get_symbol (prefix + "describe", reinterpret_cast<void *&> (describe_ptr)) &&
get_symbol (prefix + "get_name", reinterpret_cast<void *&> (get_name_ptr)) &&
get_symbol (prefix + "get_author", reinterpret_cast<void *&> (get_author_ptr)) &&
get_symbol (prefix + "get_version", reinterpret_cast<void *&> (get_version_ptr))))
throw InvalidPluginException ("incomplete/wrong exported interface");
}
void
Module::set_enabled(bool enabled)
Module::set_enabled (bool enabled)
{
if (_enabled == enabled)
return;
if (_enabled == enabled)
return;
if (enabled)
on_init_ptr();
else
on_exit_ptr();
if (enabled)
on_init_ptr ();
else
on_exit_ptr ();
_enabled = enabled;
_enabled = enabled;
}
Glib::ustring
Module::get_name() const
Module::get_name () const
{
return get_name_ptr();
return get_name_ptr ();
}
Glib::ustring
Module::get_author() const
Module::get_author () const
{
return get_author_ptr();
return get_author_ptr ();
}
Glib::ustring
Module::describe() const
Module::describe () const
{
return describe_ptr();
return describe_ptr ();
}
float
Module::get_version() const
Module::get_version () const
{
return get_version_ptr();
return get_version_ptr ();
}
bool
Module::get_enabled() const
Module::get_enabled () const
{
return _enabled;
return _enabled;
}

View File

@ -26,8 +26,6 @@
using namespace sgpem;
NullPolicyException::NullPolicyException(const char* msg)
: std::runtime_error(msg)
NullPolicyException::NullPolicyException (const char *msg) : std::runtime_error (msg)
{
}

View File

@ -18,79 +18,75 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/plugin_manager.hh>
#include <sgpemv2/module.hh>
#include <sgpemv2/global_preferences.hh>
#include <sgpemv2/module.hh>
#include <sgpemv2/plugin_manager.hh>
#include <sgpemv2/templates/singleton.tcc>
#include <glibmm/fileutils.h>
#include <glibmm/pattern.h>
#include <iostream>
#include <algorithm>
#include <iostream>
using namespace sgpem;
template class sgpem::Singleton<PluginManager>;
std::vector<Module*>
PluginManager::get_module_list() const
std::vector<Module *>
PluginManager::get_module_list () const
{
return _modules;
return _modules;
}
void
PluginManager::rescan_dirs()
PluginManager::rescan_dirs ()
{
Module* module = nullptr;
Module *module = nullptr;
for_each(_modules.begin(), _modules.end(),
[] (auto *p) { delete p; });
_modules.clear();
for_each (_modules.begin (), _modules.end (), [](auto *p) { delete p; });
_modules.clear ();
GlobalPreferences& prefs = GlobalPreferences::get_instance();
GlobalPreferences::DirVector& plugin_dirs = prefs.get_plugin_dirs();
GlobalPreferences::DirVectorIt it = plugin_dirs.begin();
GlobalPreferences &prefs = GlobalPreferences::get_instance ();
GlobalPreferences::DirVector &plugin_dirs = prefs.get_plugin_dirs ();
GlobalPreferences::DirVectorIt it = plugin_dirs.begin ();
Glib::PatternSpec shared_obj(Glib::ustring("*.") + G_MODULE_SUFFIX);
Glib::PatternSpec shared_obj (Glib::ustring ("*.") + G_MODULE_SUFFIX);
while (it != plugin_dirs.end())
{
Glib::Dir dir(*it);
for (Glib::DirIterator dir_it = dir.begin(); dir_it != dir.end(); ++dir_it)
while (it != plugin_dirs.end ())
{
// only attempt to load .so files
if (shared_obj.match(*dir_it))
{
std::string module_path = Module::build_path(*it, *dir_it);
Glib::Dir dir (*it);
std::cerr << "Attempting to load module at path " << module_path << std::endl;
for (Glib::DirIterator dir_it = dir.begin (); dir_it != dir.end (); ++dir_it)
{
// only attempt to load .so files
if (shared_obj.match (*dir_it))
{
std::string module_path = Module::build_path (*it, *dir_it);
try
{
module = new Module(module_path);
_modules.push_back(module);
std::cerr << "\tSuccess" << std::endl;
std::cerr << "Attempting to load module at path " << module_path << std::endl;
try
{
module = new Module (module_path);
_modules.push_back (module);
std::cerr << "\tSuccess" << std::endl;
}
catch (InvalidPluginException &e)
{
std::cerr << "\tFailed, invalid plugin: " << e.what () << std::endl;
}
}
}
catch (InvalidPluginException& e)
{
std::cerr << "\tFailed, invalid plugin: " << e.what() << std::endl;
}
}
it++;
}
it++;
}
}
PluginManager::PluginManager()
PluginManager::PluginManager ()
{
rescan_dirs();
rescan_dirs ();
}

View File

@ -29,10 +29,10 @@ using Glib::ustring;
// instantiate Parameter template for use outside this DSO
namespace sgpem
{
template class SG_DLLEXPORT PolicyParameters::Parameter<int>;
template class SG_DLLEXPORT PolicyParameters::Parameter<float>;
template class SG_DLLEXPORT PolicyParameters::Parameter<Glib::ustring>;
}
template class SG_DLLEXPORT PolicyParameters::Parameter<int>;
template class SG_DLLEXPORT PolicyParameters::Parameter<float>;
template class SG_DLLEXPORT PolicyParameters::Parameter<Glib::ustring>;
} // namespace sgpem
/**
@ -40,25 +40,17 @@ namespace sgpem
If there is a parameter with the same name and type it will be overwritten.
*/
void
PolicyParameters::register_int(Glib::ustring name,
const int& lower_bound,
const int& upper_bound,
const bool& required,
const int& default_value)
PolicyParameters::register_int (Glib::ustring name, const int &lower_bound, const int &upper_bound,
const bool &required, const int &default_value)
{
//there is a parameter with the same name!!
map<ustring, Parameter<int> >::iterator i = int_map.find(name);
if (i != int_map.end())
int_map.erase(i);
map<ustring, Parameter<int> >::value_type v(name, Parameter<int>(name,
default_value,
lower_bound,
upper_bound,
required,
default_value));
int_map.insert(v);
//there is a parameter with the same name!!
map<ustring, Parameter<int>>::iterator i = int_map.find (name);
if (i != int_map.end ())
int_map.erase (i);
map<ustring, Parameter<int>>::value_type v (
name, Parameter<int> (name, default_value, lower_bound, upper_bound, required, default_value));
int_map.insert (v);
}
/**
@ -66,25 +58,18 @@ PolicyParameters::register_int(Glib::ustring name,
If there is a parameter with the same name and type it will be overwritten.
*/
void
PolicyParameters::register_float(Glib::ustring name,
const float& lower_bound,
const float& upper_bound,
const bool& required,
const float& default_value)
PolicyParameters::register_float (Glib::ustring name, const float &lower_bound, const float &upper_bound,
const bool &required, const float &default_value)
{
//there is a parameter with the same name!!
map<ustring, Parameter<float> >::iterator i = float_map.find(name);
if (i != float_map.end())
float_map.erase(i);
//there is a parameter with the same name!!
map<ustring, Parameter<float>>::iterator i = float_map.find (name);
if (i != float_map.end ())
float_map.erase (i);
map<ustring, Parameter<float> >::value_type v(name, Parameter<float>(name,
default_value,
lower_bound,
upper_bound,
required,
default_value));
map<ustring, Parameter<float>>::value_type v (
name, Parameter<float> (name, default_value, lower_bound, upper_bound, required, default_value));
float_map.insert(v);
float_map.insert (v);
}
/**
@ -92,20 +77,16 @@ PolicyParameters::register_float(Glib::ustring name,
If there is a parameter with the same name and type it will be overwritten.
*/
void
PolicyParameters::register_string(Glib::ustring name, const bool& required, const Glib::ustring& default_value)
PolicyParameters::register_string (Glib::ustring name, const bool &required, const Glib::ustring &default_value)
{
//there is a parameter with the same name!!
map<ustring, Parameter<Glib::ustring> >::iterator i = string_map.find(name);
if (i != string_map.end())
string_map.erase(i);
//there is a parameter with the same name!!
map<ustring, Parameter<Glib::ustring>>::iterator i = string_map.find (name);
if (i != string_map.end ())
string_map.erase (i);
map<ustring, Parameter<Glib::ustring> >::value_type v(name, Parameter<Glib::ustring>(name,
default_value,
"",
"",
required,
default_value));
string_map.insert(v);
map<ustring, Parameter<Glib::ustring>>::value_type v (
name, Parameter<Glib::ustring> (name, default_value, "", "", required, default_value));
string_map.insert (v);
}
/**
@ -113,38 +94,38 @@ PolicyParameters::register_string(Glib::ustring name, const bool& required, cons
*/
void
PolicyParameters::clear()
PolicyParameters::clear ()
{
int_map.clear();
float_map.clear();
string_map.clear();
int_map.clear ();
float_map.clear ();
string_map.clear ();
}
/**
Retruns a copy of the map containing all registered integer parameters.
*/
map<ustring, PolicyParameters::Parameter<int> >
PolicyParameters::get_registered_int_parameters() const
map<ustring, PolicyParameters::Parameter<int>>
PolicyParameters::get_registered_int_parameters () const
{
return int_map;
return int_map;
}
/**
Retruns a copy of the map containing all registered float parameters.
*/
map<ustring, PolicyParameters::Parameter<float> >
PolicyParameters::get_registered_float_parameters() const
map<ustring, PolicyParameters::Parameter<float>>
PolicyParameters::get_registered_float_parameters () const
{
return float_map;
return float_map;
}
/**
Retruns a copy of the map containing all registered string parameters.
*/
map<ustring, PolicyParameters::Parameter<ustring> >
PolicyParameters::get_registered_string_parameters() const
map<ustring, PolicyParameters::Parameter<ustring>>
PolicyParameters::get_registered_string_parameters () const
{
return string_map;
return string_map;
}
/**
@ -154,18 +135,18 @@ PolicyParameters::get_registered_string_parameters() const
\returns FALSE in the other cases.
*/
bool
PolicyParameters::set_int(ustring name, const int& value)
PolicyParameters::set_int (ustring name, const int &value)
{
map<ustring, Parameter<int> >::iterator i = int_map.find(name);
if (i == int_map.end())
//the parameter doesn't exist!!
return false;
map<ustring, Parameter<int>>::iterator i = int_map.find (name);
if (i == int_map.end ())
//the parameter doesn't exist!!
return false;
if (value < i->second.get_lower_bound() || value > i->second.get_upper_bound())
return false;
if (value < i->second.get_lower_bound () || value > i->second.get_upper_bound ())
return false;
i->second.set_value(value);
return true;
i->second.set_value (value);
return true;
}
@ -176,18 +157,18 @@ PolicyParameters::set_int(ustring name, const int& value)
\returns FALSE in the other cases.
*/
bool
PolicyParameters::set_float(ustring name, const float& value)
PolicyParameters::set_float (ustring name, const float &value)
{
map<ustring, Parameter<float> >::iterator i = float_map.find(name);
if (i == float_map.end())
//the parameter doesn't exist!!
return false;
map<ustring, Parameter<float>>::iterator i = float_map.find (name);
if (i == float_map.end ())
//the parameter doesn't exist!!
return false;
if (value < i->second.get_lower_bound() || value > i->second.get_upper_bound())
return false;
if (value < i->second.get_lower_bound () || value > i->second.get_upper_bound ())
return false;
i->second.set_value(value);
return true;
i->second.set_value (value);
return true;
}
/**
@ -197,15 +178,15 @@ PolicyParameters::set_float(ustring name, const float& value)
\returns FALSE in the other case.
*/
bool
PolicyParameters::set_string(ustring name, const ustring& value)
PolicyParameters::set_string (ustring name, const ustring &value)
{
map<ustring, Parameter<ustring> >::iterator i = string_map.find(name);
if (i == string_map.end())
//the parameter doesn't exist!!
return false;
map<ustring, Parameter<ustring>>::iterator i = string_map.find (name);
if (i == string_map.end ())
//the parameter doesn't exist!!
return false;
i->second.set_value(value);
return true;
i->second.set_value (value);
return true;
}
/**
@ -214,13 +195,13 @@ PolicyParameters::set_string(ustring name, const ustring& value)
\throws A PolicyParametersException if the parameter has not been found.
*/
int
PolicyParameters::get_int(ustring name) const
PolicyParameters::get_int (ustring name) const
{
map<ustring, Parameter<int> >::const_iterator i = int_map.find(name);
if (i == int_map.end())
throw PolicyParametersException("Unregistred parameter");
else
return i->second.get_value();
map<ustring, Parameter<int>>::const_iterator i = int_map.find (name);
if (i == int_map.end ())
throw PolicyParametersException ("Unregistred parameter");
else
return i->second.get_value ();
}
@ -230,13 +211,13 @@ PolicyParameters::get_int(ustring name) const
\throws A PolicyParametersException if the parameter has not been found.
*/
float
PolicyParameters::get_float(ustring name) const
PolicyParameters::get_float (ustring name) const
{
map<ustring, Parameter<float> >::const_iterator i = float_map.find(name);
if (i == float_map.end())
throw PolicyParametersException("Unregistred parameter");
else
return i->second.get_value();
map<ustring, Parameter<float>>::const_iterator i = float_map.find (name);
if (i == float_map.end ())
throw PolicyParametersException ("Unregistred parameter");
else
return i->second.get_value ();
}
@ -246,12 +227,11 @@ PolicyParameters::get_float(ustring name) const
\throws A PolicyParametersException if the parameter has not been found.
*/
ustring
PolicyParameters::get_string(ustring name) const
PolicyParameters::get_string (ustring name) const
{
map<ustring, Parameter<ustring> >::const_iterator i = string_map.find(name);
if (i == string_map.end())
throw PolicyParametersException("Unregistred parameter");
else
return i->second.get_value();
map<ustring, Parameter<ustring>>::const_iterator i = string_map.find (name);
if (i == string_map.end ())
throw PolicyParametersException ("Unregistred parameter");
else
return i->second.get_value ();
}

View File

@ -22,6 +22,6 @@
using namespace sgpem;
Process::~Process()
{}
Process::~Process ()
{
}

View File

@ -22,12 +22,10 @@
using namespace sgpem;
ProcessStatistics::~ProcessStatistics()
ProcessStatistics::~ProcessStatistics ()
{
}
ProcessStatistics::ProcessStatistics()
ProcessStatistics::ProcessStatistics ()
{
}

View File

@ -24,66 +24,66 @@ using sgpem::ReadyQueue;
using sgpem::Thread;
void
ReadyQueue::swap(position a, position b)
ReadyQueue::swap (position a, position b)
{
if (a == b) return;
if (a == b)
return;
// Usage of "at()" isn't casual:
// at() checks indexes, "[]" doesn't.
// Once we've done the check once, we
// can assume it's safe to use "[]";
// this for performance reasons.
Thread* temp = _scheds.at(a);
_scheds[a] = _scheds.at(b);
_scheds[b] = temp;
// Usage of "at()" isn't casual:
// at() checks indexes, "[]" doesn't.
// Once we've done the check once, we
// can assume it's safe to use "[]";
// this for performance reasons.
Thread *temp = _scheds.at (a);
_scheds[a] = _scheds.at (b);
_scheds[b] = temp;
}
ReadyQueue::size_t
ReadyQueue::size() const
ReadyQueue::size () const
{
return _scheds.size();
return _scheds.size ();
}
sgpem::Thread&
ReadyQueue::get_item_at(position index)
sgpem::Thread &
ReadyQueue::get_item_at (position index)
{
// Checks index access
return *_scheds.at(index);
// Checks index access
return *_scheds.at (index);
}
const sgpem::Thread&
ReadyQueue::get_item_at(position index) const
const sgpem::Thread &
ReadyQueue::get_item_at (position index) const
{
// Checks index access
return *_scheds.at(index);
// Checks index access
return *_scheds.at (index);
}
void
ReadyQueue::append(Thread& thread)
ReadyQueue::append (Thread &thread)
{
_scheds.push_back(&thread);
_scheds.push_back (&thread);
}
void
ReadyQueue::bubble_to_front(position x)
ReadyQueue::bubble_to_front (position x)
{
while(x > 0)
{
swap(x - 1, x);
--x;
}
while (x > 0)
{
swap (x - 1, x);
--x;
}
}
void
ReadyQueue::erase_first()
ReadyQueue::erase_first ()
{
_scheds.erase(_scheds.begin());
_scheds.erase (_scheds.begin ());
}

View File

@ -22,6 +22,6 @@
using namespace sgpem;
Request::~Request()
{}
Request::~Request ()
{
}

View File

@ -22,7 +22,6 @@
using namespace sgpem;
Resource::~Resource()
Resource::~Resource ()
{
}

View File

@ -18,12 +18,10 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/resource_policies_gatekeeper.hh>
#include <sgpemv2/resource_policy_manager.hh>
#include <sgpemv2/resource_policy.hh>
#include "concrete_history.hh"
#include <sgpemv2/resource_policies_gatekeeper.hh>
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/resource_policy_manager.hh>
// Include full template definition only in implementation files:
#include <sgpemv2/templates/singleton.tcc>
@ -33,93 +31,94 @@
#include <algorithm>
#include <cassert>
using std::vector;
using std::map;
using std::find;
using std::map;
using std::runtime_error;
using std::vector;
using namespace sgpem;
// Explicit template instantiation to allow to export symbols from the DSO.
template class sgpem::Singleton<ResourcePoliciesGatekeeper>;
typedef vector<ResourcePolicyManager*>::iterator ManagerIterator;
typedef map<History*, ResourcePolicy*>::iterator PolicyIterator;
typedef vector<ResourcePolicyManager *>::iterator ManagerIterator;
typedef map<History *, ResourcePolicy *>::iterator PolicyIterator;
const vector<ResourcePolicyManager*>&
ResourcePoliciesGatekeeper::get_registered() const
const vector<ResourcePolicyManager *> &
ResourcePoliciesGatekeeper::get_registered () const
{
return _registered;
return _registered;
}
void
ResourcePoliciesGatekeeper::register_manager(ResourcePolicyManager* manager)
ResourcePoliciesGatekeeper::register_manager (ResourcePolicyManager *manager)
{
assert(manager != nullptr);
assert (manager != nullptr);
ManagerIterator end = _registered.end();
ManagerIterator end = _registered.end ();
if (find(_registered.begin(), end, manager) == end)
_registered.push_back(manager);
if (find (_registered.begin (), end, manager) == end)
_registered.push_back (manager);
}
void
ResourcePoliciesGatekeeper::unregister_manager(ResourcePolicyManager* manager)
ResourcePoliciesGatekeeper::unregister_manager (ResourcePolicyManager *manager)
{
assert(manager != nullptr);
assert (manager != nullptr);
ManagerIterator end = _registered.end();
ManagerIterator pos = find(_registered.begin(), end, manager);
ManagerIterator end = _registered.end ();
ManagerIterator pos = find (_registered.begin (), end, manager);
if (pos != end)
{
deactivate_policies(**pos);
_registered.erase(pos);
}
if (pos != end)
{
deactivate_policies (**pos);
_registered.erase (pos);
}
}
ResourcePolicy&
ResourcePoliciesGatekeeper::get_current_policy(History* history)
ResourcePolicy &
ResourcePoliciesGatekeeper::get_current_policy (History *history)
{
assert(history != nullptr);
assert (history != nullptr);
PolicyIterator policy = _active_policies.find(history);
PolicyIterator policy = _active_policies.find (history);
if (policy == _active_policies.end())
throw runtime_error(_("No active policy associated with this "
"history is available."));
if (policy == _active_policies.end ())
throw runtime_error (
_ ("No active policy associated with this "
"history is available."));
return *policy->second;
return *policy->second;
}
void
ResourcePoliciesGatekeeper::activate_policy(History *history, ResourcePolicy* policy)
ResourcePoliciesGatekeeper::activate_policy (History *history, ResourcePolicy *policy)
{
assert(history != nullptr && policy != nullptr);
assert (history != nullptr && policy != nullptr);
_active_policies[history] = policy;
// the content of history (if any) is not vaild any more.
down_cast<ConcreteHistory*>(history)->reset();
_active_policies[history] = policy;
// the content of history (if any) is not vaild any more.
down_cast<ConcreteHistory *> (history)->reset ();
}
ResourcePoliciesGatekeeper::ResourcePoliciesGatekeeper()
{}
ResourcePoliciesGatekeeper::ResourcePoliciesGatekeeper ()
{
}
void
ResourcePoliciesGatekeeper::deactivate_policies(const ResourcePolicyManager& manager)
ResourcePoliciesGatekeeper::deactivate_policies (const ResourcePolicyManager &manager)
{
typedef vector<ResourcePolicy*>::const_iterator AvailableIt;
typedef vector<ResourcePolicy *>::const_iterator AvailableIt;
const vector<ResourcePolicy*>& policies = manager.get_avail_policies();
const vector<ResourcePolicy *> &policies = manager.get_avail_policies ();
for (AvailableIt avail_it = policies.begin(); avail_it != policies.end(); ++avail_it)
{
for (PolicyIterator it = _active_policies.begin(); it != _active_policies.end();)
if (it->second == *avail_it)
// Please note the postfix increment (operating
// on the old iterator, now invalidated by erase)
_active_policies.erase(it++);
else
++it;
} //~ for(avail_it)
for (AvailableIt avail_it = policies.begin (); avail_it != policies.end (); ++avail_it)
{
for (PolicyIterator it = _active_policies.begin (); it != _active_policies.end ();)
if (it->second == *avail_it)
// Please note the postfix increment (operating
// on the old iterator, now invalidated by erase)
_active_policies.erase (it++);
else
++it;
} //~ for(avail_it)
}

View File

@ -22,13 +22,13 @@
using namespace sgpem;
ResourcePolicy::~ResourcePolicy()
{}
PolicyParameters&
ResourcePolicy::get_parameters()
ResourcePolicy::~ResourcePolicy ()
{
return _parameters;
}
PolicyParameters &
ResourcePolicy::get_parameters ()
{
return _parameters;
}

View File

@ -24,62 +24,62 @@
using namespace std;
using namespace sgpem;
ResourcePolicyFiFo::~ResourcePolicyFiFo()
{}
ResourcePolicyFiFo::~ResourcePolicyFiFo ()
{
}
void
ResourcePolicyFiFo::configure()
ResourcePolicyFiFo::configure ()
{
}
void
ResourcePolicyFiFo::enforce(Environment& /*environment*/, Environment::SubRequestQueue& queue, SubRequest& sr)
ResourcePolicyFiFo::enforce (Environment & /*environment*/, Environment::SubRequestQueue &queue, SubRequest &sr)
{
typedef Environment::SubRequestQueue SubRequestQueue;
typedef Environment::SubRequestQueue SubRequestQueue;
// the last inserted request goes on the last free place.
SubRequestQueue old_queue(queue);
queue.clear();
// the last inserted request goes on the last free place.
SubRequestQueue old_queue (queue);
queue.clear ();
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
{
// allocated ones remain allocated
if((**i).get_state() == Request::state_allocated)
queue.push_back(*i);
}
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
{
// allocated ones remain allocated
if ((**i).get_state () == Request::state_allocated)
queue.push_back (*i);
}
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
if((**i).get_state() != Request::state_allocated && *i != &sr)
queue.push_back(*i);
queue.push_back(&sr);
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
if ((**i).get_state () != Request::state_allocated && *i != &sr)
queue.push_back (*i);
queue.push_back (&sr);
}
Glib::ustring
ResourcePolicyFiFo::get_description() const
ResourcePolicyFiFo::get_description () const
{
return _("A resource policy which satisfies earlier requests before older ones.");
return _ ("A resource policy which satisfies earlier requests before older ones.");
}
Glib::ustring
ResourcePolicyFiFo::get_name() const
ResourcePolicyFiFo::get_name () const
{
return _("First In, First Out");
return _ ("First In, First Out");
}
void
ResourcePolicyFiFo::activate()
ResourcePolicyFiFo::activate ()
{
}
void
ResourcePolicyFiFo::deactivate()
ResourcePolicyFiFo::deactivate ()
{
}

View File

@ -30,16 +30,16 @@
namespace sgpem
{
class ResourcePolicyFiFo;
class ResourcePolicyFiFo;
/** \brief
/** \brief
It's a Strategy wich stay for a resource allocating algorithm.
It implements the related resource allocation policy.
*/
class SG_DLLLOCAL ResourcePolicyFiFo : public ResourcePolicy
{
public:
virtual ~ResourcePolicyFiFo();
class SG_DLLLOCAL ResourcePolicyFiFo : public ResourcePolicy
{
public:
virtual ~ResourcePolicyFiFo ();
/**
Initialize the inner components of the policy.
@ -47,7 +47,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented
in concrete derived classes.
*/
virtual void configure();
virtual void configure ();
/**
Mixes the queues.
@ -55,7 +55,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented
in concrete derived classes.
*/
virtual void enforce(Environment& environment, Environment::SubRequestQueue& queue, SubRequest& sr);
virtual void enforce (Environment &environment, Environment::SubRequestQueue &queue, SubRequest &sr);
/**
Gets a string description of the policy.
@ -64,16 +64,16 @@ namespace sgpem
in concrete derived classes.
\return String description of the policy.
*/
virtual Glib::ustring get_description() const;
virtual Glib::ustring get_description () const;
virtual Glib::ustring get_name() const;
virtual Glib::ustring get_name () const;
virtual void activate();
virtual void activate ();
virtual void deactivate();
};
virtual void deactivate ();
};
}//~ namespace sgpem
} // namespace sgpem
#endif //~ RESOURCE_POLICY_FIFO_HH

View File

@ -23,74 +23,74 @@
using namespace std;
using namespace sgpem;
ResourcePolicyLiFo::~ResourcePolicyLiFo()
{}
ResourcePolicyLiFo::~ResourcePolicyLiFo ()
{
}
void
ResourcePolicyLiFo::configure()
ResourcePolicyLiFo::configure ()
{
}
void
ResourcePolicyLiFo::enforce(Environment& /*environment*/, Environment::SubRequestQueue& queue, SubRequest& sr)
ResourcePolicyLiFo::enforce (Environment & /*environment*/, Environment::SubRequestQueue &queue, SubRequest &sr)
{
typedef Environment::SubRequestQueue SubRequestQueue;
typedef Environment::SubRequestQueue SubRequestQueue;
// the last inserted request goes on the first free place.
SubRequestQueue old_queue(queue);
queue.clear();
// the last inserted request goes on the first free place.
SubRequestQueue old_queue (queue);
queue.clear ();
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
{
// allocated ones remain allocated
if((**i).get_state() == Request::state_allocated)
queue.push_back(*i);
}
bool inserted = false;
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
{
// allocated ones remain allocated
if((**i).get_state() != Request::state_allocated)
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
{
// non-allocated ones go after the newly arrived
if(!inserted)
{
queue.push_back(&sr);
inserted = true;
}
if (*i != &sr)
queue.push_back(*i);
// allocated ones remain allocated
if ((**i).get_state () == Request::state_allocated)
queue.push_back (*i);
}
bool inserted = false;
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
{
// allocated ones remain allocated
if ((**i).get_state () != Request::state_allocated)
{
// non-allocated ones go after the newly arrived
if (!inserted)
{
queue.push_back (&sr);
inserted = true;
}
if (*i != &sr)
queue.push_back (*i);
}
}
}
}
Glib::ustring
ResourcePolicyLiFo::get_description() const
ResourcePolicyLiFo::get_description () const
{
return _("A resource policy which allows a request to be immediately allocated if there is enough space.");
return _ ("A resource policy which allows a request to be immediately allocated if there is enough space.");
}
Glib::ustring
ResourcePolicyLiFo::get_name() const
ResourcePolicyLiFo::get_name () const
{
return _("Last In, First Out");
return _ ("Last In, First Out");
}
void
ResourcePolicyLiFo::activate()
ResourcePolicyLiFo::activate ()
{
}
void
ResourcePolicyLiFo::deactivate()
ResourcePolicyLiFo::deactivate ()
{
}

View File

@ -31,30 +31,30 @@
namespace sgpem
{
class ResourcePolicyLiFo;
class ResourcePolicyLiFo;
/** \brief
/** \brief
It's a Strategy wich stay for a resource allocating algorithm.
It implements the related resource allocation policy.
*/
class SG_DLLLOCAL ResourcePolicyLiFo : public ResourcePolicy
{
public:
virtual ~ResourcePolicyLiFo();
class SG_DLLLOCAL ResourcePolicyLiFo : public ResourcePolicy
{
public:
virtual ~ResourcePolicyLiFo ();
/** \brief Initialize the inner components of the policy.
*
* Because it's a pure virtual method, must be re-implemented
* in concrete derived classes.
*/
virtual void configure();
virtual void configure ();
/** \brief Mixes the queues.
*
* Because it's a pure virtual method, must be re-implemented
* in concrete derived classes.
*/
virtual void enforce(Environment& environment, Environment::SubRequestQueue& queue, SubRequest& sr);
virtual void enforce (Environment &environment, Environment::SubRequestQueue &queue, SubRequest &sr);
/** \brief Gets a string description of the policy.
*
@ -62,26 +62,26 @@ namespace sgpem
* in concrete derived classes.
* \return String description of the policy.
*/
virtual Glib::ustring get_description() const;
virtual Glib::ustring get_description () const;
/** \brief Returns the policy name
*/
virtual Glib::ustring get_name() const;
virtual Glib::ustring get_name () const;
/** \brief No-op method.
*
* \see ResourcePolicy::activate()
*/
virtual void activate();
virtual void activate ();
/** \brief No-op method.
*
* \see ResourcePolicy::deactivate()
*/
virtual void deactivate();
};
virtual void deactivate ();
};
}//~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -18,20 +18,18 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/resource_policy_manager.hh>
#include <sgpemv2/resource_policies_gatekeeper.hh>
#include <sgpemv2/resource_policy_manager.hh>
using namespace sgpem;
ResourcePolicyManager::ResourcePolicyManager()
ResourcePolicyManager::ResourcePolicyManager ()
{
ResourcePoliciesGatekeeper::get_instance().register_manager(this);
ResourcePoliciesGatekeeper::get_instance ().register_manager (this);
}
ResourcePolicyManager::~ResourcePolicyManager()
ResourcePolicyManager::~ResourcePolicyManager ()
{
ResourcePoliciesGatekeeper::get_instance().unregister_manager(this);
ResourcePoliciesGatekeeper::get_instance ().unregister_manager (this);
}

View File

@ -24,77 +24,76 @@
using namespace sgpem;
ResourcePolicyPriority::~ResourcePolicyPriority()
ResourcePolicyPriority::~ResourcePolicyPriority ()
{
}
void
ResourcePolicyPriority::configure()
ResourcePolicyPriority::configure ()
{
}
void
ResourcePolicyPriority::enforce(Environment& /*environment*/, Environment::SubRequestQueue& queue, SubRequest& sr)
ResourcePolicyPriority::enforce (Environment & /*environment*/, Environment::SubRequestQueue &queue, SubRequest &sr)
{
typedef Environment::SubRequestQueue SubRequestQueue;
typedef Environment::SubRequestQueue SubRequestQueue;
SubRequestQueue old_queue(queue);
queue.clear();
SubRequestQueue old_queue (queue);
queue.clear ();
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
{
// allocated ones remain allocated
if((**i).get_state() == Request::state_allocated)
queue.push_back(*i);
}
int pthis = sr.get_request().get_thread().get_current_priority();
// assume they are ordered by priority.
bool inserted = false;
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
{
// allocated ones remain allocated
if((**i).get_state() != Request::state_allocated)
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
{
// non-allocated ones with lower priority go after the newly arrived
int pthat = (**i).get_request().get_thread().get_current_priority();
if(!inserted && pthis <= pthat)
{
queue.push_back(&sr);
inserted = true;
}
if (*i != &sr)
queue.push_back(*i);
// allocated ones remain allocated
if ((**i).get_state () == Request::state_allocated)
queue.push_back (*i);
}
int pthis = sr.get_request ().get_thread ().get_current_priority ();
// assume they are ordered by priority.
bool inserted = false;
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
{
// allocated ones remain allocated
if ((**i).get_state () != Request::state_allocated)
{
// non-allocated ones with lower priority go after the newly arrived
int pthat = (**i).get_request ().get_thread ().get_current_priority ();
if (!inserted && pthis <= pthat)
{
queue.push_back (&sr);
inserted = true;
}
if (*i != &sr)
queue.push_back (*i);
}
}
}
}
Glib::ustring
ResourcePolicyPriority::get_description() const
ResourcePolicyPriority::get_description () const
{
return _("A resource policy which satisfies higher priority requests before lower priority ones.");
return _ ("A resource policy which satisfies higher priority requests before lower priority ones.");
}
Glib::ustring
ResourcePolicyPriority::get_name() const
ResourcePolicyPriority::get_name () const
{
return _("Higher Priority First");
return _ ("Higher Priority First");
}
void
ResourcePolicyPriority::activate()
ResourcePolicyPriority::activate ()
{
}
void
ResourcePolicyPriority::deactivate()
ResourcePolicyPriority::deactivate ()
{
}

View File

@ -23,36 +23,34 @@
#include "gettext.h"
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/policy_parameters.hh>
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/user_interrupt_exception.hh>
#include <glibmm/ustring.h>
namespace sgpem
{
/// \brief A resource allocation policy which provides a better service
/// to higer priority threads.
///
/// A resource allocation policy which provides a better service
/// to higer priority threads. This policy sorts the request queues
/// following the priority of the owners of the requests.
class ResourcePolicyPriority;
/// \brief A resource allocation policy which provides a better service
/// to higer priority threads.
///
/// A resource allocation policy which provides a better service
/// to higer priority threads. This policy sorts the request queues
/// following the priority of the owners of the requests.
class ResourcePolicyPriority;
class SG_DLLLOCAL ResourcePolicyPriority : public ResourcePolicy
{
public:
class SG_DLLLOCAL ResourcePolicyPriority : public ResourcePolicy
{
public:
/// \brief Standard virtual destructor.
///
/// Standard virtual destructor.
virtual ~ResourcePolicyPriority();
virtual ~ResourcePolicyPriority ();
/// \brief Initializes the inner components of the policy.
///
/// Does nothing.
virtual void configure();
virtual void configure ();
/// \brief Sorts the subrequest queue letting higher priority threads to be the first ones
/// to get the resources.
@ -63,33 +61,33 @@ namespace sgpem
/// \param environment the environment on which the policy applies.
/// \param queue the queue where a subrequest has just been added.
/// \param sr the subrequest which has just been added.
virtual void enforce(Environment& environment, Environment::SubRequestQueue& queue, SubRequest& sr);
virtual void enforce (Environment &environment, Environment::SubRequestQueue &queue, SubRequest &sr);
/// \brief Returns a description of the policy.
///
/// Returns a description of the policy.
/// \return a description of the policy.
virtual Glib::ustring get_description() const;
virtual Glib::ustring get_description () const;
/// \brief Returns the name of the policy.
///
/// Returns the name of the policy.
/// \return the name of the policy.
virtual Glib::ustring get_name() const;
virtual Glib::ustring get_name () const;
/// \brief Activates the policy.
///
/// Does nothing.
virtual void activate();
virtual void activate ();
/// \brief Deactivates the policy.
///
/// Does nothing.
virtual void deactivate();
};
virtual void deactivate ();
};
}//~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -25,88 +25,91 @@
using namespace std;
using namespace sgpem;
ResourcePolicyPriorityInheritance::~ResourcePolicyPriorityInheritance()
{}
ResourcePolicyPriorityInheritance::~ResourcePolicyPriorityInheritance ()
{
}
void
ResourcePolicyPriorityInheritance::configure()
ResourcePolicyPriorityInheritance::configure ()
{
}
void
ResourcePolicyPriorityInheritance::enforce(Environment& /*environment*/, Environment::SubRequestQueue& queue, SubRequest& sr)
ResourcePolicyPriorityInheritance::enforce (Environment & /*environment*/, Environment::SubRequestQueue &queue, SubRequest &sr)
{
typedef Environment::SubRequestQueue SubRequestQueue;
typedef Environment::SubRequestQueue SubRequestQueue;
SubRequestQueue old_queue(queue);
queue.clear();
SubRequestQueue old_queue (queue);
queue.clear ();
// the priority may only rise!
int pmax = sr.get_request().get_thread().get_current_priority();
// the priority may only rise!
int pmax = sr.get_request ().get_thread ().get_current_priority ();
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
{
// determine the max priority
int pthat = (**i).get_request().get_thread().get_current_priority();
if (pthat < pmax)
pmax = pthat;
// allocated ones remain allocated
if((**i).get_state() == Request::state_allocated)
queue.push_back(*i);
}
int pthis = sr.get_request().get_thread().get_current_priority();
// assume they are ordered by priority.
bool inserted = false;
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++)
{
// allocated ones remain allocated
if((**i).get_state() != Request::state_allocated)
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
{
// non-allocated ones with lower priority go after the newly arrived
int pthat = (**i).get_request().get_thread().get_current_priority();
if(!inserted && pthis <= pthat)
{
queue.push_back(&sr);
inserted = true;
}
if (*i != &sr)
queue.push_back(*i);
// determine the max priority
int pthat = (**i).get_request ().get_thread ().get_current_priority ();
if (pthat < pmax)
pmax = pthat;
// allocated ones remain allocated
if ((**i).get_state () == Request::state_allocated)
queue.push_back (*i);
}
else
int pthis = sr.get_request ().get_thread ().get_current_priority ();
// assume they are ordered by priority.
bool inserted = false;
typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin (); i != old_queue.end (); i++)
{
// increase the priority of a the thread to the maximum priority of any process waiting
int push = pmax - (**i).get_request().get_thread().get_current_priority();
(**i).get_request().get_thread().set_priority_push(push);
// allocated ones remain allocated
if ((**i).get_state () != Request::state_allocated)
{
// non-allocated ones with lower priority go after the newly arrived
int pthat = (**i).get_request ().get_thread ().get_current_priority ();
if (!inserted && pthis <= pthat)
{
queue.push_back (&sr);
inserted = true;
}
if (*i != &sr)
queue.push_back (*i);
}
else
{
// increase the priority of a the thread to the maximum priority of any process waiting
int push = pmax - (**i).get_request ().get_thread ().get_current_priority ();
(**i).get_request ().get_thread ().set_priority_push (push);
}
}
}
}
Glib::ustring
ResourcePolicyPriorityInheritance::get_description() const
ResourcePolicyPriorityInheritance::get_description () const
{
return _("A resource policy which solves the priority inversion problem by raising the priority of a thread to the maximum relative to the queue.");
return _ (
"A resource policy which solves the priority inversion problem by raising the priority of a thread to the "
"maximum relative to the queue.");
}
Glib::ustring
ResourcePolicyPriorityInheritance::get_name() const
ResourcePolicyPriorityInheritance::get_name () const
{
return _("Basic Priority Inheritance Protocol");
return _ ("Basic Priority Inheritance Protocol");
}
void
ResourcePolicyPriorityInheritance::activate()
ResourcePolicyPriorityInheritance::activate ()
{
}
void
ResourcePolicyPriorityInheritance::deactivate()
ResourcePolicyPriorityInheritance::deactivate ()
{
}

View File

@ -23,25 +23,24 @@
namespace sgpem
{
class ResourcePolicyPriorityInheritance;
class ResourcePolicyPriorityInheritance;
}
#include <sgpemv2/resource_policy.hh>
namespace sgpem
{
/**
/**
* \brief It's a Strategy wich stay for a resource allocating algorithm.
* It implements the related resource allocation policy.
*/
class SG_DLLLOCAL ResourcePolicyPriorityInheritance : public ResourcePolicy
{
public:
class SG_DLLLOCAL ResourcePolicyPriorityInheritance : public ResourcePolicy
{
public:
/// \brief Standard virtual destructor.
///
/// Standard virtual destructor.
virtual ~ResourcePolicyPriorityInheritance();
virtual ~ResourcePolicyPriorityInheritance ();
/**
\brief Initialize the inner components of the policy.
@ -49,7 +48,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented
in concrete derived classes.
*/
virtual void configure();
virtual void configure ();
/**
\brief Mixes the queues.
@ -57,9 +56,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented
in concrete derived classes.
*/
virtual void enforce(Environment& environment,
Environment::SubRequestQueue& queue,
SubRequest& sr);
virtual void enforce (Environment &environment, Environment::SubRequestQueue &queue, SubRequest &sr);
/**
\brief Gets a string description of the policy.
@ -68,16 +65,16 @@ namespace sgpem
in concrete derived classes.
\return String description of the policy.
*/
virtual Glib::ustring get_description() const;
virtual Glib::ustring get_description () const;
virtual Glib::ustring get_name() const;
virtual Glib::ustring get_name () const;
virtual void activate();
virtual void activate ();
virtual void deactivate();
};
virtual void deactivate ();
};
}//~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -24,16 +24,19 @@
using namespace sgpem;
Schedulable::~Schedulable()
{}
unsigned int Schedulable::get_remaining_time() const
Schedulable::~Schedulable ()
{
assert(get_total_cpu_time() >= get_elapsed_time());
return get_total_cpu_time() - get_elapsed_time();
}
int Schedulable::get_priority_push() const
unsigned int
Schedulable::get_remaining_time () const
{
return get_current_priority() - get_base_priority();
assert (get_total_cpu_time () >= get_elapsed_time ());
return get_total_cpu_time () - get_elapsed_time ();
}
int
Schedulable::get_priority_push () const
{
return get_current_priority () - get_base_priority ();
}

View File

@ -22,11 +22,10 @@
using namespace sgpem;
SchedulableStatistics::SchedulableStatistics()
SchedulableStatistics::SchedulableStatistics ()
{
}
SchedulableStatistics::~SchedulableStatistics()
SchedulableStatistics::~SchedulableStatistics ()
{
}

View File

@ -18,7 +18,6 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
/*
// DISCLAIMER FOR THE RAMPANT CODER: \\
// ----------------------------------------------------\\
@ -36,8 +35,8 @@
#include <sgpemv2/scheduler.hh>
// Do not include full template definition in the header file
#include <sgpemv2/templates/singleton.tcc>
#include <sgpemv2/templates/sequences.tcc>
#include <sgpemv2/templates/singleton.tcc>
#include <glibmm/thread.h>
@ -52,81 +51,78 @@ using namespace sgpem;
template class sgpem::Singleton<Scheduler>;
typedef std::vector<DynamicProcess*> Processes;
typedef std::vector<DynamicRequest*> Requests;
typedef std::vector<DynamicSubRequest*> SubRequests;
typedef std::vector<DynamicThread*> Threads;
typedef Environment::Resources Resources;
typedef Environment::SubRequestQueue SubRequestQueue;
typedef std::vector<DynamicProcess *> Processes;
typedef std::vector<DynamicRequest *> Requests;
typedef std::vector<DynamicSubRequest *> SubRequests;
typedef std::vector<DynamicThread *> Threads;
typedef Environment::Resources Resources;
typedef Environment::SubRequestQueue SubRequestQueue;
// ------------------ Static helper functions --------------
inline bool is_running(const Thread* running_thread);
static void collect_threads(const std::vector<Process*>& procs, Threads& collected_threads);
static void prepare_ready_queue(ConcreteEnvironment& snapshot, const Threads& all_threads);
static void terminate_all_requests_of(DynamicThread& thread, ConcreteEnvironment& environment);
static void update_allocated_requests(DynamicThread& running_thread, ConcreteEnvironment& environment);
static void raise_new_requests(DynamicThread& running_thread, ConcreteEnvironment& environment, ResourcePolicy& resource_policy);
static void look_for_mutant_request_states(ConcreteEnvironment& environment, unsigned int& alive_threads);
static void determine_subr_allocable_status(const Resource& res, const SubRequestQueue& queue);
inline bool is_running (const Thread *running_thread);
static void collect_threads (const std::vector<Process *> &procs, Threads &collected_threads);
static void prepare_ready_queue (ConcreteEnvironment &snapshot, const Threads &all_threads);
static void terminate_all_requests_of (DynamicThread &thread, ConcreteEnvironment &environment);
static void update_allocated_requests (DynamicThread &running_thread, ConcreteEnvironment &environment);
static void raise_new_requests (DynamicThread &running_thread, ConcreteEnvironment &environment, ResourcePolicy &resource_policy);
static void look_for_mutant_request_states (ConcreteEnvironment &environment, unsigned int &alive_threads);
static void determine_subr_allocable_status (const Resource &res, const SubRequestQueue &queue);
// ---------------------------------------------------------
bool
is_running(const Thread* running_thread)
is_running (const Thread *running_thread)
{
return running_thread != nullptr && running_thread->get_state() == Schedulable::state_running;
return running_thread != nullptr && running_thread->get_state () == Schedulable::state_running;
}
// Collects all threads of an environment into a single vector
void
collect_threads(const std::vector<Process*>& procs,
Threads& collected_threads)
collect_threads (const std::vector<Process *> &procs, Threads &collected_threads)
{
collected_threads.clear();
for (Iseq<vector<Process*>::const_iterator> seq = iseq(procs); seq; ++seq)
{
const Threads& ts = ((DynamicProcess&) **seq).get_dynamic_threads();
collected_threads.insert(collected_threads.end(), ts.begin(), ts.end());
}
collected_threads.clear ();
for (Iseq<vector<Process *>::const_iterator> seq = iseq (procs); seq; ++seq)
{
const Threads &ts = ((DynamicProcess &) **seq).get_dynamic_threads ();
collected_threads.insert (collected_threads.end (), ts.begin (), ts.end ());
}
}
void
prepare_ready_queue(ConcreteEnvironment& snapshot,
const Threads& all_threads)
prepare_ready_queue (ConcreteEnvironment &snapshot, const Threads &all_threads)
{
ReadyQueue& queue = snapshot.get_sorted_queue();
assert(queue.size() == 0);
for (Iseq<Threads::const_iterator> seq = iseq(all_threads); seq; ++seq)
{
if ((*seq)->get_state() == Schedulable::state_ready)
queue.append(**seq);
}
ReadyQueue &queue = snapshot.get_sorted_queue ();
assert (queue.size () == 0);
for (Iseq<Threads::const_iterator> seq = iseq (all_threads); seq; ++seq)
{
if ((*seq)->get_state () == Schedulable::state_ready)
queue.append (**seq);
}
}
// When a thread terminates, unconditionally kill all its requests
void
terminate_all_requests_of(DynamicThread& thread,
ConcreteEnvironment& environment)
terminate_all_requests_of (DynamicThread &thread, ConcreteEnvironment &environment)
{
Requests& reqs = thread.get_dynamic_requests();
for (Iseq<Requests::iterator> r_it = iseq(reqs); r_it; ++r_it)
Requests &reqs = thread.get_dynamic_requests ();
for (Iseq<Requests::iterator> r_it = iseq (reqs); r_it; ++r_it)
{
SubRequests& subreqs = (*r_it)->get_dynamic_subrequests();
for (Iseq<SubRequests::iterator> s_it = iseq(subreqs); s_it; ++s_it)
SubRequests &subreqs = (*r_it)->get_dynamic_subrequests ();
for (Iseq<SubRequests::iterator> s_it = iseq (subreqs); s_it; ++s_it)
{
(*s_it)->set_state(Request::state_exhausted);
Environment::resource_key_t rkey = (*s_it)->get_resource_key();
SubRequestQueue& queue = environment.get_request_queue(rkey);
SubRequestQueue::iterator removable = find(queue.begin(), queue.end(), *s_it);
if(removable != queue.end()) queue.erase(removable);
(*s_it)->set_state (Request::state_exhausted);
Environment::resource_key_t rkey = (*s_it)->get_resource_key ();
SubRequestQueue &queue = environment.get_request_queue (rkey);
SubRequestQueue::iterator removable = find (queue.begin (), queue.end (), *s_it);
if (removable != queue.end ())
queue.erase (removable);
}
}
}
@ -134,31 +130,31 @@ terminate_all_requests_of(DynamicThread& thread,
// For the current thread, see if there are requests that are exhausted
void
update_allocated_requests(DynamicThread& running_thread,
ConcreteEnvironment& environment)
update_allocated_requests (DynamicThread &running_thread, ConcreteEnvironment &environment)
{
// Go for all dynamic requests of this thread
Requests& reqs = running_thread.get_dynamic_requests();
for (Iseq<Requests::iterator> req_it = iseq(reqs); req_it; ++req_it)
{
SubRequests& cur_request = (*req_it)->get_dynamic_subrequests();
for (Iseq<SubRequests::iterator> subr_it = iseq(cur_request); subr_it; ++subr_it)
{
DynamicSubRequest& cur_subr = **subr_it;
if(cur_subr.get_state() == Request::state_allocated)
{
cur_subr.decrease_remaining_time();
if(cur_subr.get_remaining_time() == 0)
{
cur_subr.set_state(Request::state_exhausted);
Environment::resource_key_t rkey = cur_subr.get_resource_key();
SubRequestQueue& queue = environment.get_request_queue(rkey);
SubRequestQueue::iterator removable = find(queue.begin(), queue.end(), &cur_subr);
if(removable != queue.end()) queue.erase(removable);
}
}
} //~ for(over subrequests)
} //~ for(over requests)
// Go for all dynamic requests of this thread
Requests &reqs = running_thread.get_dynamic_requests ();
for (Iseq<Requests::iterator> req_it = iseq (reqs); req_it; ++req_it)
{
SubRequests &cur_request = (*req_it)->get_dynamic_subrequests ();
for (Iseq<SubRequests::iterator> subr_it = iseq (cur_request); subr_it; ++subr_it)
{
DynamicSubRequest &cur_subr = **subr_it;
if (cur_subr.get_state () == Request::state_allocated)
{
cur_subr.decrease_remaining_time ();
if (cur_subr.get_remaining_time () == 0)
{
cur_subr.set_state (Request::state_exhausted);
Environment::resource_key_t rkey = cur_subr.get_resource_key ();
SubRequestQueue &queue = environment.get_request_queue (rkey);
SubRequestQueue::iterator removable = find (queue.begin (), queue.end (), &cur_subr);
if (removable != queue.end ())
queue.erase (removable);
}
}
} //~ for(over subrequests)
} //~ for(over requests)
}
@ -169,72 +165,70 @@ update_allocated_requests(DynamicThread& running_thread,
// Remember that a thread may run only if all of its requests are either FUTURE,
// ALLOCATED or EXHAUSTED.
void
raise_new_requests(DynamicThread& running_thread, ConcreteEnvironment& environment, ResourcePolicy& resource_policy)
raise_new_requests (DynamicThread &running_thread, ConcreteEnvironment &environment, ResourcePolicy &resource_policy)
{
// Go for all dynamic requests of this thread
Requests& reqs = running_thread.get_dynamic_requests();
for (Iseq<Requests::iterator> req_it = iseq(reqs); req_it; ++req_it)
{
DynamicRequest& cur_req = **req_it;
SubRequests& subreqs = (*req_it)->get_dynamic_subrequests();
// Go for all dynamic requests of this thread
Requests &reqs = running_thread.get_dynamic_requests ();
for (Iseq<Requests::iterator> req_it = iseq (reqs); req_it; ++req_it)
{
DynamicRequest &cur_req = **req_it;
SubRequests &subreqs = (*req_it)->get_dynamic_subrequests ();
// Add to the queue only requests passing from future to another state:
if(cur_req.get_state() == Request::state_future &&
cur_req.get_instant() == running_thread.get_elapsed_time())
{
for (Iseq<SubRequests::iterator> subr_it = iseq(subreqs); subr_it; ++subr_it)
{
// Do the proper adding:
DynamicSubRequest& cur_subr = **subr_it;
Environment::resource_key_t rkey = cur_subr.get_resource_key();
SubRequestQueue& queue = environment.get_request_queue(rkey);
queue.push_back(&cur_subr);
// Add to the queue only requests passing from future to another state:
if (cur_req.get_state () == Request::state_future && cur_req.get_instant () == running_thread.get_elapsed_time ())
{
for (Iseq<SubRequests::iterator> subr_it = iseq (subreqs); subr_it; ++subr_it)
{
// Do the proper adding:
DynamicSubRequest &cur_subr = **subr_it;
Environment::resource_key_t rkey = cur_subr.get_resource_key ();
SubRequestQueue &queue = environment.get_request_queue (rkey);
queue.push_back (&cur_subr);
/// TODO: right here, right now we should call the resource policy to
/// update the queue. Updates the state of the subrequest depending
/// on the position in the queue, as explained before.
resource_policy.enforce(environment, queue, cur_subr);
/// TODO: right here, right now we should call the resource policy to
/// update the queue. Updates the state of the subrequest depending
/// on the position in the queue, as explained before.
resource_policy.enforce (environment, queue, cur_subr);
// Get the number of places for the corresponding resource
Resource& resource = *environment.get_resources().find(rkey)->second;
// Get the number of places for the corresponding resource
Resource &resource = *environment.get_resources ().find (rkey)->second;
// WARNING: adding a new request may require updating the status of ALL other
// requests in the queue
determine_subr_allocable_status(resource, queue);
// WARNING: adding a new request may require updating the status of ALL other
// requests in the queue
determine_subr_allocable_status (resource, queue);
// after that, check if it is globally allocable.
// See if the subrequest is allocable or unallocable, and set its state.
// It's important that the subrequest has already been added to the queue.
// determine_subr_allocable_status(cur_req, cur_subr, resource, queue);
// after that, check if it is globally allocable.
// See if the subrequest is allocable or unallocable, and set its state.
// It's important that the subrequest has already been added to the queue.
// determine_subr_allocable_status(cur_req, cur_subr, resource, queue);
} //~ for(over subrequests)
} //~ if(request is future and is time to allocate it)
} //~ for(over subrequests)
} //~ if(request is future and is time to allocate it)
// A request may be ALLOCATED only when it is ALLOCABLE, i.e. when all its subrequests
// are ALLOCABLE. A request is allocated when all its subrequests are either TERMINATED
// A request may be ALLOCATED only when it is ALLOCABLE, i.e. when all its subrequests
// are ALLOCABLE. A request is allocated when all its subrequests are either TERMINATED
// or ALLOCATED, but at least one is ALLOCATED.
// Now, since the thread is willing to run, we must allocate the request if possible.
// All requests we treat are at the moment non-preemptable, so it is not permitted to temporarily
// preempt a resource to a thread to free a place and potentially allow one other thread
// to use that place. This is why we need to allocate requests (which means allocating
// resources to threads).
// resources to threads).
// If it is actually allocable, allocate it
switch(cur_req.get_state())
{
case Request::state_allocable:
// If it is actually allocable, allocate it
switch (cur_req.get_state ())
{
const SubRequests& const_subreqs = subreqs;
for(Iseq<SubRequests::const_iterator> it_dsrs = iseq(const_subreqs); it_dsrs; ++it_dsrs)
case Request::state_allocable:
{
const SubRequests &const_subreqs = subreqs;
for (Iseq<SubRequests::const_iterator> it_dsrs = iseq (const_subreqs); it_dsrs; ++it_dsrs)
{
DynamicSubRequest& subreq = **it_dsrs;
assert(subreq.get_state() == Request::state_allocable);
/*
DynamicSubRequest &subreq = **it_dsrs;
assert (subreq.get_state () == Request::state_allocable);
/*
// Move this request up the queue, to the back of the allocated
// subrequests. This is mainly for display. :-)
// The rest of the queue sorting business is up to the resource policy.
@ -248,45 +242,44 @@ raise_new_requests(DynamicThread& running_thread, ConcreteEnvironment& environme
assert(this_subreq != queue.end());
swap(*alloc_it, *this_subreq);
*/
subreq.set_state(Request::state_allocated);
subreq.set_state (Request::state_allocated);
}
}
break;
case Request::state_unallocable:
// If it does exist at least one unallocable request, the thread may not run!
running_thread.set_state(Schedulable::state_blocked);
break;
case Request::state_unallocable:
// If it does exist at least one unallocable request, the thread may not run!
running_thread.set_state (Schedulable::state_blocked);
break;
default:
break;
}//~ switch(request state)
default:
break;
} //~ switch(request state)
} //~ for(over requests)
} //~ for(over requests)
}
// The following loop updates the states of the subrequests depending
// on their position in the queue
void
determine_subr_allocable_status(const Resource& res, const SubRequestQueue& queue)
determine_subr_allocable_status (const Resource &res, const SubRequestQueue &queue)
{
unsigned int total_places = res.get_places();
unsigned int position_in_queue = 0;
for(Iseq<SubRequestQueue::const_iterator> queue_it = iseq(queue);
queue_it; queue_it++, position_in_queue++)
unsigned int total_places = res.get_places ();
unsigned int position_in_queue = 0;
for (Iseq<SubRequestQueue::const_iterator> queue_it = iseq (queue); queue_it; queue_it++, position_in_queue++)
{
DynamicSubRequest& sr = (DynamicSubRequest&) **queue_it;
if (sr.get_state() == Request::state_allocated)
continue;
if(position_in_queue + 1 > total_places)
DynamicSubRequest &sr = (DynamicSubRequest &) **queue_it;
if (sr.get_state () == Request::state_allocated)
continue;
if (position_in_queue + 1 > total_places)
{
sr.set_state(Request::state_unallocable);
// Kludge:
sr.get_request().get_thread().set_state(Schedulable::state_blocked);
sr.set_state (Request::state_unallocable);
// Kludge:
sr.get_request ().get_thread ().set_state (Schedulable::state_blocked);
}
else
sr.set_state(Request::state_allocable);
else
sr.set_state (Request::state_allocable);
} //~ for(over subrequest queue)
}
@ -295,148 +288,142 @@ determine_subr_allocable_status(const Resource& res, const SubRequestQueue& queu
// step of the simulation. It also put previously blocked threads
// back into ready state if need arises.
void
look_for_mutant_request_states(ConcreteEnvironment& environment,
unsigned int& alive_threads)
look_for_mutant_request_states (ConcreteEnvironment &environment, unsigned int &alive_threads)
{
// Now listening to: Testament's ``First Strike Is Still Deadly''
// The name of this function evokes mighty monsters from the abyss. In
// fact, it's what it actually does (okay, okay, pull the other one,
// it's got brass bells on).
// Now listening to: Testament's ``First Strike Is Still Deadly''
// The name of this function evokes mighty monsters from the abyss. In
// fact, it's what it actually does (okay, okay, pull the other one,
// it's got brass bells on).
// We start assuming that SubRequestsQueues are up-to-date
Resources& resources = environment.get_resources();
for(Iseq<Resources::iterator> res_it = iseq(resources); res_it; ++res_it)
// We start assuming that SubRequestsQueues are up-to-date
Resources &resources = environment.get_resources ();
for (Iseq<Resources::iterator> res_it = iseq (resources); res_it; ++res_it)
{
Environment::resource_key_t rkey = res_it->first;
SubRequestQueue& queue = environment.get_request_queue(rkey);
Environment::resource_key_t rkey = res_it->first;
SubRequestQueue &queue = environment.get_request_queue (rkey);
unsigned int queue_pos = 0;
for(Iseq<SubRequestQueue::iterator> subr_it = iseq(queue); subr_it; ++subr_it, ++queue_pos)
unsigned int queue_pos = 0;
for (Iseq<SubRequestQueue::iterator> subr_it = iseq (queue); subr_it; ++subr_it, ++queue_pos)
{
DynamicSubRequest& subr = (DynamicSubRequest&) **subr_it;
DynamicRequest& req = subr.get_request();
Request::state prev_req_state = req.get_state();
DynamicSubRequest &subr = (DynamicSubRequest &) **subr_it;
DynamicRequest &req = subr.get_request ();
Request::state prev_req_state = req.get_state ();
// If a request is already allocated, we don't have to touch it!
if(prev_req_state == Request::state_allocated)
continue;
// If a request is already allocated, we don't have to touch it!
if (prev_req_state == Request::state_allocated)
continue;
// Update the state of the subrequest, either from allocable to
// unallocable or vice-versa
// determine_subr_allocable_status(req, subr, *res_it->second, queue);
determine_subr_allocable_status(*res_it->second, queue);
// Update the state of the subrequest, either from allocable to
// unallocable or vice-versa
// determine_subr_allocable_status(req, subr, *res_it->second, queue);
determine_subr_allocable_status (*res_it->second, queue);
// TODO: The following is a moderately expensive operation
// to do here. See if we can move it somewhere else.
// TODO: The following is a moderately expensive operation
// to do here. See if we can move it somewhere else.
// If a request changes state from allocable to unallocable,
// the corresponding thread should be blocked, and vice-versa
DynamicThread& thread = req.get_thread();
if(prev_req_state == Request::state_allocable &&
req.get_state() == Request::state_unallocable)
// If a request changes state from allocable to unallocable,
// the corresponding thread should be blocked, and vice-versa
DynamicThread &thread = req.get_thread ();
if (prev_req_state == Request::state_allocable && req.get_state () == Request::state_unallocable)
{
if(thread.get_state() != Schedulable::state_blocked)
alive_threads--;
thread.set_state(Schedulable::state_blocked);
if (thread.get_state () != Schedulable::state_blocked)
alive_threads--;
thread.set_state (Schedulable::state_blocked);
}
else if(prev_req_state == Request::state_unallocable &&
req.get_state() == Request::state_allocable)
else if (prev_req_state == Request::state_unallocable && req.get_state () == Request::state_allocable)
{
if(thread.get_state() == Schedulable::state_blocked)
alive_threads++;
thread.set_state(Schedulable::state_ready);
if (thread.get_state () == Schedulable::state_blocked)
alive_threads++;
thread.set_state (Schedulable::state_ready);
}
} //~ for(over subrequests in the queue)
} //~ for(over resources)
}
// ---------------------------------------------------------
//private constructor.
Scheduler::Scheduler()
: _ready_queue(NULL), _policy(NULL), _step_mutex()
{}
ReadyQueue*
Scheduler::get_ready_queue()
Scheduler::Scheduler () : _ready_queue (NULL), _policy (NULL), _step_mutex ()
{
return _ready_queue;
}
CPUPolicy*
Scheduler::get_policy()
ReadyQueue *
Scheduler::get_ready_queue ()
{
return _policy;
return _ready_queue;
}
CPUPolicy *
Scheduler::get_policy ()
{
return _policy;
}
bool
Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy& resource_policy)
Scheduler::step_forward (History &history, CPUPolicy &cpu_policy, ResourcePolicy &resource_policy)
{
// This very method should be exclusive: no concurrent behaviour, from when we
// store a readyqueue and policy pointer for the user-policy to retrieve, to when
// the policy returns
Glib::Mutex::Lock lock (_step_mutex);
// This very method should be exclusive: no concurrent behaviour, from when we
// store a readyqueue and policy pointer for the user-policy to retrieve, to when
// the policy returns
Glib::Mutex::Lock lock (_step_mutex);
// NOTE: Be sure to read the *ORIGINAL* documentation in the design document for this method!
// NOTE: Be sure to read the *ORIGINAL* documentation in the design document for this method!
unsigned int alive_threads = 0; // Assume we've finished. Then prove me wrong.
int current_instant = history.get_size() - 1; /* They should be equivalent */
unsigned int alive_threads = 0; // Assume we've finished. Then prove me wrong.
int current_instant = history.get_size () - 1; /* They should be equivalent */
// Safe cast:
ConcreteHistory& concrete_history = static_cast<ConcreteHistory&>(history);
// Safe cast:
ConcreteHistory &concrete_history = static_cast<ConcreteHistory &> (history);
// Use an auto_ptr since we've some exceptions in the coming...
unique_ptr<ConcreteEnvironment> new_snapshot(new ConcreteEnvironment(concrete_history.get_environment_at(current_instant)));
// Use an auto_ptr since we've some exceptions in the coming...
unique_ptr<ConcreteEnvironment> new_snapshot (new ConcreteEnvironment (concrete_history.get_environment_at (current_instant)));
Threads all_threads;
DynamicThread* running_thread = nullptr;
Threads all_threads;
DynamicThread *running_thread = nullptr;
collect_threads(new_snapshot->get_processes(), all_threads);
collect_threads (new_snapshot->get_processes (), all_threads);
// The first thing we've to do is to update the state of the old
// running thread, if there's one.
for (Iseq<Threads::iterator> it = iseq(all_threads); it; ++it)
// The first thing we've to do is to update the state of the old
// running thread, if there's one.
for (Iseq<Threads::iterator> it = iseq (all_threads); it; ++it)
{
DynamicThread &current = **it;
// Save the current running thread for future usage, if it hasn't ended
// its allotted time
if (current.get_state () == Schedulable::state_running)
{
DynamicThread& current = **it;
running_thread = &current; // Even if we can change its state to terminate
// Save the current running thread for future usage, if it hasn't ended
// its allotted time
if (current.get_state() == Schedulable::state_running)
{
running_thread = &current; // Even if we can change its state to terminate
// increasing the time elapsed of the running thread + process
// should be done here as the first thing, instead than
// directly after selecting them
if (current.get_total_cpu_time () - current.get_elapsed_time () > 0)
current.decrease_remaining_time ();
// increasing the time elapsed of the running thread + process
// should be done here as the first thing, instead than
// directly after selecting them
if (current.get_total_cpu_time() - current.get_elapsed_time() > 0)
current.decrease_remaining_time();
// 4a. Look for exhausted requests for the running thread
update_allocated_requests (current, *new_snapshot);
// 4a. Look for exhausted requests for the running thread
update_allocated_requests(current, *new_snapshot);
// 2. mark threads that used all their allotted time as terminated,
// and put their requests as exhausted
if (current.get_total_cpu_time() - current.get_elapsed_time() == 0)
// 2. mark threads that used all their allotted time as terminated,
// and put their requests as exhausted
if (current.get_total_cpu_time () - current.get_elapsed_time () == 0)
{
current.set_state(Schedulable::state_terminated);
current.set_last_release(current_instant);
terminate_all_requests_of(current, *new_snapshot);
running_thread = nullptr;
current.set_state (Schedulable::state_terminated);
current.set_last_release (current_instant);
terminate_all_requests_of (current, *new_snapshot);
running_thread = nullptr;
}
// if we found the running thread, there isn't another one,
// so we can safely exit the for loop.
break;
// if we found the running thread, there isn't another one,
// so we can safely exit the for loop.
break;
} //~ if state == running
} //~ for over all threads
@ -444,184 +431,184 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
// When a new instant cames, we could have to update the state of future
// threads to make them ready. We also keep a count of alive threads
for (Iseq<Threads::iterator> it = iseq(all_threads); it; ++it)
for (Iseq<Threads::iterator> it = iseq (all_threads); it; ++it)
{
DynamicThread &current = **it;
// 1. mark future threads as ready, if appropriate
if (current.get_state () == Schedulable::state_future)
{
DynamicThread& current = **it;
Process &parent = current.get_process ();
if ((long) parent.get_arrival_time () <= current_instant && parent.get_elapsed_time () == current.get_arrival_time ())
current.set_state (Schedulable::state_ready);
}
// 1. mark future threads as ready, if appropriate
if (current.get_state() == Schedulable::state_future)
{
Process& parent = current.get_process();
if ((long) parent.get_arrival_time() <= current_instant &&
parent.get_elapsed_time() == current.get_arrival_time())
current.set_state(Schedulable::state_ready);
}
// 3. check for simulation termination (we can directly use threads
// for this check, since processes' state is based upon threads' one)
Schedulable::state cur_state = current.get_state();
if ((cur_state & (Schedulable::state_blocked | Schedulable::state_terminated)) == 0 &&
(current.get_process().get_state() & (Schedulable::state_terminated | Schedulable::state_blocked)) == 0) // check for holes
{
alive_threads++;
}
} //~ for over all_threads
// ?. Time to see if some unallocable request became allocable, so
// the thread can pass from blocked to ready state, or the other way
// round
look_for_mutant_request_states(*new_snapshot, alive_threads);
// Now if the simulation ended we append the newly
// created environment and return false
if (alive_threads == 0) goto final_cleanup;
// Use the CPU Policy to sort the ready queue, and manage
// requests for the newly selected running thread
try
{
// Temporarily set the _ready_queue param and the _policy one for
// use from external plugins. In fact, this is how get_ready_queue()
// acts as a callback function.
_policy = &cpu_policy;
_ready_queue = &new_snapshot->get_sorted_queue();
// Determine if the policy is pre_emptive, and what time slice it uses
bool preemptive_policy = cpu_policy.is_pre_emptive();
int time_slice = cpu_policy.get_time_slice();
// ?. See if old running_thread has to be put to ready state
// This happens when a time slice ends
if (is_running(running_thread) && time_slice > 0 &&
// A process can be preempted every n-th time-slice, so we use the modulo operator:
(current_instant - running_thread->get_last_acquisition()) % time_slice == 0)
{
running_thread->set_state(Schedulable::state_ready);
running_thread->set_last_release(current_instant);
}
prepare_ready_queue(*new_snapshot, all_threads);
// If the policy is preemptible, and we still have a running thread,
// add it to the queue.
if(preemptive_policy && is_running(running_thread))
_ready_queue->append(*running_thread);
// ?. Ask the policy to sort the queue. If we must select
// a new thread and it can't run for some reason (it goes blocked, or
// terminates), then we remove it from the built ReadyQueue and
// check if the next one can run (see while loop further below).
if(_ready_queue->size() > 0) cpu_policy.sort_queue();
// If we don't have to select a new running thread, because the old one didn't
// have to release the CPU, our work may end here:
// * if the current running thread doesn't block, we can perform the final cleanup,
// since the queue is already sorted
// * else we've to select another running thread, so we continue down in the method
if( // Non-preemptive policy, not ended time-slice:
(!preemptive_policy && is_running(running_thread)) ||
// Pre-emptive policy, running thread still the first of the queue.
// Note: if is_running(running_thread) == true, then _ready_queue->size() > 0
(preemptive_policy && is_running(running_thread) && &_ready_queue->get_item_at(0) == running_thread) )
{
raise_new_requests(*running_thread, *new_snapshot, resource_policy);
if(running_thread->get_state() != Schedulable::state_blocked)
goto final_cleanup;
else
{
running_thread->set_last_release(current_instant);
_ready_queue->erase_first();
running_thread = nullptr;
alive_threads--;
// Proceed to select a new running thread, below
}
}
bool we_ve_got_a_winner = false;
while(_ready_queue->size() > 0 && !we_ve_got_a_winner) // No sense in trying to schedule something that isn't there
{
// Else, it's time to see if the first candidate can run
DynamicThread& candidate = (DynamicThread&) _ready_queue->get_item_at(0);
// If a thread has been created with duration "0" (silly, but possible);
// if you think it's safe, you can change this condition with an assert
// and delete the body of the ``if''.
if(candidate.get_total_cpu_time() - candidate.get_elapsed_time() == 0)
{
candidate.set_last_acquisition(current_instant);
candidate.set_last_release(current_instant);
candidate.set_state(Schedulable::state_terminated);
// Put every request of this thread to state_exhausted
terminate_all_requests_of(candidate, *new_snapshot);
_ready_queue->erase_first();
alive_threads--;
continue;
}
// Now we check if our candidate blocks on a new request
raise_new_requests(candidate, *new_snapshot, resource_policy);
if(candidate.get_state() != Schedulable::state_blocked)
// If we got here, our candidate can run
we_ve_got_a_winner /*!hurrah!*/ = true;
else // if blocked, we've to remove it from the ready queue
{
_ready_queue->erase_first();
alive_threads--;
}
}
// ?. Finally select the new thread (if appropriate); now we're sure
// the one we have can run
if (we_ve_got_a_winner)
{
// Fix fields of running thread
DynamicThread& new_running = (DynamicThread&) _ready_queue->get_item_at(0);
_ready_queue->erase_first();
new_running.set_state(Schedulable::state_running);
// If the new running is different from the old one,
// remember to release our old pal, and to acquire our
// new runner.
if(&new_running != running_thread)
// 3. check for simulation termination (we can directly use threads
// for this check, since processes' state is based upon threads' one)
Schedulable::state cur_state = current.get_state ();
if ((cur_state & (Schedulable::state_blocked | Schedulable::state_terminated)) == 0 &&
(current.get_process ().get_state () & (Schedulable::state_terminated | Schedulable::state_blocked)) == 0) // check for holes
{
if(running_thread != nullptr)
alive_threads++;
}
} //~ for over all_threads
// ?. Time to see if some unallocable request became allocable, so
// the thread can pass from blocked to ready state, or the other way
// round
look_for_mutant_request_states (*new_snapshot, alive_threads);
// Now if the simulation ended we append the newly
// created environment and return false
if (alive_threads == 0)
goto final_cleanup;
// Use the CPU Policy to sort the ready queue, and manage
// requests for the newly selected running thread
try
{
// Temporarily set the _ready_queue param and the _policy one for
// use from external plugins. In fact, this is how get_ready_queue()
// acts as a callback function.
_policy = &cpu_policy;
_ready_queue = &new_snapshot->get_sorted_queue ();
// Determine if the policy is pre_emptive, and what time slice it uses
bool preemptive_policy = cpu_policy.is_pre_emptive ();
int time_slice = cpu_policy.get_time_slice ();
// ?. See if old running_thread has to be put to ready state
// This happens when a time slice ends
if (is_running (running_thread) && time_slice > 0 &&
// A process can be preempted every n-th time-slice, so we use the modulo operator:
(current_instant - running_thread->get_last_acquisition ()) % time_slice == 0)
{
running_thread->set_state (Schedulable::state_ready);
running_thread->set_last_release (current_instant);
}
prepare_ready_queue (*new_snapshot, all_threads);
// If the policy is preemptible, and we still have a running thread,
// add it to the queue.
if (preemptive_policy && is_running (running_thread))
_ready_queue->append (*running_thread);
// ?. Ask the policy to sort the queue. If we must select
// a new thread and it can't run for some reason (it goes blocked, or
// terminates), then we remove it from the built ReadyQueue and
// check if the next one can run (see while loop further below).
if (_ready_queue->size () > 0)
cpu_policy.sort_queue ();
// If we don't have to select a new running thread, because the old one didn't
// have to release the CPU, our work may end here:
// * if the current running thread doesn't block, we can perform the final cleanup,
// since the queue is already sorted
// * else we've to select another running thread, so we continue down in the method
if ( // Non-preemptive policy, not ended time-slice:
(!preemptive_policy && is_running (running_thread)) ||
// Pre-emptive policy, running thread still the first of the queue.
// Note: if is_running(running_thread) == true, then _ready_queue->size() > 0
(preemptive_policy && is_running (running_thread) && &_ready_queue->get_item_at (0) == running_thread))
{
raise_new_requests (*running_thread, *new_snapshot, resource_policy);
if (running_thread->get_state () != Schedulable::state_blocked)
goto final_cleanup;
else
{
running_thread->set_state(Schedulable::state_ready);
running_thread->set_last_release(current_instant);
running_thread->set_last_release (current_instant);
_ready_queue->erase_first ();
running_thread = nullptr;
alive_threads--;
// Proceed to select a new running thread, below
}
}
bool we_ve_got_a_winner = false;
while (_ready_queue->size () > 0 && !we_ve_got_a_winner) // No sense in trying to schedule something that isn't there
{
// Else, it's time to see if the first candidate can run
DynamicThread &candidate = (DynamicThread &) _ready_queue->get_item_at (0);
// If a thread has been created with duration "0" (silly, but possible);
// if you think it's safe, you can change this condition with an assert
// and delete the body of the ``if''.
if (candidate.get_total_cpu_time () - candidate.get_elapsed_time () == 0)
{
candidate.set_last_acquisition (current_instant);
candidate.set_last_release (current_instant);
candidate.set_state (Schedulable::state_terminated);
// Put every request of this thread to state_exhausted
terminate_all_requests_of (candidate, *new_snapshot);
_ready_queue->erase_first ();
alive_threads--;
continue;
}
// Now we check if our candidate blocks on a new request
raise_new_requests (candidate, *new_snapshot, resource_policy);
if (candidate.get_state () != Schedulable::state_blocked)
// If we got here, our candidate can run
we_ve_got_a_winner /*!hurrah!*/ = true;
else // if blocked, we've to remove it from the ready queue
{
_ready_queue->erase_first ();
alive_threads--;
}
}
// ?. Finally select the new thread (if appropriate); now we're sure
// the one we have can run
if (we_ve_got_a_winner)
{
// Fix fields of running thread
DynamicThread &new_running = (DynamicThread &) _ready_queue->get_item_at (0);
_ready_queue->erase_first ();
new_running.set_state (Schedulable::state_running);
// If the new running is different from the old one,
// remember to release our old pal, and to acquire our
// new runner.
if (&new_running != running_thread)
{
if (running_thread != nullptr)
{
running_thread->set_state (Schedulable::state_ready);
running_thread->set_last_release (current_instant);
}
new_running.set_last_acquisition (current_instant);
}
new_running.set_last_acquisition(current_instant);
}
}
catch (const CPUPolicyException &e)
{
// Reset values that the policy doesn't need anymore
_policy = nullptr;
_ready_queue = nullptr;
// Do we need to update/reset something else?
// Going up unwinding the stack, tell:
// - the user that the policy sucks
// - SimulationController that everything stopped
throw;
}
final_cleanup:
// append the new snapshot...
// ...and remember to release the auto_ptr!
concrete_history.append_new_environment (new_snapshot.release ());
}
catch (const CPUPolicyException& e)
{
// Reset values that the policy doesn't need anymore
_policy = nullptr;
_ready_queue = nullptr;
// Do we need to update/reset something else?
// Going up unwinding the stack, tell:
// - the user that the policy sucks
// - SimulationController that everything stopped
throw;
}
final_cleanup:
// append the new snapshot...
// ...and remember to release the auto_ptr!
concrete_history.append_new_environment(new_snapshot.release());
// Reset values that the policy doesn't need anymore
_policy = nullptr;
_ready_queue = nullptr;
// If we got there, a step has been performed.
// Return if we can perform another step.
return alive_threads != 0;
// If we got there, a step has been performed.
// Return if we can perform another step.
return alive_threads != 0;
}

View File

@ -22,6 +22,6 @@
using namespace sgpem;
SerializeVisitor::~SerializeVisitor()
{}
SerializeVisitor::~SerializeVisitor ()
{
}

View File

@ -24,14 +24,13 @@
using namespace sgpem;
Serializer::Serializer()
Serializer::Serializer ()
{
// automatically register subclasses to the manager
SerializersGatekeeper::get_instance().register_serializer(this);
// automatically register subclasses to the manager
SerializersGatekeeper::get_instance ().register_serializer (this);
}
Serializer::~Serializer()
Serializer::~Serializer ()
{
// INSPECTOR NOTE: no unregister here?
// INSPECTOR NOTE: no unregister here?
}

View File

@ -18,12 +18,10 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/serializer_error.hh>
using namespace sgpem;
SerializerError::SerializerError(const std::string& what) :
std::runtime_error(what)
{}
SerializerError::SerializerError (const std::string &what) : std::runtime_error (what)
{
}

View File

@ -18,10 +18,8 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
#include <sgpemv2/serializers_gatekeeper.hh>
#include <sgpemv2/serializer.hh>
#include <sgpemv2/serializers_gatekeeper.hh>
// Include full template definition only in implementation files:
#include <sgpemv2/templates/singleton.tcc>
@ -29,50 +27,48 @@
#include <algorithm>
#include <cassert>
using std::vector;
using std::find;
using std::runtime_error;
using std::vector;
using namespace sgpem;
// Explicit template instantiation to allow to export symbols from the DSO.
template class sgpem::Singleton<SerializersGatekeeper>;
typedef vector<Serializer*>::iterator SerializerIterator;
typedef vector<Serializer *>::iterator SerializerIterator;
vector<Serializer*>
SerializersGatekeeper::get_registered() const
vector<Serializer *>
SerializersGatekeeper::get_registered () const
{
return _registered;
return _registered;
}
void
SerializersGatekeeper::register_serializer(Serializer* serializer)
SerializersGatekeeper::register_serializer (Serializer *serializer)
{
assert(serializer != nullptr);
assert (serializer != nullptr);
SerializerIterator end = _registered.end();
SerializerIterator end = _registered.end ();
if (find(_registered.begin(), end, serializer) == end)
_registered.push_back(serializer);
if (find (_registered.begin (), end, serializer) == end)
_registered.push_back (serializer);
}
void
SerializersGatekeeper::unregister_serializer(Serializer* serializer)
SerializersGatekeeper::unregister_serializer (Serializer *serializer)
{
assert(serializer != nullptr);
assert (serializer != nullptr);
SerializerIterator end = _registered.end();
SerializerIterator pos = find(_registered.begin(), end, serializer);
SerializerIterator end = _registered.end ();
SerializerIterator pos = find (_registered.begin (), end, serializer);
if (pos != end)
{
_registered.erase(pos);
}
if (pos != end)
{
_registered.erase (pos);
}
}
SerializersGatekeeper::SerializersGatekeeper()
SerializersGatekeeper::SerializersGatekeeper ()
{
}

View File

@ -5,4 +5,3 @@
#define POLDIR "@policiesdir@"
#define PLUGDIR "@plugindir@"
#define EXAMPLESDIR "@examplesdir@"

View File

@ -23,26 +23,26 @@
namespace sgpem
{
class CPUPolicyManager;
class CPUPolicy;
class History;
}
class CPUPolicyManager;
class CPUPolicy;
class History;
} // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh>
#include <vector>
#include <map>
#include <stdexcept>
#include <vector>
#include <sgpemv2/templates/singleton.hh>
#include <sgpemv2/malformed_policy_exception.hh>
#include <sgpemv2/templates/singleton.hh>
#include <sgpemv2/user_interrupt_exception.hh>
namespace sgpem
{
class CPUPoliciesGatekeeper;
class CPUPoliciesGatekeeper;
/** \brief This is the container of all CPU policies found on the system.
/** \brief This is the container of all CPU policies found on the system.
*
* Keeps all registered policy managers in order to access to available policies
* Every CPUPolicyManager should register itself to this class so that
@ -50,22 +50,22 @@ namespace sgpem
*
* This class' constructor should be friend with Singleton (shake hands, make a smile!).
*/
class SG_DLLEXPORT CPUPoliciesGatekeeper : public Singleton<CPUPoliciesGatekeeper>
{
class SG_DLLEXPORT CPUPoliciesGatekeeper : public Singleton<CPUPoliciesGatekeeper>
{
friend class Singleton<CPUPoliciesGatekeeper>;
public:
public:
typedef CPUPolicyManager Manager;
typedef std::vector<Manager*> Managers;
typedef std::vector<Manager *> Managers;
/** \brief Returns registered ::CPUManager */
Managers get_registered() const;
Managers get_registered () const;
/** \brief Register a new manager
*
* A no-op if a manager of the same type already exists
*/
void register_manager(CPUPolicyManager* manager);
void register_manager (CPUPolicyManager *manager);
/** \brief Unregister a given manager
*
@ -73,35 +73,33 @@ namespace sgpem
* to ensure that the currently active policies weren't managed by it. If so, the policies
* should be deactivated before removal.
*/
void unregister_manager(CPUPolicyManager* manager);
void unregister_manager (CPUPolicyManager *manager);
/** \brief Returns the currently active policy
*
* If no policy was previously activated for the attached
* ::History, throw an appropriate exception.
*/
CPUPolicy* get_current_policy(History* history);
CPUPolicy *get_current_policy (History *history);
/** \brief Associates a policy with history.
* If an exception is thrown, the current associated *policy with this history
* (if there are any), is \b no more active, \b nor associated
*/
void activate_policy(History* history, CPUPolicy* policy);
void activate_policy (History *history, CPUPolicy *policy);
private:
CPUPoliciesGatekeeper(); //private constructor.
CPUPoliciesGatekeeper(const CPUPoliciesGatekeeper&);
CPUPoliciesGatekeeper& operator=(const CPUPoliciesGatekeeper&);
private:
CPUPoliciesGatekeeper (); //private constructor.
CPUPoliciesGatekeeper (const CPUPoliciesGatekeeper &);
CPUPoliciesGatekeeper &operator= (const CPUPoliciesGatekeeper &);
/** \brief Deactivates active policies managed by the specified manager. */
void deactivate_policies(CPUPolicyManager* manager);
void deactivate_policies (CPUPolicyManager *manager);
Managers _registered;
std::map<History*, CPUPolicy*> _active_policies;
};
Managers _registered;
std::map<History *, CPUPolicy *> _active_policies;
};
}//~ namespace sgpem
} // namespace sgpem
#endif //~ CPU_POLICIES_GATEKEEPER_HH

View File

@ -21,31 +21,31 @@
#ifndef CPU_POLICY_HH
#define CPU_POLICY_HH 1
#include <sgpemv2/sgpemv2-visibility.hh>
#include "gettext.h"
#include <sgpemv2/sgpemv2-visibility.hh>
#include "glibmm/ustring.h"
#include <sgpemv2/malformed_policy_exception.hh>
#include <sgpemv2/policy_parameters.hh>
#include <sgpemv2/user_interrupt_exception.hh>
#include <sgpemv2/malformed_policy_exception.hh>
#include <stdexcept>
namespace sgpem
{
class CPUPolicy;
class CPUPolicy;
/** \brief
/** \brief
It's a Strategy wich stay for a scheduling algorithm.
It implements the related scheduling policy.
Its goal is, usually, to keep a list of Schedulable objects
mantained in a ReadyQueue.
*/
class SG_DLLEXPORT CPUPolicy
{
public:
virtual ~CPUPolicy();
class SG_DLLEXPORT CPUPolicy
{
public:
virtual ~CPUPolicy ();
/**
Initialize the inner components of the policy.
@ -53,7 +53,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented
in concrete derived classes.
*/
virtual void configure() = 0;
virtual void configure () = 0;
/**
Sort the \ref ReadyQueue object that contain all the Schedulable objects
@ -62,7 +62,7 @@ namespace sgpem
Because it's a pure virtual method, must be re-implemented
in concrete derived classes.
*/
virtual void sort_queue() const = 0;
virtual void sort_queue () const = 0;
/**
Gets a string description of the policy.
@ -71,9 +71,9 @@ namespace sgpem
in concrete derived classes.
\return String description of the policy.
*/
virtual Glib::ustring get_description() const = 0;
virtual Glib::ustring get_description () const = 0;
virtual Glib::ustring get_name() const = 0;
virtual Glib::ustring get_name () const = 0;
/**
Tell if this policy is preemptible.
@ -82,7 +82,7 @@ namespace sgpem
in concrete derived classes.
\return True if this policy is preemptible.
*/
virtual bool is_pre_emptive() const = 0;
virtual bool is_pre_emptive () const = 0;
/**
Gets the time quantum for the policy.
@ -91,33 +91,32 @@ namespace sgpem
in concrete derived classes.
\return Time quantum for the policy.
*/
virtual int get_time_slice() const = 0;
virtual int get_time_slice () const = 0;
virtual void activate() = 0;
virtual void activate () = 0;
virtual void deactivate() = 0;
virtual void deactivate () = 0;
/**
Gets the parameters related with this policy.
\return The policy parameters.
*/
PolicyParameters& get_parameters();
PolicyParameters &get_parameters ();
/** This method is used only as a callback by scripting languages */
static CPUPolicy* callback_get_policy();
static CPUPolicy *callback_get_policy ();
protected:
PolicyParameters _parameters;
protected:
PolicyParameters _parameters;
static void set_callback_policy(CPUPolicy* ptr = nullptr);
static void set_callback_policy (CPUPolicy *ptr = nullptr);
private:
private:
// Used by callback_get_policy:
static CPUPolicy* _callback_policy;
static CPUPolicy *_callback_policy;
};
};
}//~ namespace sgpem
} // namespace sgpem
#endif //~ CPU_POLICY_HH

View File

@ -31,13 +31,13 @@
namespace sgpem
{
class CPUPolicyException;
class CPUPolicyException;
class SG_DLLEXPORT CPUPolicyException : public std::runtime_error
{
public:
explicit CPUPolicyException(const std::string& msg = "");
};
} //~ namespace sgpem
class SG_DLLEXPORT CPUPolicyException : public std::runtime_error
{
public:
explicit CPUPolicyException (const std::string &msg = "");
};
} // namespace sgpem
#endif

View File

@ -23,7 +23,7 @@
namespace sgpem
{
class CPUPolicyManager;
class CPUPolicyManager;
}
#include <sgpemv2/sgpemv2-visibility.hh>
@ -35,15 +35,15 @@ namespace sgpem
namespace sgpem
{
/**
/**
\brief CPUPolicyManager is the Abstract Factory for
\ref CPUPolicy objects.
*/
class SG_DLLEXPORT CPUPolicyManager
{
public:
class SG_DLLEXPORT CPUPolicyManager
{
public:
typedef CPUPolicy Policy;
typedef std::vector<Policy*> Policies;
typedef std::vector<Policy *> Policies;
/** \brief CPUPolicyManager constructor
*
@ -51,13 +51,13 @@ namespace sgpem
* when needed. This is done so that concrete subclasses can be defined
* even if they are found in external dynamic modules not known at compile time.
*/
CPUPolicyManager();
CPUPolicyManager ();
virtual ~CPUPolicyManager() = 0;
virtual ~CPUPolicyManager () = 0;
virtual const Policies& get_avail_policies() = 0;
virtual const Policies &get_avail_policies () = 0;
protected:
protected:
/**
* \brief Collects available policies
*
@ -68,12 +68,11 @@ namespace sgpem
* method will be called at some time during the initialization of
* the manager (usually inside the constructor).
*/
virtual void collect_policies() = 0;
virtual void collect_policies () = 0;
std::vector<CPUPolicy*> _policies;
};
std::vector<CPUPolicy *> _policies;
};
} //~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -23,7 +23,7 @@
namespace sgpem
{
class ResourcePolicy;
class ResourcePolicy;
}
#include <sgpemv2/sgpemv2-visibility.hh>
@ -35,33 +35,32 @@ namespace sgpem
namespace sgpem
{
class CppResourcePolicyManager;
class CppResourcePolicyManager;
/**
/**
ResourcePolicyManager is the Abstract Factory for \ref ResourcePolicy objects.
*/
class SG_DLLEXPORT CppResourcePolicyManager : public ResourcePolicyManager
{
public:
class SG_DLLEXPORT CppResourcePolicyManager : public ResourcePolicyManager
{
public:
/** \brief CppResourcePolicyManager constructor
*
* Registers itself to the ResourcePoliciesGatekeeper singleton.
*/
CppResourcePolicyManager();
CppResourcePolicyManager ();
virtual ~CppResourcePolicyManager();
virtual ~CppResourcePolicyManager ();
virtual const std::vector<ResourcePolicy*>& get_avail_policies() const;
virtual const std::vector<ResourcePolicy *> &get_avail_policies () const;
private:
std::vector<ResourcePolicy*> _policies;
private:
std::vector<ResourcePolicy *> _policies;
// an Instance of this class is created by default and it is registered to
// the ResourcePolicyGateKeeper
static CppResourcePolicyManager _default_instance;
};
};
} //~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -31,38 +31,38 @@
namespace sgpem
{
class ReadyQueue;
class Process;
class Request;
class Resource;
class ReadyQueue;
class Process;
class Request;
class Resource;
/// \brief An instant of the simulation.
/// An object of the Environment class represents a snapshot of
/// the simulated environment taken in a fixed instant, composed
/// by processes, threads, resources and more.
/// A snapshot for every single entity is accessible from here.
/// All the provided objects and data is constant.
///
/// Class History provides access to Environments for each instant
/// of the simulation.
///
/// Anyway, as well as the returned collections contain non-const
/// pointers, it will be possible to call non-const member functions
/// on these objects. This has no consequences until someone adds
/// non-const member functions to these classes.
///
/// This class is abstract: it provides the public interface to
/// read the content of an History.
/// \see History
/// \brief An instant of the simulation.
/// An object of the Environment class represents a snapshot of
/// the simulated environment taken in a fixed instant, composed
/// by processes, threads, resources and more.
/// A snapshot for every single entity is accessible from here.
/// All the provided objects and data is constant.
///
/// Class History provides access to Environments for each instant
/// of the simulation.
///
/// Anyway, as well as the returned collections contain non-const
/// pointers, it will be possible to call non-const member functions
/// on these objects. This has no consequences until someone adds
/// non-const member functions to these classes.
///
/// This class is abstract: it provides the public interface to
/// read the content of an History.
/// \see History
class SG_DLLEXPORT Environment
{
public:
typedef SubRequest::resource_key_t resource_key_t;
class SG_DLLEXPORT Environment
{
public:
typedef SubRequest::resource_key_t resource_key_t;
typedef std::vector<Process*> Processes;
typedef std::map<resource_key_t, Resource*> Resources;
typedef std::vector<SubRequest*> SubRequestQueue;
typedef std::vector<Process *> Processes;
typedef std::map<resource_key_t, Resource *> Resources;
typedef std::vector<SubRequest *> SubRequestQueue;
/// \brief Returns an indexed set of snapshots of the processes
/// Returns a standard vector of Process objects describing
@ -71,8 +71,7 @@ namespace sgpem
///
/// \return a constant set of snapshots of processes
virtual const Processes&
get_processes() const = 0;
virtual const Processes &get_processes () const = 0;
/// \brief Returns an indexed set of snapshots of the resources
@ -89,8 +88,7 @@ namespace sgpem
///
/// \return an indexed constant set of snapshot of resources.
virtual const Resources&
get_resources() const = 0;
virtual const Resources &get_resources () const = 0;
/// \brief Returns a snapshot of the current request queue for a resource.
@ -100,8 +98,7 @@ namespace sgpem
/// \param resource the resource the requests are for
/// \return the current ready requests queue (constant).
virtual const SubRequestQueue&
get_request_queue(resource_key_t resource_key) const = 0;
virtual const SubRequestQueue &get_request_queue (resource_key_t resource_key) const = 0;
/// \brief Returns a snapshot of the current scheduler's ready queue.
@ -111,18 +108,15 @@ namespace sgpem
/// of the CPU.
/// \return the current ready queue (constant).
virtual const ReadyQueue&
get_sorted_queue() const = 0;
virtual const ReadyQueue &get_sorted_queue () const = 0;
/// \brief The standard virtual destructor.
/// The standard virtual destructor.
virtual
~Environment() = 0;
};
virtual ~Environment () = 0;
};
}
} // namespace sgpem
#endif

View File

@ -30,74 +30,75 @@
#include <vector>
// Do not include complete template definition here:
#include <sgpemv2/templates/singleton.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/request.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/templates/singleton.hh>
namespace sgpem
{
class GlobalPreferences;
class KeyFile;
}
class GlobalPreferences;
class KeyFile;
} // namespace sgpem
namespace sgpem
{
/**
/**
\brief Contains all global application preferences
*/
class SG_DLLEXPORT GlobalPreferences : public Singleton<GlobalPreferences>
{
class SG_DLLEXPORT GlobalPreferences : public Singleton<GlobalPreferences>
{
friend class Singleton<GlobalPreferences>;
public:
public:
typedef std::vector<Glib::ustring> DirVector;
typedef DirVector::iterator DirVectorIt;
typedef DirVector::const_iterator DirVectorConstIt;
typedef DirVector::iterator DirVectorIt;
typedef DirVector::const_iterator DirVectorConstIt;
/**
\return GlobalPreferences configuration filename
*/
Glib::ustring get_config_filename() const;
Glib::ustring get_config_filename () const;
/**
\brief Returns configured Policy directories
\return ::_policy_dirs
*/
DirVector& get_policy_dirs();
DirVector &get_policy_dirs ();
/**
\brief Returns configured Plugin directories
\return ::_plugin_dirs
*/
DirVector& get_plugin_dirs();
DirVector &get_plugin_dirs ();
/**
\brief Returns the simumulation speed
\return _speed
*/
int get_speed();
int get_speed ();
/**
\brief Returns the simumulation speed and return old speed
\return _speed
*/
int set_speed(int new_speed);
int set_speed (int new_speed);
/**
\return A HTML color name or hexadecimal code
*/
const Glib::ustring get_schedulable_color(Schedulable::state st) const;
const Glib::ustring get_schedulable_color (Schedulable::state st) const;
/**
\brief Also works with SubRequest::state
\return A HTML color name or hexadecimal code
*/
const Glib::ustring get_request_color(Request::state st) const;
const Glib::ustring get_request_color (Request::state st) const;
/**
\brief Writes preferences to disk
@ -110,7 +111,7 @@ namespace sgpem
We advice using a key=value text format.
#- Close the configuration file.
*/
void write_configrc();
void write_configrc ();
/**
\brief Load global preferences from disk
@ -119,7 +120,7 @@ namespace sgpem
\throw std::io_error
*/
void load_configrc();
void load_configrc ();
/** \brief Prepare directory to read/write preferences to disk
*
@ -128,25 +129,25 @@ namespace sgpem
* %ApplicationData%/sgpemv2, on *nix systems $HOME/.sgpemv2.
* If it doesn't exist, attempt to create it.
*/
Glib::ustring get_preferences_dir() const;
Glib::ustring get_preferences_dir () const;
private:
GlobalPreferences();
GlobalPreferences(const GlobalPreferences&);
GlobalPreferences& operator=(const GlobalPreferences&);
private:
GlobalPreferences ();
GlobalPreferences (const GlobalPreferences &);
GlobalPreferences &operator= (const GlobalPreferences &);
void key_file_read(KeyFile& kf);
void key_file_write(KeyFile& kf);
void key_file_read (KeyFile &kf);
void key_file_write (KeyFile &kf);
/**
\brief Returns directories to search for plugins
*/
DirVector _mod_dirs;
DirVector _mod_dirs;
/**
\brief Returns directories to search for policies
*/
DirVector _pol_dirs;
DirVector _pol_dirs;
/*
These directories can be added to SGPEM in the following ways:
@ -156,7 +157,7 @@ namespace sgpem
-# By a backend::Plugin::on_init() method called when loading an external DSO. This is perfectly normal and permitted.
*/
int _speed;
};
}
};
} // namespace sgpem
#endif

View File

@ -34,7 +34,7 @@
namespace sgpem
{
/** \brief Manages the history of the simulation
/** \brief Manages the history of the simulation
Manages the history of the simulation from the instant 0 to the current time,
i.e. permits to know the state of each schedulable object inside this time interval.
@ -43,37 +43,37 @@ namespace sgpem
In a future iteration it will be possible to revert the entire simulation to a state
present in the history ("undo operation")
*/
class History;
class History;
// Forward declarations:
class HistoryObserver;
class Resource;
class Process;
class Thread;
class Request;
class SubRequest;
// Forward declarations:
class HistoryObserver;
class Resource;
class Process;
class Thread;
class Request;
class SubRequest;
class SG_DLLEXPORT History
{
public:
class SG_DLLEXPORT History
{
public:
// Forward declaration
class LockNotify;
friend class History::LockNotify;
typedef unsigned int size_t;
typedef unsigned int time_t;
typedef unsigned int position;
typedef int prio_t;
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;
typedef const std::pair<resource_key_t, Resource*> ResourcePair;
typedef Environment::resource_key_t resource_key_t;
typedef const std::pair<resource_key_t, Resource *> ResourcePair;
History();
virtual ~History() = 0;
History ();
virtual ~History () = 0;
virtual size_t get_size() const = 0;
virtual const Environment& get_last_environment() const = 0;
virtual const Environment& get_environment_at(position index) const = 0;
virtual size_t get_size () const = 0;
virtual const Environment &get_last_environment () const = 0;
virtual const Environment &get_environment_at (position index) const = 0;
/**
\brief Removes a Resource from the whole History.
@ -83,7 +83,7 @@ namespace sgpem
\param resource_key The key of the resource to remove.
*/
virtual void remove(resource_key_t resource_key) = 0;
virtual void remove (resource_key_t resource_key) = 0;
/**
\brief Removes a Process from the whole History.
@ -92,7 +92,7 @@ namespace sgpem
\param process The process to remove.
*/
virtual void remove(Process& process) = 0;
virtual void remove (Process &process) = 0;
/**
\brief Removes a thread from the whole History.
@ -101,7 +101,7 @@ namespace sgpem
\param thread The thread to remove.
*/
virtual void remove(Thread& thread) = 0;
virtual void remove (Thread &thread) = 0;
/**
\brief Removes a request from the whole History.
@ -111,7 +111,7 @@ namespace sgpem
\param request The request to remove.
*/
virtual void remove(Request& request) = 0;
virtual void remove (Request &request) = 0;
/**
\brief Removes a subrequest from the whole History.
@ -121,12 +121,12 @@ namespace sgpem
\param subrequest The subrequest to remove.
*/
virtual void remove(SubRequest& subrequest) = 0;
virtual void remove (SubRequest &subrequest) = 0;
/**
\brief Clears the whole history
*/
virtual void clear() = 0;
virtual void clear () = 0;
/**
\brief Add a Resource to the simulation.
@ -137,10 +137,8 @@ namespace sgpem
\param availability The instant from wich the resource is available.
\return a pair with unique key and pointer to the resource created.
*/
virtual ResourcePair add_resource(const Glib::ustring& name,
bool preemptable = false,
size_t places = 1,
size_t availability = 0) = 0;
virtual ResourcePair
add_resource (const Glib::ustring &name, bool preemptable = false, size_t places = 1, size_t availability = 0) = 0;
/**
\brief Change data of an existing resource.
@ -151,11 +149,8 @@ namespace sgpem
\param places Number of places of the resource.
\param availability The instant from wich the resource is available.
*/
virtual void edit_resource(Resource& resource,
const Glib::ustring& name,
bool preemptable = false,
size_t places = 1,
size_t availability = 0) = 0;
virtual void edit_resource (Resource &resource, const Glib::ustring &name, bool preemptable = false,
size_t places = 1, size_t availability = 0) = 0;
/**
\brief Add a Process to the simulation.
@ -166,9 +161,7 @@ namespace sgpem
(scheduler can change it during execution).
\return The newly created process.
*/
virtual Process& add_process(const Glib::ustring& name,
time_t arrival_time,
prio_t base_priority = 0) = 0;
virtual Process &add_process (const Glib::ustring &name, time_t arrival_time, prio_t base_priority = 0) = 0;
/**
\brief Edit an exixting Process in the simulation.
@ -179,10 +172,7 @@ namespace sgpem
\param base_priority Process priority at start up time
(scheduler can change it during execution).
*/
virtual void edit_process(Process& process,
const Glib::ustring& name,
time_t arrival_time,
prio_t base_priority = 0) = 0;
virtual void edit_process (Process &process, const Glib::ustring &name, time_t arrival_time, prio_t base_priority = 0) = 0;
/**
@ -196,11 +186,8 @@ namespace sgpem
(scheduler can change it during execution).
\return The newly created thread.
*/
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;
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;
/**
\brief Edit an exixting Thread in the simulation.
@ -212,11 +199,8 @@ namespace sgpem
\param base_priority Thread priority at start up time
(scheduler can change it during execution).
*/
virtual void edit_thread(Thread& thread,
const Glib::ustring& name,
time_t cpu_time,
time_t arrival_time = 0,
prio_t base_priority = 0) = 0;
virtual void edit_thread (Thread &thread, const Glib::ustring &name, time_t cpu_time, time_t arrival_time = 0,
prio_t base_priority = 0) = 0;
/**
\brief Add a Request to an existing thread.
@ -225,8 +209,7 @@ namespace sgpem
\param instant When the request arrives.
\return The newly created request.
*/
virtual Request& add_request(Thread& owner,
time_t instant) = 0;
virtual Request &add_request (Thread &owner, time_t instant) = 0;
/**
\brief Edit a Request.
@ -234,8 +217,7 @@ namespace sgpem
\param request Reference to editing request.
\param instant When the request arrives.
*/
virtual void edit_request(Request& request,
time_t instant) = 0;
virtual void edit_request (Request &request, time_t instant) = 0;
/**
@ -246,9 +228,7 @@ namespace sgpem
\param duration Total time of request usage.
\return The newly created subrequest.
*/
virtual SubRequest& add_subrequest(Request& request,
resource_key_t resource_key,
time_t duration) = 0;
virtual SubRequest &add_subrequest (Request &request, resource_key_t resource_key, time_t duration) = 0;
/**
\brief Edit an existing SubRequest.
@ -257,17 +237,15 @@ namespace sgpem
\param resource_key Key of the requested resource.
\param duration Total time of request usage.
*/
virtual void edit_subrequest(SubRequest& subrequest,
resource_key_t resource_key,
time_t duration) = 0;
virtual void edit_subrequest (SubRequest &subrequest, resource_key_t resource_key, time_t duration) = 0;
/**
\return actual instant (current time in simulation)
*/
virtual position get_front() const;
virtual position get_front () const;
/**
*/
virtual bool is_sealed() const = 0;
virtual bool is_sealed () const = 0;
/**
\brief Attach a new observer object for this History.
@ -277,31 +255,31 @@ namespace sgpem
want to be notified, e.g. only when resources change but not when requests
do, etc.
*/
virtual void attach(HistoryObserver& observer);
virtual void attach (HistoryObserver &observer);
/**
\brief Detach an observer object for this History.
*/
virtual void detach(const HistoryObserver& observer);
virtual void detach (const HistoryObserver &observer);
/**
\brief Brings History to initial state.
*/
virtual void reset() = 0;
virtual void reset () = 0;
protected:
typedef std::vector<HistoryObserver*> RegisteredObservers;
protected:
typedef std::vector<HistoryObserver *> RegisteredObservers;
RegisteredObservers _observers;
/**
\brief Notify all registered ::HistoryObserver that the History has changed.
Calls HistoryObserver.update(this) for each registered observer.
*/
void notify_change();
void notify_change ();
position _front;
position _front;
private:
private:
/** \brief Enable/disable notifications to registered observers
*
* This is quite useful to disable momentarily notification while you
@ -310,16 +288,16 @@ namespace sgpem
*
* \return The old value
*/
bool set_notify_enabled(bool enabled = true);
bool set_notify_enabled (bool enabled = true);
/**
\brief Flag indicating notification to observers enabled/disbled.
*/
bool _notify;
}; //~ class History
}; //~ class History
/** \brief Disables notifications to History during the life of this object
/** \brief Disables notifications to History during the life of this object
*
* This class is useful if you've to do a lot of sequential operations on
* History that would reset it / notify its observers. For example, when loading
@ -328,21 +306,21 @@ namespace sgpem
*
* Locks can be taken recursively without fear.
*/
class SG_DLLEXPORT History::LockNotify
{
public:
LockNotify(History& history);
~LockNotify();
class SG_DLLEXPORT History::LockNotify
{
public:
LockNotify (History &history);
~LockNotify ();
private:
History& _h;
bool _was_enabled;
private:
History &_h;
bool _was_enabled;
LockNotify(const LockNotify&);
LockNotify& operator=(const LockNotify&);
}; //~ class History::LockNotify
LockNotify (const LockNotify &);
LockNotify &operator= (const LockNotify &);
}; //~ class History::LockNotify
}//~ namespace sgpem
} // namespace sgpem
#endif //~ HISTORY_HH

View File

@ -23,34 +23,31 @@
namespace sgpem
{
class History;
class HistoryObserver;
}
class History;
class HistoryObserver;
} // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh>
namespace sgpem
{
/** \brief Specifies that the object wants to be notified
/** \brief Specifies that the object wants to be notified
* whenever backend::History changes
*
* Observers need to register to an History if they want to be
* notified.
* \see History
*/
class SG_DLLEXPORT HistoryObserver
{
public:
class SG_DLLEXPORT HistoryObserver
{
public:
/** \brief Called on an History update
*/
virtual void update(const History& changed_history) = 0;
virtual ~HistoryObserver();
virtual void update (const History &changed_history) = 0;
virtual ~HistoryObserver ();
}
; // class HistoryObserver
}; // class HistoryObserver
}//~ namespace sgpem
} // namespace sgpem
#endif //HISTORY_OBSERVER_H

View File

@ -27,22 +27,21 @@
namespace sgpem
{
/**
/**
* \brief This exception is thrown when the DSO you're trying to load doesn't
* export a valid SGPEMv2 backend::Plugin interface.
*/
class InvalidPluginException : public std::runtime_error
{
public:
class InvalidPluginException : public std::runtime_error
{
public:
/**
* \brief Exception constructor.
*
* \param what A constant string msg indicating the failure reason.
*/
InvalidPluginException(const std::string& what);
}
; //~ class InvalidPluginException
InvalidPluginException (const std::string &what);
}; //~ class InvalidPluginException
} //~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -23,7 +23,7 @@
namespace sgpem
{
class KeyFile;
class KeyFile;
}
#include <sgpemv2/sgpemv2-visibility.hh>
@ -35,7 +35,7 @@ namespace sgpem
namespace sgpem
{
/** \brief Save and retrieve configuration files formatted as key=value rows.
/** \brief Save and retrieve configuration files formatted as key=value rows.
*
* This class handles files to store and retrieve configuration preferences
* in the form of: key=value rows.
@ -48,65 +48,64 @@ namespace sgpem
* Reading files, empty lines and lines starting with # are ignored.
*
*/
class SG_DLLEXPORT KeyFile
{
public:
class SG_DLLEXPORT KeyFile
{
public:
/** \brief Elements iterator type definition. */
typedef std::map<Glib::ustring, Glib::ustring>::const_iterator elements_iterator;
/** \brief Object constructor */
KeyFile();
KeyFile ();
/** \brief Elements iterator (begin of container) initializer. */
elements_iterator elements_begin() const;
elements_iterator elements_begin () const;
/** \brief Elements iterator (end of container) initializer */
elements_iterator elements_end() const;
elements_iterator elements_end () const;
/** \brief Insert a new key/value pair.
*
* \param key The key value to insert.
* \param value The value associated to the key inserted.
*/
void insert_key_value(const Glib::ustring& key, const Glib::ustring& value);
void insert_key_value (const Glib::ustring &key, const Glib::ustring &value);
/** \brief Insert a new key/value pair.
*
* \param key The key value to insert.
* \return A pointer to the value associated to the searched key or 0 if not found.
*/
const Glib::ustring* search_value(const Glib::ustring& key);
const Glib::ustring *search_value (const Glib::ustring &key);
/** \brief Read a file into this object.
*
* \param filename The file to read from.
*/
void file_read(const Glib::ustring& filename);
void file_read (const Glib::ustring &filename);
/** \brief Read a stream into this object.
*
* \param is the stream to read from.
*/
void file_read(std::istream& is);
void file_read (std::istream &is);
/** \brief Write into a file from this object.
*
* \param filename The file to write to.
*/
void file_write(const Glib::ustring& filename);
void file_write (const Glib::ustring &filename);
/** \brief Write into a stream from this object.
*
* \param os the stream to write to.
*/
void file_write(std::ostream& os);
private:
void file_write (std::ostream &os);
std::map<Glib::ustring, Glib::ustring> _elements;
};
}
private:
std::map<Glib::ustring, Glib::ustring> _elements;
};
} // namespace sgpem
#endif

View File

@ -31,21 +31,20 @@
namespace sgpem
{
/// \brief An exception signaling a non well-formed script.
/// Represents an exception which may be raised to signal that a script which
/// was supposed to represent a policy is not well-formed.
class MalformedPolicyException;
/// \brief An exception signaling a non well-formed script.
/// Represents an exception which may be raised to signal that a script which
/// was supposed to represent a policy is not well-formed.
class MalformedPolicyException;
class SG_DLLEXPORT MalformedPolicyException : public CPUPolicyException
{
public:
class SG_DLLEXPORT MalformedPolicyException : public CPUPolicyException
{
public:
/// \brief Constructor taking a message as parameter.
///
/// Creates a MalformedPolicyException with an optional detailed message.
/// \param msg a message carrying detailed information.
explicit MalformedPolicyException(const std::string& msg = "");
};
} //~ namespace sgpem
explicit MalformedPolicyException (const std::string &msg = "");
};
} // namespace sgpem
#endif

View File

@ -30,20 +30,18 @@
namespace sgpem
{
/// \brief A link to a loaded DSO object
///
/// When a plugin is found, PluginManager::rescan_dirs() tries to load it by
/// creating an object of this class.
/// The constructor should throw InvalidPluginException if the plugin isn't
/// a valid SGPEMv2 one. This should be handled directly into
/// PluginManager::rescan_dirs().
class Module;
/// \brief A link to a loaded DSO object
///
/// When a plugin is found, PluginManager::rescan_dirs() tries to load it by
/// creating an object of this class.
/// The constructor should throw InvalidPluginException if the plugin isn't
/// a valid SGPEMv2 one. This should be handled directly into
/// PluginManager::rescan_dirs().
class Module;
class SG_DLLEXPORT Module : public Glib::Module
{
public:
class SG_DLLEXPORT Module : public Glib::Module
{
public:
/// \brief Constructor taking an identifier.
///
/// Constructor taking an identifier.
@ -51,50 +49,50 @@ namespace sgpem
/// doesn't export a valid SGPEMv2 backend::Plugin interface.
/// \param identifier A string with the DSO name without any file-extension
/// suffix. This is retrieved by PluginManager::rescan_dirs().
Module(const Glib::ustring& identifier);
Module (const Glib::ustring &identifier);
/// \brief Enables or disables a plugin
///
/// Enables/disables a plugin, calling its on_init()/on_exit() exported
/// functions where appropriate.
/// \param enabled whether to enable or disable the module.
void set_enabled(bool enabled = true);
void set_enabled (bool enabled = true);
/// \brief Returns the name of the module.
///
/// Calls Plugin::get_name()
/// \return the name of the module.
Glib::ustring get_name() const;
Glib::ustring get_name () const;
/// \brief Returns the author of the module.
///
/// Calls Plugin::get_author()
/// \return the author of the module.
Glib::ustring get_author() const;
Glib::ustring get_author () const;
/// \brief Returns a description of the module.
///
/// Calls Plugin::describe()
/// \return a description of the module.
Glib::ustring describe() const;
Glib::ustring describe () const;
/// \brief Returns the version of the module.
///
/// Calls Plugin::get_version()
/// \return the version of the module.
float get_version() const;
float get_version () const;
/// \brief Returns whether the module is enabled or disabled.
///
/// Enables/disables a plugin, calling its on_init()/on_exit() exported
/// functions where appropriate.
/// \param enabled whether to enable or disable the module.
bool get_enabled() const;
bool get_enabled () const;
private:
typedef void (*f_void)(void);
typedef const char* (*f_ustring)(void);
typedef float (*f_float)(void);
private:
typedef void (*f_void) (void);
typedef const char *(*f_ustring) (void);
typedef float (*f_float) (void);
/// True if the plugin is enabled, false otherwise
///
@ -104,17 +102,15 @@ namespace sgpem
///
Glib::ustring _id;
f_void on_init_ptr;
f_void on_exit_ptr;
f_void on_init_ptr;
f_void on_exit_ptr;
f_ustring describe_ptr;
f_ustring get_name_ptr;
f_ustring get_author_ptr;
f_float get_version_ptr;
f_float get_version_ptr;
}
; //~ class Module
}; //~ class Module
} //~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -31,16 +31,16 @@
namespace sgpem
{
class NullPolicyException;
class NullPolicyException;
/** \brief Exception thrown when no policy has been selected and
/** \brief Exception thrown when no policy has been selected and
* an operation that involves scheduling is requested
*/
class SG_DLLEXPORT NullPolicyException : public std::runtime_error
{
public:
explicit NullPolicyException(const char* msg = "");
};
} //~ namespace sgpem
class SG_DLLEXPORT NullPolicyException : public std::runtime_error
{
public:
explicit NullPolicyException (const char *msg = "");
};
} // namespace sgpem
#endif

View File

@ -28,7 +28,7 @@ extern "C"
{
#endif
/** \file plugin.hh
/** \file plugin.hh
* All loadable modules that want to act as plugins
* for SGPEMv2 should implement this interface.
* Only the header file containing this interface
@ -38,23 +38,23 @@ extern "C"
* outside its DSO.
*/
/** \brief Called when a plugin is loaded and enabled
/** \brief Called when a plugin is loaded and enabled
*
* Sets up the plugin's initial state and
* performs needed actions before its usage can start.
*/
SG_DLLEXPORT void sgpem__Plugin__on_init();
SG_DLLEXPORT void sgpem__Plugin__on_init ();
SG_DLLEXPORT void sgpem__Plugin__on_exit();
SG_DLLEXPORT const char* sgpem__Plugin__describe();
SG_DLLEXPORT const char* sgpem__Plugin__get_name();
SG_DLLEXPORT const char* sgpem__Plugin__get_author();
SG_DLLEXPORT float sgpem__Plugin__get_version();
SG_DLLEXPORT void sgpem__Plugin__on_exit ();
SG_DLLEXPORT const char *sgpem__Plugin__describe ();
SG_DLLEXPORT const char *sgpem__Plugin__get_name ();
SG_DLLEXPORT const char *sgpem__Plugin__get_author ();
SG_DLLEXPORT float sgpem__Plugin__get_version ();
// To know why SG_DLLEXPORT must go *before* the return
// value, see http://gcc.gnu.org/ml/gcc-help/2005-04/msg00340.html
// To know why SG_DLLEXPORT must go *before* the return
// value, see http://gcc.gnu.org/ml/gcc-help/2005-04/msg00340.html
#ifdef __cplusplus
#ifdef __cplusplus
}
#endif

View File

@ -23,7 +23,7 @@
namespace sgpem
{
class Module;
class Module;
}
#include <sgpemv2/sgpemv2-visibility.hh>
@ -34,25 +34,24 @@ namespace sgpem
namespace sgpem
{
class PluginManager;
class PluginManager;
class SG_DLLEXPORT PluginManager : public Singleton<PluginManager>
{
class SG_DLLEXPORT PluginManager : public Singleton<PluginManager>
{
friend class Singleton<PluginManager>;
public:
std::vector<Module*> get_module_list() const;
void rescan_dirs();
public:
std::vector<Module *> get_module_list () const;
private:
PluginManager();
void rescan_dirs ();
std::vector<Module*> _modules;
private:
PluginManager ();
}
; //~ class PluginManager
std::vector<Module *> _modules;
} //~ namespace sgpem
}; //~ class PluginManager
} // namespace sgpem
#endif

View File

@ -24,32 +24,31 @@
#include <sgpemv2/sgpemv2-visibility.hh>
#include <map>
#include <string>
#include <stdexcept>
#include <string>
#include "glibmm/ustring.h"
namespace sgpem
{
class SG_DLLEXPORT PolicyParametersException : public std::runtime_error
{
public:
PolicyParametersException(std::string msg): std::runtime_error(msg) {}
};
class SG_DLLEXPORT PolicyParametersException : public std::runtime_error
{
public:
PolicyParametersException (std::string msg) : std::runtime_error (msg)
{
}
};
/** \brief Represents all configurable parameters of a single scheduling policy.
/** \brief Represents all configurable parameters of a single scheduling policy.
Represents all configurable parameters of a single scheduling policy. Is is used by the user
interface: it serves to know which parameters the user will be asked for.
Each Policy object owns only one instance of this class.
*/
class SG_DLLEXPORT PolicyParameters
{
public:
class SG_DLLEXPORT PolicyParameters
{
public:
// -------------------------------------------------------------------------
/** \brief This class represents a sigle parameter of type \c T
@ -57,12 +56,11 @@ namespace sgpem
This class is useful only to store informations about each parameter. No checks
on the values entered are done.
*/
template<typename T>
template <typename T>
class SG_DLLEXPORT Parameter
{
public:
/** \brief Constructs the parameter
public:
/** \brief Constructs the parameter
\param name The name of the parameter. This string will be used to refer to this parameter, thus it MUST
be uniqe (one string identifies \b only ONE parameter)
\param value The initial value of this parameter
@ -71,46 +69,45 @@ namespace sgpem
\param required Denotes if this parameter is required by the policy.
\param default_value The initial value of this parameter. (If not specified it's set to 0).
*/
Parameter(Glib::ustring name, const T& value,
const T& lower_bound, const T& upper_bound,
const bool& required, const T& default_value = 0);
Parameter (Glib::ustring name, const T &value, const T &lower_bound, const T &upper_bound, const bool &required,
const T &default_value = 0);
/** \returns The name of the parameter (its UNIQUE key)
/** \returns The name of the parameter (its UNIQUE key)
*/
Glib::ustring get_name() const;
Glib::ustring get_name () const;
/** \returns The lower bound
/** \returns The lower bound
*/
T get_lower_bound() const;
T get_lower_bound () const;
/** \returns The upper bound
/** \returns The upper bound
*/
T get_upper_bound() const;
T get_upper_bound () const;
/** \returns TRUE if this parameter is required
/** \returns TRUE if this parameter is required
*/
bool is_required() const;
bool is_required () const;
/** \returns Its default value
/** \returns Its default value
*/
T get_default() const;
T get_default () const;
/** \returns Its actual value
/** \returns Its actual value
*/
T get_value() const;
T get_value () const;
/** \brief Changes the value of the parameter.
/** \brief Changes the value of the parameter.
\warning NO CHECK is done whether the value repects its bounds!!
*/
void set_value(const T&);
void set_value (const T &);
private:
Glib::ustring _name;
T _value;
T _lower_bound;
T _upper_bound;
bool _is_required;
T _default;
private:
Glib::ustring _name;
T _value;
T _lower_bound;
T _upper_bound;
bool _is_required;
T _default;
};
@ -132,7 +129,8 @@ namespace sgpem
\param required Denotes if this parameter is required by the policy.
\param default_value The initial value of this parameter. (If not specified it's set to 0).
*/
void register_int(Glib::ustring name, const int& lower_bound, const int& upper_bound, const bool& required, const int& default_value = 0);
void register_int (Glib::ustring name, const int &lower_bound, const int &upper_bound, const bool &required,
const int &default_value = 0);
/**\brief Registers a FLOAT parameter.
@ -146,7 +144,8 @@ namespace sgpem
\param required Denotes if this parameter is required by the policy.
\param default_value The initial value of this parameter. (If not specified it's set to 0.0f).
*/
void register_float(Glib::ustring name, const float& lower_bound, const float& upper_bound, const bool& required, const float& default_value = 0.0f);
void register_float (Glib::ustring name, const float &lower_bound, const float &upper_bound, const bool &required,
const float &default_value = 0.0f);
/**\brief Registers a STRING parameter.
@ -159,12 +158,12 @@ namespace sgpem
\param required Denotes if this parameter is required by the policy.
\param default_value The initial value of this parameter. (If not specified it's set to the empty string).
*/
void register_string(Glib::ustring name, const bool& required, const Glib::ustring& default_value = "");
void register_string (Glib::ustring name, const bool &required, const Glib::ustring &default_value = "");
/**\brief Deletes all registered parameters.
*/
void clear();
void clear ();
//#############################################
@ -174,17 +173,17 @@ namespace sgpem
/** \brief Permits to retrieve all registered INTEGER parameters
\returns a map of INTEGER parameters identfied by their name
*/
std::map<Glib::ustring, Parameter<int> > get_registered_int_parameters() const;
std::map<Glib::ustring, Parameter<int>> get_registered_int_parameters () const;
/** \brief Permits to retrieve all registered FLOAT parameters
\returns a map of FLOAT parameters identfied by their name
*/
std::map<Glib::ustring, Parameter<float> > get_registered_float_parameters() const;
std::map<Glib::ustring, Parameter<float>> get_registered_float_parameters () const;
/** \brief Permits to retrieve all registered STRING parameters
\returns a map of STRING parameters identfied by their name
*/
std::map<Glib::ustring, Parameter<Glib::ustring> > get_registered_string_parameters() const;
std::map<Glib::ustring, Parameter<Glib::ustring>> get_registered_string_parameters () const;
//#############################################
@ -199,7 +198,7 @@ namespace sgpem
exceed the bounds proper to that parameter
\returns FALSE if the parameter named "name" is not found or if "value" exceeds the bounds
*/
bool set_int(Glib::ustring name, const int& value);
bool set_int (Glib::ustring name, const int &value);
/** \brief Sets the value of a registred FLOAT parameter
@ -209,7 +208,7 @@ namespace sgpem
exceed the bounds proper to that parameter
\returns FALSE if the parameter named "name" is not found or if "value" exceeds the bounds
*/
bool set_float(Glib::ustring name, const float& value);
bool set_float (Glib::ustring name, const float &value);
/** \brief Sets the value of a registred STRING parameter
@ -219,7 +218,7 @@ namespace sgpem
exceed the bounds proper to that parameter
\returns FALSE if the parameter named "name" is not found or if "value" exceeds the bounds
*/
bool set_string(Glib::ustring name, const Glib::ustring& value);
bool set_string (Glib::ustring name, const Glib::ustring &value);
//#############################################
@ -230,28 +229,27 @@ namespace sgpem
\returns the INTEGER value of the parameter named \e name
\throws PolicyParametersException if the parameter named \e name has not been registered
*/
int get_int(Glib::ustring name) const;
int get_int (Glib::ustring name) const;
/** \brief Returns the value of an FLOAT parameter
\returns the FLOAT value of the parameter named \e name
\throws PolicyParametersException if the parameter named \e name has not been registered
*/
float get_float(Glib::ustring name) const;
float get_float (Glib::ustring name) const;
/** \brief Returns the value of an STRING parameter
\returns the STRING value of the parameter named \e name
\throws PolicyParametersException if the parameter named \e name has not been registered
*/
Glib::ustring get_string(Glib::ustring name) const;
Glib::ustring get_string (Glib::ustring name) const;
private:
std::map<Glib::ustring, Parameter<int>> int_map;
std::map<Glib::ustring, Parameter<float>> float_map;
std::map<Glib::ustring, Parameter<Glib::ustring>> string_map;
};
private:
std::map<Glib::ustring, Parameter<int> > int_map;
std::map<Glib::ustring, Parameter<float> > float_map;
std::map<Glib::ustring, Parameter<Glib::ustring> > string_map;
};
}//~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -21,29 +21,28 @@
#ifndef PROCESS_HH
#define PROCESS_HH 1
#include <sgpemv2/sgpemv2-visibility.hh>
#include "glibmm/ustring.h"
#include <sgpemv2/sgpemv2-visibility.hh>
#include <vector>
#include <sgpemv2/schedulable.hh>
namespace sgpem
{
class Process;
class Thread;
class SerializeVisitor;
class Process;
class Thread;
class SerializeVisitor;
class SG_DLLEXPORT Process : public virtual Schedulable
{
public:
virtual ~Process();
class SG_DLLEXPORT Process : public virtual Schedulable
{
public:
virtual ~Process ();
virtual std::vector<Thread*> get_threads() = 0;
virtual std::vector<const Thread*> get_threads() const = 0;
virtual void serialize(SerializeVisitor& translator) const = 0;
};
virtual std::vector<Thread *> get_threads () = 0;
virtual std::vector<const Thread *> get_threads () const = 0;
virtual void serialize (SerializeVisitor &translator) const = 0;
};
}//~namespace sgpem
} // namespace sgpem
#endif //~ PROCESS_HH

View File

@ -23,10 +23,10 @@
#include "thread_statistics.hh"
#include <sgpemv2/sgpemv2-visibility.hh>
#include <sgpemv2/schedulable_statistics.hh>
#include <sgpemv2/thread_statistics.hh>
#include <sgpemv2/process.hh>
#include <sgpemv2/schedulable_statistics.hh>
#include <sgpemv2/sgpemv2-visibility.hh>
#include <sgpemv2/thread_statistics.hh>
#include <glibmm/ustring.h>
@ -34,19 +34,19 @@
namespace sgpem
{
class ProcessStatistics : public SchedulableStatistics
{
class ProcessStatistics : public SchedulableStatistics
{
public:
~ProcessStatistics();
~ProcessStatistics ();
virtual float get_average_response_time() const = 0;
virtual const Process* get_core() const = 0;
virtual float get_average_response_time () const = 0;
virtual const Process *get_core () const = 0;
virtual std::vector<const ThreadStatistics*> get_threads_statistics() const = 0;
virtual std::vector<const ThreadStatistics *> get_threads_statistics () const = 0;
protected:
ProcessStatistics();
};
}
ProcessStatistics ();
};
} // namespace sgpem
#endif

View File

@ -28,29 +28,29 @@
namespace sgpem
{
class ReadyQueue;
class Thread;
class SG_DLLEXPORT ReadyQueue
{
public:
class ReadyQueue;
class Thread;
class SG_DLLEXPORT ReadyQueue
{
public:
typedef unsigned int position;
typedef unsigned int size_t;
/**
/**
* \brief Swaps the object at position \a a with the object
* at position \a b Used for implementing in-place sorting algorithms.
*
* \param a first object position
* \param b second object position
*/
void swap(position a, position b);
void swap (position a, position b);
/**
* \brief Return the size of the queue.
*
* \return _scheds.size()
*/
size_t size() const;
size_t size () const;
/**
* \brief Returns an item contained in the vector.
@ -60,7 +60,7 @@ namespace sgpem
* \return The item at positon \a index.
* \throw std::out_of_range if position is < 1 or > size()-1.
*/
Thread& get_item_at(position index);
Thread &get_item_at (position index);
/**
@ -71,38 +71,37 @@ namespace sgpem
* \return A constant reference to the item at positon \a index.
* \throw std::out_of_range if position is < 1 or > size()-1
*/
const Thread& get_item_at(position index) const;
const Thread &get_item_at (position index) const;
/**
* \brief Add a new ::Thread at the end of the queue.
*
* \param schedulable A reference to the appending thread.
*/
void append(Thread& schedulable);
void append (Thread &schedulable);
/**
* \brief Bubble element x to the front of the queue
*/
void bubble_to_front(position x);
void bubble_to_front (position x);
/**
* \brief Remove the first item from the threads vector.
*/
void erase_first();
void erase_first ();
private:
private:
/**
* \brief Threads container definition.
*/
typedef std::vector<Thread*> Threads;
typedef std::vector<Thread *> Threads;
/**
* \brief Threads container member.
*/
Threads _scheds;
};
};
}
} // namespace sgpem
#endif

View File

@ -23,44 +23,43 @@
namespace sgpem
{
class Request;
class SerializeVisitor;
class SubRequest;
class Thread;
}
class Request;
class SerializeVisitor;
class SubRequest;
class Thread;
} // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh>
#include <vector>
namespace sgpem
{
class SG_DLLEXPORT Request
{
public:
class SG_DLLEXPORT Request
{
public:
enum state
{
state_unallocable = 1 << 0,
state_allocated = 1 << 1,
state_future = 1 << 2,
state_exhausted = 1 << 3,
state_allocable = 1 << 4
state_unallocable = 1 << 0,
state_allocated = 1 << 1,
state_future = 1 << 2,
state_exhausted = 1 << 3,
state_allocable = 1 << 4
};
virtual ~Request();
virtual ~Request ();
virtual Thread& get_thread() = 0;
virtual Thread &get_thread () = 0;
virtual bool operator==(const Request& op2) const = 0;
virtual bool operator== (const Request &op2) const = 0;
virtual std::vector<SubRequest*> get_subrequests() = 0;
virtual unsigned int get_instant() const = 0;
virtual std::vector<SubRequest *> get_subrequests () = 0;
virtual unsigned int get_instant () const = 0;
virtual state get_state() const = 0;
virtual state get_state () const = 0;
virtual void serialize(SerializeVisitor& translator) const = 0;
};
virtual void serialize (SerializeVisitor &translator) const = 0;
};
}
} // namespace sgpem
#endif

View File

@ -21,29 +21,29 @@
#ifndef RESOURCE_HH
#define RESOURCE_HH 1
#include <sgpemv2/sgpemv2-visibility.hh>
#include "glibmm/ustring.h"
#include <sgpemv2/sgpemv2-visibility.hh>
namespace sgpem
{
class Resource;
class SerializeVisitor;
class Resource;
class SerializeVisitor;
/** \brief An abstract class representing a resource
/** \brief An abstract class representing a resource
*
* A resource in a real operating system could be a printer,
* a socket, a chunk of memory, or a simple file.
*/
class SG_DLLEXPORT Resource
{
public:
virtual ~Resource();
class SG_DLLEXPORT Resource
{
public:
virtual ~Resource ();
/** \brief See if two different states point to the same resource */
virtual bool operator==(const Resource& op2) const = 0;
virtual bool operator== (const Resource &op2) const = 0;
/** \brief Returns the resource name */
virtual Glib::ustring get_name() const = 0;
virtual Glib::ustring get_name () const = 0;
/** \brief Return the number of places this resource has available
* before becoming unavailable
@ -51,13 +51,12 @@ namespace sgpem
* E.g. if a resource has two places, it can fulfill only two
* ::SubRequests at each instant
*/
virtual unsigned int get_places() const = 0;
virtual unsigned int get_places () const = 0;
/** \brief Used to serialize the informations of this entity */
virtual void serialize(SerializeVisitor& translator) const = 0;
};
virtual void serialize (SerializeVisitor &translator) const = 0;
};
}
} // namespace sgpem
#endif

View File

@ -23,48 +23,48 @@
namespace sgpem
{
class ResourcePolicyManager;
class ResourcePolicy;
class History;
}
class ResourcePolicyManager;
class ResourcePolicy;
class History;
} // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh>
#include <vector>
#include <map>
#include <stdexcept>
#include <vector>
#include <sgpemv2/templates/singleton.hh>
namespace sgpem
{
class ResourcePoliciesGatekeeper;
class ResourcePoliciesGatekeeper;
/** \brief FIXME document me
/** \brief FIXME document me
*/
class SG_DLLEXPORT ResourcePoliciesGatekeeper : public Singleton<ResourcePoliciesGatekeeper>
{
class SG_DLLEXPORT ResourcePoliciesGatekeeper : public Singleton<ResourcePoliciesGatekeeper>
{
friend class Singleton<ResourcePoliciesGatekeeper>;
public:
public:
typedef ResourcePolicyManager Manager;
typedef std::vector<Manager*> Managers;
typedef std::vector<Manager *> Managers;
/**
* \brief Returns registered resources policy managers.
*
* \return Registered resources policy managers.
*/
const Managers& get_registered() const;
const Managers &get_registered () const;
/**
* \brief Register a new resources policy manager.
* A no-op if a manager of the same type already exists.
*/
void register_manager(ResourcePolicyManager* manager);
void register_manager (ResourcePolicyManager *manager);
/**
* \brief Unregister a given manager. If not present, it is a no-op.
@ -74,7 +74,7 @@ namespace sgpem
*
* \param manager The resource policy manager to remove.
*/
void unregister_manager(ResourcePolicyManager* manager);
void unregister_manager (ResourcePolicyManager *manager);
/**
* \brief Returns the currently active policy.
@ -83,40 +83,39 @@ namespace sgpem
*
* \return The current policy.
*/
ResourcePolicy& get_current_policy(History* history);
ResourcePolicy &get_current_policy (History *history);
/**
\brief Given a policy, sets it as the history current one.
Also deactivates the old policy if present, and then activates
the new policy before use. If old_policy == new_policy, it's a no-op.
*/
void activate_policy(History* history, ResourcePolicy* policy);
void activate_policy (History *history, ResourcePolicy *policy);
private:
private:
/**
\brief Private constructor.
*/
ResourcePoliciesGatekeeper(); //private constructor.
ResourcePoliciesGatekeeper (); //private constructor.
/**
\brief Private copy constructor.
*/
ResourcePoliciesGatekeeper(const ResourcePoliciesGatekeeper&);
ResourcePoliciesGatekeeper (const ResourcePoliciesGatekeeper &);
/**
\brief Private assignment operator.
*/
ResourcePoliciesGatekeeper& operator=(const ResourcePoliciesGatekeeper&);
ResourcePoliciesGatekeeper &operator= (const ResourcePoliciesGatekeeper &);
void deactivate_policies(const ResourcePolicyManager& manager);
void deactivate_policies (const ResourcePolicyManager &manager);
/**
\brief Container of registered managers.
*/
Managers _registered;
Managers _registered;
/**
\brief Container of active policies.
*/
std::map<History*, ResourcePolicy*> _active_policies;
};
std::map<History *, ResourcePolicy *> _active_policies;
};
}//~ namespace sgpem
} // namespace sgpem
#endif //RESOURCE_POLICIES_GATEKEEPER_HH

View File

@ -23,41 +23,39 @@
namespace sgpem
{
class ResourcePolicy;
class ResourcePolicy;
}
#include "gettext.h"
#include <sgpemv2/sgpemv2-visibility.hh>
#include <sgpemv2/policy_parameters.hh>
#include <sgpemv2/user_interrupt_exception.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/policy_parameters.hh>
#include <sgpemv2/sgpemv2-visibility.hh>
#include <sgpemv2/sub_request.hh>
#include <sgpemv2/user_interrupt_exception.hh>
#include <glibmm/ustring.h>
namespace sgpem
{
/// \brief A resource allocation policy.
///
/// A resource allocation policy manages the queues of requests.
/// Its purpose is to decide which threads may use the available
/// resources first.
class SG_DLLEXPORT ResourcePolicy
{
public:
/// \brief A resource allocation policy.
///
/// A resource allocation policy manages the queues of requests.
/// Its purpose is to decide which threads may use the available
/// resources first.
class SG_DLLEXPORT ResourcePolicy
{
public:
/// \brief Standard virtual destructor.
///
/// Standard virtual destructor.
virtual ~ResourcePolicy();
virtual ~ResourcePolicy ();
/// \brief Initializes the inner components of the policy.
///
/// Because it's a pure virtual method, must be re-implemented
/// in concrete derived classes.
virtual void configure() = 0;
virtual void configure () = 0;
/// \brief Sorts the subrequest queue.
///
@ -67,7 +65,7 @@ namespace sgpem
/// \param environment the environment on which the policy applies.
/// \param queue the queue where a subrequest has just been added.
/// \param sr the subrequest which has just been added.
virtual void enforce(Environment& environment, Environment::SubRequestQueue& queue, SubRequest& sr) = 0;
virtual void enforce (Environment &environment, Environment::SubRequestQueue &queue, SubRequest &sr) = 0;
/// \brief Returns a description of the policy.
///
@ -75,7 +73,7 @@ namespace sgpem
/// in concrete derived classes.
/// Returns a description of the policy.
/// \return a description of the policy.
virtual Glib::ustring get_description() const = 0;
virtual Glib::ustring get_description () const = 0;
/// \brief Returns the name of the policy.
///
@ -83,32 +81,32 @@ namespace sgpem
/// in concrete derived classes.
/// Returns the name of the policy.
/// \return the name of the policy.
virtual Glib::ustring get_name() const = 0;
virtual Glib::ustring get_name () const = 0;
/// \brief Activates the policy.
///
/// Because it's a pure virtual method, must be re-implemented
/// in concrete derived classes.
virtual void activate() = 0;
virtual void activate () = 0;
/// \brief Deactivates the policy.
///
/// Because it's a pure virtual method, must be re-implemented
/// in concrete derived classes.
virtual void deactivate() = 0;
virtual void deactivate () = 0;
/// \brief Returns the parameters used to customize the policy.
///
/// Returns the parameters used to customize the policy.
/// The user may modify them directly.
/// \return the parameters used to customize the policy.
PolicyParameters& get_parameters();
PolicyParameters &get_parameters ();
protected:
protected:
PolicyParameters _parameters;
};
};
}//~ namespace sgpem
} // namespace sgpem
#endif

View File

@ -23,7 +23,7 @@
namespace sgpem
{
class ResourcePolicy;
class ResourcePolicy;
}
#include <sgpemv2/sgpemv2-visibility.hh>
@ -33,28 +33,27 @@ namespace sgpem
namespace sgpem
{
class ResourcePolicyManager;
class ResourcePolicyManager;
/**
/**
ResourcePolicyManager is the Abstract Factory for \ref ResourcePolicy objects.
*/
class SG_DLLEXPORT ResourcePolicyManager
{
public:
class SG_DLLEXPORT ResourcePolicyManager
{
public:
typedef ResourcePolicy Policy;
typedef std::vector<Policy*> Policies;
typedef std::vector<Policy *> Policies;
/** \brief ResourcePolicyManager constructor
*
* Registers itself to the ResourcePoliciesGatekeeper singleton.
*/
ResourcePolicyManager();
ResourcePolicyManager ();
virtual ~ResourcePolicyManager();
virtual ~ResourcePolicyManager ();
virtual const Policies& get_avail_policies() const = 0;
};
virtual const Policies &get_avail_policies () const = 0;
};
} //~ namespace sgpem
} // namespace sgpem
#endif // ~ RESOURCE_POLICY_MANAGER_HH

View File

@ -27,22 +27,21 @@
namespace sgpem
{
/// \brief Represents a schedulable entity within the simulated system.
///
/// Represents a schedulable entity within the simulated system.
/// Real world schedulable entities are, for example: batch jobs, processes
/// threads, fibers.
/// This class factors out some of their features.
///
/// This is an abstract class. Known subclasses are ::Process, and ::Thread
class Schedulable;
/// \brief Represents a schedulable entity within the simulated system.
///
/// Represents a schedulable entity within the simulated system.
/// Real world schedulable entities are, for example: batch jobs, processes
/// threads, fibers.
/// This class factors out some of their features.
///
/// This is an abstract class. Known subclasses are ::Process, and ::Thread
class Schedulable;
class SerializeVisitor;
class SG_DLLEXPORT Schedulable
{
public:
class SerializeVisitor;
class SG_DLLEXPORT Schedulable
{
public:
/// \brief This flag describes the actual state of the schedulable.
///
/// You can think of this flag as the particular stack in the OS where the
@ -51,17 +50,17 @@ namespace sgpem
/// processes. These are emulated in a single list by this flag.
enum state
{
state_running = 1 << 0,
state_ready = 1 << 1,
state_blocked = 1 << 2,
state_future = 1 << 3,
state_terminated = 1 << 4
state_running = 1 << 0,
state_ready = 1 << 1,
state_blocked = 1 << 2,
state_future = 1 << 3,
state_terminated = 1 << 4
};
/// \brief Virtual destructor
///
/// Abstract virtual destructor
virtual ~Schedulable() = 0;
virtual ~Schedulable () = 0;
/// \brief Redefined operator equals (static equality).
///
@ -73,14 +72,14 @@ namespace sgpem
/// time and elapsed time do count.
/// \param op2 the Schedulable to compare this with.
/// \return true if the Schedulable equal, false otherwise.
virtual bool operator==(const Schedulable& op2) const = 0;
virtual bool operator== (const Schedulable &op2) const = 0;
/// \brief Returns the name of the Schedulable.
///
/// Returns the name of the Schedulable.
/// \return the name of the Schedulable.
virtual Glib::ustring get_name() const = 0;
virtual Glib::ustring get_name () const = 0;
/// \brief Returns the arrival time of the Schedulable.
///
@ -91,7 +90,7 @@ namespace sgpem
///
/// The arrival time is a static (respect to the simulation) property.
/// \return the arrival time of the Schedulable.
virtual unsigned int get_arrival_time() const = 0;
virtual unsigned int get_arrival_time () const = 0;
/// \brief Returns the elapsed time of the Schedulable.
///
@ -101,7 +100,7 @@ namespace sgpem
///
/// The elapsed time is a dynamic (respect to the simulation) property.
/// \return the elapsed time of the Schedulable.
virtual unsigned int get_elapsed_time() const = 0;
virtual unsigned int get_elapsed_time () const = 0;
/// \brief Returns the remaining time of the Schedulable.
///
@ -114,7 +113,7 @@ namespace sgpem
///
/// The remaining time is a dynamic (respect to the simulation) property.
/// \return the remaining time of the Schedulable.
virtual unsigned int get_remaining_time() const;
virtual unsigned int get_remaining_time () const;
/// \brief Returns the last aquisition instant of the Schedulable.
///
@ -127,7 +126,7 @@ namespace sgpem
///
/// The last aquisition instant is a dynamic (respect to the simulation) property.
/// \return the last aquisition instant of the Schedulable.
virtual int get_last_acquisition() const = 0;
virtual int get_last_acquisition () const = 0;
/// \brief Returns the last release instant of the Schedulable.
///
@ -140,7 +139,7 @@ namespace sgpem
///
/// The last release instant is a dynamic (respect to the simulation) property.
/// \return the last release instant of the Schedulable.
virtual int get_last_release() const = 0;
virtual int get_last_release () const = 0;
/// \brief Returns the base priority of the Schedulable.
///
@ -154,7 +153,7 @@ namespace sgpem
///
/// The base priority is a static (respect to the simulation) property.
/// \return the base priority of the Schedulable.
virtual int get_base_priority() const = 0;
virtual int get_base_priority () const = 0;
/// \brief Returns the total required CPU time of the Schedulable.
///
@ -167,7 +166,7 @@ namespace sgpem
///
/// The total required CPU time is a static (respect to the simulation) property.
/// \return the total required CPU time of the Schedulable.
virtual unsigned int get_total_cpu_time() const = 0;
virtual unsigned int get_total_cpu_time () const = 0;
/// \brief Returns the current priority of the Schedulable.
///
@ -181,7 +180,7 @@ namespace sgpem
///
/// The current priority is a dynamic (respect to the simulation) property.
/// \return the dynamic priority of the Schedulable.
virtual int get_current_priority() const = 0;
virtual int get_current_priority () const = 0;
/// \brief Returns the current priority push of the Schedulable.
///
@ -195,7 +194,7 @@ namespace sgpem
///
/// The priority push is a dynamic (respect to the simulation) property.
/// \return the current priority push of the Schedulable.
virtual int get_priority_push() const;
virtual int get_priority_push () const;
/// \brief Sets the priority push of the Schedulable, returning the old one.
///
@ -210,7 +209,7 @@ namespace sgpem
/// The priority push is a dynamic (respect to the simulation) property.
/// \param new_value the new push to be set.
/// \return the old priority push of the Schedulable.
virtual int set_priority_push(int new_value = 0) = 0;
virtual int set_priority_push (int new_value = 0) = 0;
/// \brief Returns the current state of the Schedulable.
///
@ -221,13 +220,13 @@ namespace sgpem
///
/// The current state is a dynamic (respect to the simulation) property.
/// \return the current state of the Schedulable.
virtual state get_state() const = 0;
virtual state get_state () const = 0;
/// \brief Serializes this entity using a visitor pattern.
///
/// \param translator the visitor used to serialize this entity.
virtual void serialize(SerializeVisitor& translator) const = 0;
};
}
virtual void serialize (SerializeVisitor &translator) const = 0;
};
} // namespace sgpem
#endif

View File

@ -29,80 +29,79 @@
namespace sgpem
{
/** \brief Represents the statistics of a Schedulable
/** \brief Represents the statistics of a Schedulable
Represents the statistics of a Schedulable. This class is created by "Statistics" class
and presents only "getters" methods which execute no calculations: they only return the
internal results calulated at construction time. To retrieve these results the whole History
(until the instant specified through Statistics::calculateStatisticsAt(int)) is scanned.
*/
class SchedulableStatistics
{
public:
virtual ~SchedulableStatistics();
class SchedulableStatistics
{
public:
virtual ~SchedulableStatistics ();
/** \brief Returns the total execution time
/** \brief Returns the total execution time
\returns the number of instants during which the state of the schedulable was "running"
*/
virtual int get_execution_time() const =0;
virtual int get_execution_time () const = 0;
/** \brief Returns the percentage of the execution
/** \brief Returns the percentage of the execution
\returns the number of instants during which the state of the schedulable was "running"
divided by the total running time of the schedulable
*/
virtual int get_execution_progress() const =0;
virtual int get_execution_progress () const = 0;
/** \brief Returns the total incativity time
/** \brief Returns the total incativity time
\returns the number of instants during which the state of the schedulable was "ready" or "blocked"
*/
virtual int get_total_inactivity() const =0;
virtual int get_total_inactivity () const = 0;
/** \brief Returns the response time of the schedulable
/** \brief Returns the response time of the schedulable
\returns the number of instants during which the state of the schedulable was "ready" or "blocked"
before the first execution instant
*/
virtual int get_response_time() const =0;
virtual int get_response_time () const = 0;
/** \brief Returns the turn-around time of the schedulable
/** \brief Returns the turn-around time of the schedulable
\returns the number of instants during which the state of the schedulable was "ready" or "blocked"
or "running"
*/
virtual int get_turn_around() const =0;
virtual int get_turn_around () const = 0;
/** \brief Returns the percentage of the execution efficiency
/** \brief Returns the percentage of the execution efficiency
\returns The percentage of the efficiency. This value is calucated this way: turn_around/execution_time
*/
virtual int get_efficiency() const =0;
virtual int get_efficiency () const = 0;
/** \brief Returns the resources usage time of the schedulable
/** \brief Returns the resources usage time of the schedulable
\returns the number of instants during which the the schedulable used a resource. If the schedulable
used more than one resource a time then this value is increased accordingly.
*/
virtual int get_resource_usage_time() const =0;
virtual int get_resource_usage_time () const = 0;
/** \brief Returns the number of instants this schedulable was waiting for a resource to be allocable
/** \brief Returns the number of instants this schedulable was waiting for a resource to be allocable
\returns the number of instants during which the state of the schedulable was "blocked"
*/
virtual int get_resource_waitings_time() const =0;
virtual int get_resource_waitings_time () const = 0;
/** \brief Returns the Schedulable object these statistics refer to
/** \brief Returns the Schedulable object these statistics refer to
\returns Returns a const pointer to the Schedulable object these statistics refer to
*/
virtual const Schedulable* get_core() const =0;
virtual const Schedulable *get_core () const = 0;
protected:
protected:
SchedulableStatistics ();
SchedulableStatistics();
int _execution_time;
int _execution_progress;
int _total_inactivity;
int _response_time;
int _turn_around;
int _efficiency;
int _resource_usage_time;
int _resource_waitings_time;
};
}
int _execution_time;
int _execution_progress;
int _total_inactivity;
int _response_time;
int _turn_around;
int _efficiency;
int _resource_usage_time;
int _resource_waitings_time;
};
} // namespace sgpem
#endif

View File

@ -22,18 +22,18 @@
#define SCHEDULER_HH 1
namespace sgpem
{
class Scheduler;
class CPUPolicy;
}
class Scheduler;
class CPUPolicy;
} // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/cpu_policy.hh>
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/ready_queue.hh>
#include <sgpemv2/user_interrupt_exception.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/malformed_policy_exception.hh>
#include <sgpemv2/ready_queue.hh>
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/user_interrupt_exception.hh>
// Do not include full template definition here
#include <sgpemv2/templates/singleton.hh>
@ -42,10 +42,10 @@ namespace sgpem
namespace sgpem
{
class Scheduler;
class Scheduler;
/** \brief Manages the DynamicSchedulable objects, implementing a given policy.
/** \brief Manages the DynamicSchedulable objects, implementing a given policy.
Class Scheduler manages the schedulable entities which are ready to run,
ordering them in a queue; it also checks that the current scheduling policy
@ -56,10 +56,11 @@ namespace sgpem
*/
class SG_DLLEXPORT Scheduler : public Singleton<Scheduler>
{
class SG_DLLEXPORT Scheduler : public Singleton<Scheduler>
{
friend class Singleton<Scheduler>;
public:
public:
/**
Generates a new ReadyQueue representing the status of the processes
at the simulation instant next to the current one, and extends the History by
@ -68,7 +69,7 @@ namespace sgpem
\return false If the simulation has ended, true otherwise
*/
bool step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy& resource_policy);
bool step_forward (History &history, CPUPolicy &cpu_policy, ResourcePolicy &resource_policy);
/**
\brief Returns the policy that will be used to generate the simulation at the next instant.
@ -77,7 +78,7 @@ namespace sgpem
by step_forward(). Else, a nullptr pointer will be returned.
\return A pointer to the active policy, or nullptr if not inside step_forward()
*/
CPUPolicy* get_policy();
CPUPolicy *get_policy ();
/**
\brief Returns a pointer to the queue containing all the ready
@ -87,17 +88,17 @@ namespace sgpem
by step_forward(). Else, a nullptr pointer will be returned.
\return A pointer to the queue, or nullptr if not inside step_forward()
*/
ReadyQueue* get_ready_queue();
ReadyQueue *get_ready_queue ();
private:
Scheduler(); //private constructor.
private:
Scheduler (); //private constructor.
ReadyQueue* _ready_queue;
CPUPolicy* _policy;
ReadyQueue *_ready_queue;
CPUPolicy *_policy;
Glib::Mutex _step_mutex;
};
Glib::Mutex _step_mutex;
};
}//~ namespace sgpem
} // namespace sgpem
#endif //SCHEDULER_HH

View File

@ -23,14 +23,14 @@
namespace sgpem
{
class History;
class Environment;
class Resource;
class Process;
class Thread;
class Request;
class SubRequest;
}
class History;
class Environment;
class Resource;
class Process;
class Thread;
class Request;
class SubRequest;
} // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh>
@ -40,63 +40,62 @@ namespace sgpem
namespace sgpem
{
class SerializeVisitor;
class SerializeVisitor;
/**
/**
\brief Interface class to serialize data
This class is a virtual class and each method must be reimplemented
in derived classes to have effective serialization.
*/
class SG_DLLEXPORT SerializeVisitor
{
public:
virtual ~SerializeVisitor() = 0;
class SG_DLLEXPORT SerializeVisitor
{
public:
virtual ~SerializeVisitor () = 0;
/**
\brief Add output to the serializer taking data from history
*/
virtual void from_history(const History& obj) = 0;
virtual void from_history (const History &obj) = 0;
/**
\brief Add output to the serializer taking data from environment
*/
virtual void from_environment(const Environment& obj) = 0;
virtual void from_environment (const Environment &obj) = 0;
/**
\brief Add output to the serializer taking data from resource
BUG: a resource must be saved with her own associated key.
*/
virtual void from_resource(const Resource& obj) = 0;
virtual void from_resource (const Resource &obj) = 0;
/**
\brief Add output to the serializer taking data from resource and key
BUG FIXED: This save a resource with her own associated key.
*/
virtual void from_resource(const Resource& obj, const Glib::ustring& key) = 0;
virtual void from_resource (const Resource &obj, const Glib::ustring &key) = 0;
/**
\brief Add output to the serializer taking data from process
*/
virtual void from_process(const Process& obj) = 0;
virtual void from_process (const Process &obj) = 0;
/**
\brief Add output to the serializer taking data from thread
*/
virtual void from_thread(const Thread& obj) = 0;
virtual void from_thread (const Thread &obj) = 0;
/**
\brief Add output to the serializer taking data from request
*/
virtual void from_request(const Request& obj) = 0;
virtual void from_request (const Request &obj) = 0;
/**
\brief Add output to the serializer taking data from subrequest
*/
virtual void from_subrequest(const SubRequest& obj) = 0;
};
}
virtual void from_subrequest (const SubRequest &obj) = 0;
};
} // namespace sgpem
#endif

Some files were not shown because too many files have changed in this diff Show More