Reformat using clang-format
This commit is contained in:
parent
c1ac6f279b
commit
ffd4b6b319
|
@ -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 **/
|
||||
|
||||
_add_button->signal_clicked().connect(
|
||||
sigc::mem_fun(*this, &AddRequestDialog::_on_add));
|
||||
/** ATTACH SIGNAL HANDLERS FOR BUTTONS **/
|
||||
|
||||
_remove_button->signal_clicked().connect(
|
||||
sigc::mem_fun(*this, &AddRequestDialog::_on_remove));
|
||||
_add_button->signal_clicked ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_add));
|
||||
|
||||
_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);
|
||||
_remove_button->signal_clicked ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_remove));
|
||||
|
||||
_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);
|
||||
_ok_button->set_sensitive (false);
|
||||
_remove_button->set_sensitive (false);
|
||||
_add_button->set_sensitive (false);
|
||||
|
||||
_resource_combo->signal_changed().connect(
|
||||
sigc::mem_fun(*this, &AddRequestDialog::_on_combo_selection_changed));
|
||||
|
||||
/** INITIALIZE LISTVIEW **/
|
||||
|
||||
_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);
|
||||
/** INITIALIZE COMBOBOX **/
|
||||
_combo_columns.add (_combo_key_column);
|
||||
_combo_columns.add (_combo_resource_column);
|
||||
|
||||
_list_model->signal_row_deleted().connect(
|
||||
sigc::mem_fun(*this, &AddRequestDialog::_on_row_removed));
|
||||
_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);
|
||||
|
||||
_list_model->signal_row_inserted().connect(
|
||||
sigc::mem_fun(*this, &AddRequestDialog::_on_row_added));
|
||||
_resource_combo->signal_changed ().connect (sigc::mem_fun (*this, &AddRequestDialog::_on_combo_selection_changed));
|
||||
|
||||
_list->append_column(_("key"), _list_key_column);
|
||||
_list->append_column(_("resource"), _list_resource_column);
|
||||
_list->append_column(_("duration"), _list_duration_column);
|
||||
/** INITIALIZE LISTVIEW **/
|
||||
|
||||
_list->get_selection()->signal_changed().connect(
|
||||
sigc::mem_fun(*this, &AddRequestDialog::_on_list_selection_changed));
|
||||
_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->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->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));
|
||||
}
|
||||
|
||||
Request*
|
||||
AddRequestDialog::run_add(sgpem::Thread& owner)
|
||||
Request *
|
||||
AddRequestDialog::run_add (sgpem::Thread &owner)
|
||||
{
|
||||
update_combo();
|
||||
update_combo ();
|
||||
|
||||
Request* r = nullptr;
|
||||
|
||||
// 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());
|
||||
Request *r = nullptr;
|
||||
|
||||
History& h = Simulation::get_instance().get_history();
|
||||
// reset the dialog data
|
||||
// _list_model->clear();
|
||||
// _instant_spin->set_value(0.0);
|
||||
// _duration_spin->set_value(0.0);
|
||||
|
||||
r = &h.add_request(owner, _instant_spin->get_value_as_int());
|
||||
if (run () == RESPONSE_OK)
|
||||
{
|
||||
assert (_list_model->children ());
|
||||
|
||||
TreeNodeChildren sreq_container = _list_model->children();
|
||||
History &h = Simulation::get_instance ().get_history ();
|
||||
|
||||
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it)
|
||||
h.add_subrequest(*r, (*it)[_list_key_column], (*it)[_list_duration_column]);
|
||||
}
|
||||
r = &h.add_request (owner, _instant_spin->get_value_as_int ());
|
||||
|
||||
hide();
|
||||
TreeNodeChildren sreq_container = _list_model->children ();
|
||||
|
||||
return r;
|
||||
for (Iseq<TreeIter> it = iseq (sreq_container); it; ++it)
|
||||
h.add_subrequest (*r, (*it)[_list_key_column], (*it)[_list_duration_column]);
|
||||
}
|
||||
|
||||
hide ();
|
||||
|
||||
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();
|
||||
|
||||
_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();
|
||||
History &history = Simulation::get_instance ().get_history ();
|
||||
const Environment::Resources &resources = history.get_last_environment ().get_resources ();
|
||||
|
||||
for(Iseq<vector<SubRequest*>::iterator> it = iseq(subrequests); it; ++it)
|
||||
{
|
||||
SubRequest& sr = *(*it);
|
||||
_instant_spin->set_value (static_cast<double> (request.get_instant ()));
|
||||
|
||||
TreeModel::Row row = *(_list_model->append());
|
||||
// PLEASE KEEP THIS A COPY, WE *NEED* TO COPY IT
|
||||
vector<SubRequest *> subrequests = request.get_subrequests ();
|
||||
|
||||
unsigned int key = sr.get_resource_key();
|
||||
row[_list_key_column] = key;
|
||||
for (Iseq<vector<SubRequest *>::iterator> it = iseq (subrequests); it; ++it)
|
||||
{
|
||||
SubRequest &sr = *(*it);
|
||||
|
||||
const ustring name = resources.find(key)->second->get_name();
|
||||
row[_list_resource_column] = name;
|
||||
TreeModel::Row row = *(_list_model->append ());
|
||||
|
||||
row[_list_duration_column] = sr.get_length();
|
||||
}
|
||||
unsigned int key = sr.get_resource_key ();
|
||||
row[_list_key_column] = key;
|
||||
|
||||
if(run() == RESPONSE_OK)
|
||||
{
|
||||
assert(_list_model->children());
|
||||
const ustring name = resources.find (key)->second->get_name ();
|
||||
row[_list_resource_column] = name;
|
||||
|
||||
History::LockNotify h_lock(history);
|
||||
row[_list_duration_column] = sr.get_length ();
|
||||
}
|
||||
|
||||
// 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));
|
||||
if (run () == RESPONSE_OK)
|
||||
{
|
||||
assert (_list_model->children ());
|
||||
|
||||
history.edit_request(request, _instant_spin->get_value_as_int());
|
||||
History::LockNotify h_lock (history);
|
||||
|
||||
TreeNodeChildren sreq_container = _list_model->children();
|
||||
// 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));
|
||||
|
||||
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it)
|
||||
history.add_subrequest(request, (*it)[_list_key_column], (*it)[_list_duration_column]);
|
||||
}
|
||||
history.edit_request (request, _instant_spin->get_value_as_int ());
|
||||
|
||||
hide();
|
||||
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]);
|
||||
}
|
||||
|
||||
hide ();
|
||||
}
|
||||
|
||||
void
|
||||
AddRequestDialog::update_combo()
|
||||
AddRequestDialog::update_combo ()
|
||||
{
|
||||
typedef Environment::Resources::const_iterator ResourceIt;
|
||||
|
||||
const Environment::Resources& resources =
|
||||
Simulation::get_instance().get_history().get_last_environment().get_resources();
|
||||
|
||||
_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();
|
||||
}
|
||||
|
||||
Dialog::on_show();
|
||||
typedef Environment::Resources::const_iterator ResourceIt;
|
||||
|
||||
const Environment::Resources &resources = Simulation::get_instance ().get_history ().get_last_environment ().get_resources ();
|
||||
|
||||
_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 ();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
AddRequestDialog::_on_list_selection_changed()
|
||||
{
|
||||
_remove_button->set_sensitive(
|
||||
_list->get_selection()->count_selected_rows() > 0);
|
||||
TreeModel::iterator it = _list->get_selection ()->get_selected ();
|
||||
_list_model->erase (it);
|
||||
}
|
||||
|
||||
void
|
||||
AddRequestDialog::_on_row_added(const Gtk::TreePath&, const Gtk::TreeIter&)
|
||||
AddRequestDialog::_on_list_selection_changed ()
|
||||
{
|
||||
_ok_button->set_sensitive(true);
|
||||
_remove_button->set_sensitive (_list->get_selection ()->count_selected_rows () > 0);
|
||||
}
|
||||
|
||||
void
|
||||
AddRequestDialog::_on_row_removed(const Gtk::TreePath&)
|
||||
void
|
||||
AddRequestDialog::_on_row_added (const Gtk::TreePath &, const Gtk::TreeIter &)
|
||||
{
|
||||
_ok_button->set_sensitive(static_cast<bool>(_list_model->children()));
|
||||
_ok_button->set_sensitive (true);
|
||||
}
|
||||
|
||||
void
|
||||
AddRequestDialog::_on_combo_selection_changed()
|
||||
void
|
||||
AddRequestDialog::_on_row_removed (const Gtk::TreePath &)
|
||||
{
|
||||
_add_button->set_sensitive(static_cast<bool>(_resource_combo->get_active()));
|
||||
_ok_button->set_sensitive (static_cast<bool> (_list_model->children ()));
|
||||
}
|
||||
|
||||
void
|
||||
AddRequestDialog::_on_combo_selection_changed ()
|
||||
{
|
||||
_add_button->set_sensitive (static_cast<bool> (_resource_combo->get_active ()));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
private:
|
||||
void run_edit (Request &request);
|
||||
|
||||
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
|
||||
|
|
|
@ -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 ----------------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
bool _sealed;
|
||||
}
|
||||
; //~ class ConcreteHistory
|
||||
ConcreteHistory &operator= (const ConcreteHistory &op2);
|
||||
|
||||
}//~ namespace sgpem
|
||||
bool _sealed;
|
||||
}; //~ class ConcreteHistory
|
||||
|
||||
} // namespace sgpem
|
||||
|
||||
#endif //~ CONCRETE_HISTORY_HH
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
//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();
|
||||
|
||||
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(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();
|
||||
}
|
||||
}
|
||||
|
||||
//******* 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++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//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;
|
||||
|
||||
if (_turn_around == 0)
|
||||
_efficiency = -1;
|
||||
else
|
||||
_efficiency = (_execution_time*100)/_turn_around;
|
||||
|
||||
_response_time = min_reponse;
|
||||
|
||||
if (arrived_threads != 0)
|
||||
_average_response_time = (float)((int)((_average_response_time/arrived_threads)*100))/100;
|
||||
//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"
|
||||
|
||||
_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 && 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 ((*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 ();
|
||||
|
||||
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;
|
||||
|
||||
_total_inactivity = _turn_around - _execution_time;
|
||||
|
||||
if (_turn_around == 0)
|
||||
_efficiency = -1;
|
||||
else
|
||||
_efficiency = (_execution_time * 100) / _turn_around;
|
||||
|
||||
_response_time = min_reponse;
|
||||
|
||||
if (arrived_threads != 0)
|
||||
_average_response_time = (float) ((int) ((_average_response_time / arrived_threads) * 100)) / 100;
|
||||
}
|
||||
|
||||
|
||||
ConcreteProcessStatistics::~ConcreteProcessStatistics()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_execution_time() const
|
||||
ConcreteProcessStatistics::~ConcreteProcessStatistics ()
|
||||
{
|
||||
return _execution_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_execution_progress() const
|
||||
{
|
||||
return _execution_progress;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_total_inactivity() const
|
||||
{
|
||||
return _total_inactivity;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_response_time() const
|
||||
{
|
||||
return _response_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_turn_around() const
|
||||
{
|
||||
return _turn_around;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_efficiency() const
|
||||
ConcreteProcessStatistics::get_execution_time () const
|
||||
{
|
||||
return _efficiency;
|
||||
return _execution_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_resource_usage_time() const
|
||||
ConcreteProcessStatistics::get_execution_progress () const
|
||||
{
|
||||
return _resource_usage_time;
|
||||
return _execution_progress;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_resource_waitings_time() const
|
||||
ConcreteProcessStatistics::get_total_inactivity () const
|
||||
{
|
||||
return _resource_waitings_time;
|
||||
return _total_inactivity;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_response_time () const
|
||||
{
|
||||
return _response_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_turn_around () const
|
||||
{
|
||||
return _turn_around;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_efficiency () const
|
||||
{
|
||||
return _efficiency;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_resource_usage_time () const
|
||||
{
|
||||
return _resource_usage_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteProcessStatistics::get_resource_waitings_time () const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
int started_schedulables_count = 0; //useful for stats thath can be -1
|
||||
|
||||
if (instant == -1)
|
||||
return;
|
||||
|
||||
//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)
|
||||
_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
|
||||
|
||||
if (instant == -1)
|
||||
return;
|
||||
|
||||
//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++)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
|
||||
//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 ();
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
//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
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_inactivity_time () const
|
||||
{
|
||||
return _average_inactivity_time;
|
||||
return _average_inactivity_time;
|
||||
}
|
||||
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_execution_progress() const
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_execution_progress () const
|
||||
{
|
||||
return _average_execution_progress;
|
||||
return _average_execution_progress;
|
||||
}
|
||||
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_turn_around() const
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_turn_around () const
|
||||
{
|
||||
return _average_turn_around;
|
||||
return _average_turn_around;
|
||||
}
|
||||
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_response_time() const
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_response_time () const
|
||||
{
|
||||
return _average_response_time;
|
||||
return _average_response_time;
|
||||
}
|
||||
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_efficiency() const
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_efficiency () const
|
||||
{
|
||||
return _average_efficiency;
|
||||
return _average_efficiency;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteSimulationStatistics::get_terminated_processes() const
|
||||
int
|
||||
ConcreteSimulationStatistics::get_terminated_processes () const
|
||||
{
|
||||
return _terminated_processes;
|
||||
return _terminated_processes;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteSimulationStatistics::get_terminated_threads() const
|
||||
int
|
||||
ConcreteSimulationStatistics::get_terminated_threads () const
|
||||
{
|
||||
return _terminated_threads;
|
||||
return _terminated_threads;
|
||||
}
|
||||
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_processes_throughput() const
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_processes_throughput () const
|
||||
{
|
||||
return _average_processes_throughput;
|
||||
return _average_processes_throughput;
|
||||
}
|
||||
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_threads_throughput() const
|
||||
float
|
||||
ConcreteSimulationStatistics::get_average_threads_throughput () const
|
||||
{
|
||||
return _average_threads_throughput;
|
||||
return _average_threads_throughput;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -19,61 +19,58 @@
|
|||
|
||||
|
||||
#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>
|
||||
|
||||
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)
|
||||
void
|
||||
ConcreteStatistics::calculateStatisticsAt (const int &instant)
|
||||
{
|
||||
//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));
|
||||
|
||||
if (_sim_stats)
|
||||
delete _sim_stats;
|
||||
//create simulation statistics using just obtained process statistics
|
||||
_sim_stats = new ConcreteSimulationStatistics(_proc_stats, instant);
|
||||
//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));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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();
|
||||
|
||||
//****** 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++;
|
||||
|
||||
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++;
|
||||
|
||||
res_iter++;
|
||||
}
|
||||
|
||||
}//istants
|
||||
|
||||
//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;
|
||||
//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
|
||||
|
||||
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 ();
|
||||
|
||||
//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
|
||||
|
||||
|
||||
//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++;
|
||||
}
|
||||
|
||||
} //istants
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
|
||||
ConcreteThreadStatistics::~ConcreteThreadStatistics()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_execution_time() const
|
||||
ConcreteThreadStatistics::~ConcreteThreadStatistics ()
|
||||
{
|
||||
return _execution_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_execution_progress() const
|
||||
{
|
||||
return _execution_progress;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_total_inactivity() const
|
||||
{
|
||||
return _total_inactivity;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_response_time() const
|
||||
{
|
||||
return _response_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_turn_around() const
|
||||
{
|
||||
return _turn_around;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_efficiency() const
|
||||
ConcreteThreadStatistics::get_execution_time () const
|
||||
{
|
||||
return _efficiency;
|
||||
return _execution_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_resource_usage_time() const
|
||||
ConcreteThreadStatistics::get_execution_progress () const
|
||||
{
|
||||
return _resource_usage_time;
|
||||
return _execution_progress;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_resource_waitings_time() const
|
||||
ConcreteThreadStatistics::get_total_inactivity () const
|
||||
{
|
||||
return _resource_waitings_time;
|
||||
return _total_inactivity;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_real_arrival_time() const
|
||||
ConcreteThreadStatistics::get_response_time () const
|
||||
{
|
||||
return _real_arrival_time;
|
||||
return _response_time;
|
||||
}
|
||||
|
||||
const Thread*
|
||||
ConcreteThreadStatistics::get_core() const
|
||||
int
|
||||
ConcreteThreadStatistics::get_turn_around () const
|
||||
{
|
||||
return _core;
|
||||
return _turn_around;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_efficiency () const
|
||||
{
|
||||
return _efficiency;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_resource_usage_time () const
|
||||
{
|
||||
return _resource_usage_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_resource_waitings_time () const
|
||||
{
|
||||
return _resource_waitings_time;
|
||||
}
|
||||
|
||||
int
|
||||
ConcreteThreadStatistics::get_real_arrival_time () const
|
||||
{
|
||||
return _real_arrival_time;
|
||||
}
|
||||
|
||||
const Thread *
|
||||
ConcreteThreadStatistics::get_core () const
|
||||
{
|
||||
return _core;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
@ -72,10 +71,10 @@ namespace sgpem
|
|||
/// the state of the Schedulable is switched from future to
|
||||
/// ready.
|
||||
///
|
||||
/// The arrival time is a static (respect to the simulation) property.
|
||||
/// 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,26 +89,26 @@ 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.
|
||||
///
|
||||
/// Returns the total required CPU time of the Schedulable.
|
||||
/// The total required CPU time is the time the Schedulable needs to
|
||||
/// The total required CPU time is the time the Schedulable needs to
|
||||
/// complete its work.
|
||||
///
|
||||
///
|
||||
/// When a Schedulable's elapsed CPU time equals the total required CPU time
|
||||
/// its state is set to "terminated".
|
||||
/// its state is set to "terminated".
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Returns the current priority push of the Schedulable.
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// importance of the Schedulable. Priority-sensitive policies usually give
|
||||
/// better services to more important Schedulables.
|
||||
///
|
||||
|
@ -118,12 +117,12 @@ 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.
|
||||
///
|
||||
/// Sets the current priority push of the Schedulable.
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// importance of the Schedulable. Priority-sensitive policies usually give
|
||||
/// better services to more important Schedulables.
|
||||
///
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
using namespace sgpem;
|
||||
|
||||
|
||||
Environment::~Environment()
|
||||
{}
|
||||
|
||||
Environment::~Environment ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <sgpemv2/history_observer.hh>
|
||||
|
||||
sgpem::HistoryObserver::~HistoryObserver() {}
|
||||
sgpem::HistoryObserver::~HistoryObserver ()
|
||||
{
|
||||
}
|
||||
|
||||
// Pure abstract class. Nothing else to put here.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,12 @@ using Glib::ustring;
|
|||
|
||||
|
||||
// instantiate Parameter template for use outside this DSO
|
||||
namespace sgpem
|
||||
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));
|
||||
|
||||
float_map.insert(v);
|
||||
map<ustring, Parameter<float>>::value_type v (
|
||||
name, Parameter<float> (name, default_value, lower_bound, upper_bound, required, default_value));
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
|
||||
using namespace sgpem;
|
||||
|
||||
Process::~Process()
|
||||
{}
|
||||
|
||||
Process::~Process ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -22,12 +22,10 @@
|
|||
using namespace sgpem;
|
||||
|
||||
|
||||
ProcessStatistics::~ProcessStatistics()
|
||||
ProcessStatistics::~ProcessStatistics ()
|
||||
{
|
||||
}
|
||||
|
||||
ProcessStatistics::ProcessStatistics()
|
||||
ProcessStatistics::ProcessStatistics ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,66 +24,66 @@ using sgpem::ReadyQueue;
|
|||
using sgpem::Thread;
|
||||
|
||||
void
|
||||
ReadyQueue::swap(position a, position b)
|
||||
|
||||
{
|
||||
if (a == b) return;
|
||||
ReadyQueue::swap (position a, position b)
|
||||
|
||||
// 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;
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
|
||||
void
|
||||
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 ());
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
|
||||
using namespace sgpem;
|
||||
|
||||
Request::~Request()
|
||||
{}
|
||||
|
||||
Request::~Request ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
using namespace sgpem;
|
||||
|
||||
Resource::~Resource()
|
||||
Resource::~Resource ()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
|
||||
using namespace sgpem;
|
||||
|
||||
ResourcePolicy::~ResourcePolicy()
|
||||
{}
|
||||
|
||||
|
||||
PolicyParameters&
|
||||
ResourcePolicy::get_parameters()
|
||||
ResourcePolicy::~ResourcePolicy ()
|
||||
{
|
||||
return _parameters;
|
||||
}
|
||||
|
||||
|
||||
PolicyParameters &
|
||||
ResourcePolicy::get_parameters ()
|
||||
{
|
||||
return _parameters;
|
||||
}
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -22,11 +22,10 @@
|
|||
|
||||
using namespace sgpem;
|
||||
|
||||
SchedulableStatistics::SchedulableStatistics()
|
||||
SchedulableStatistics::SchedulableStatistics ()
|
||||
{
|
||||
}
|
||||
|
||||
SchedulableStatistics::~SchedulableStatistics()
|
||||
SchedulableStatistics::~SchedulableStatistics ()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ¤t = **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 = ¤t; // 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 = ¤t; // 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 ¤t = **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;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
|
||||
using namespace sgpem;
|
||||
|
||||
SerializeVisitor::~SerializeVisitor()
|
||||
{}
|
||||
|
||||
SerializeVisitor::~SerializeVisitor ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -5,4 +5,3 @@
|
|||
#define POLDIR "@policiesdir@"
|
||||
#define PLUGDIR "@plugindir@"
|
||||
#define EXAMPLESDIR "@examplesdir@"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
protected:
|
||||
PolicyParameters _parameters;
|
||||
static CPUPolicy *callback_get_policy ();
|
||||
|
||||
static void set_callback_policy(CPUPolicy* ptr = nullptr);
|
||||
protected:
|
||||
PolicyParameters _parameters;
|
||||
|
||||
private:
|
||||
static void set_callback_policy (CPUPolicy *ptr = nullptr);
|
||||
|
||||
private:
|
||||
// Used by callback_get_policy:
|
||||
static CPUPolicy* _callback_policy;
|
||||
static CPUPolicy *_callback_policy;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}//~ namespace sgpem
|
||||
} // namespace sgpem
|
||||
|
||||
#endif //~ CPU_POLICY_HH
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
namespace sgpem
|
||||
{
|
||||
class CPUPolicyManager;
|
||||
class CPUPolicyManager;
|
||||
}
|
||||
|
||||
#include <sgpemv2/sgpemv2-visibility.hh>
|
||||
|
@ -35,29 +35,29 @@ 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
|
||||
*
|
||||
* Registers the \b this pointer to the CPUPoliciesGatekeeper, so it can be accessed
|
||||
* 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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -30,75 +30,76 @@
|
|||
#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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -30,71 +30,69 @@
|
|||
|
||||
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.
|
||||
/// \throw InvalidPluginException If the DSO you're trying to load
|
||||
/// doesn't export a valid SGPEMv2 backend::Plugin interface.
|
||||
/// \param identifier A string with the DSO name without any file-extension
|
||||
/// \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
|
||||
/// 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
|
||||
/// 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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -24,45 +24,43 @@
|
|||
#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
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -23,49 +23,49 @@
|
|||
|
||||
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.
|
||||
* When unregistering a manager, care should be taken to ensure that
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -23,92 +23,90 @@
|
|||
|
||||
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
|
||||
/// 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.
|
||||
///
|
||||
/// Because it's a pure virtual method, must be re-implemented
|
||||
/// Because it's a pure virtual method, must be re-implemented
|
||||
/// in concrete derived classes.
|
||||
///
|
||||
/// \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.
|
||||
///
|
||||
/// Because it's a pure virtual method, must be re-implemented
|
||||
/// Because it's a pure virtual method, must be re-implemented
|
||||
/// 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.
|
||||
///
|
||||
/// Because it's a pure virtual method, must be re-implemented
|
||||
/// Because it's a pure virtual method, must be re-implemented
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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).
|
||||
///
|
||||
|
@ -69,18 +68,18 @@ namespace sgpem
|
|||
/// By design, a Schedulable entity equals an other schedulable entity
|
||||
/// when their static (respect to the simulation) properties are equal.
|
||||
/// This means, for example, that the priority push does not count when
|
||||
/// determining equality, nor state, last aquisition and last release
|
||||
/// determining equality, nor state, last aquisition and last release
|
||||
/// 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,33 +113,33 @@ 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.
|
||||
///
|
||||
/// Returns the last aquisition instant of the Schedulable.
|
||||
/// The last aquisition instant of a Schedulable is the last instant at witch
|
||||
/// its state changed from anything but "running" to "running", i.e. when it
|
||||
/// its state changed from anything but "running" to "running", i.e. when it
|
||||
/// received the cpu.
|
||||
///
|
||||
/// Its dual feature is the last release instant.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Returns the last release instant of the Schedulable.
|
||||
/// The last release instant of a Schedulable is the last instant at witch
|
||||
/// its state changed from "running" to anything but "running", i.e. when it
|
||||
/// its state changed from "running" to anything but "running", i.e. when it
|
||||
/// abandoned the cpu.
|
||||
///
|
||||
/// Its dual feature is the last aquisition instant.
|
||||
///
|
||||
/// 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,20 +153,20 @@ 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.
|
||||
///
|
||||
/// Returns the total required CPU time of the Schedulable.
|
||||
/// The total required CPU time is the time the Schedulable needs to
|
||||
/// The total required CPU time is the time the Schedulable needs to
|
||||
/// complete its work.
|
||||
///
|
||||
///
|
||||
/// When a Schedulable's elapsed CPU time equals the total required CPU time
|
||||
/// its state is set to "terminated".
|
||||
/// its state is set to "terminated".
|
||||
///
|
||||
/// 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,12 +180,12 @@ 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.
|
||||
///
|
||||
/// Returns the current priority push of the Schedulable.
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// importance of the Schedulable. Priority-sensitive policies usually give
|
||||
/// better services to more important Schedulables.
|
||||
///
|
||||
|
@ -195,12 +194,12 @@ 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.
|
||||
///
|
||||
/// Sets the current priority push of the Schedulable.
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// The current priority push of a Schedulable is an indicator of the local
|
||||
/// importance of the Schedulable. Priority-sensitive policies usually give
|
||||
/// better services to more important Schedulables.
|
||||
///
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,8 +78,8 @@ 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
|
||||
schedulable objects (for the policy to sort it).
|
||||
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue