Reformat using clang-format

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

View File

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

View File

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

View File

@ -36,182 +36,167 @@
using namespace sgpem; using namespace sgpem;
using namespace std; using namespace std;
ConcreteEnvironment::ConcreteEnvironment() ConcreteEnvironment::ConcreteEnvironment ()
{ {
// Nothing to do here. Really. // Nothing to do here. Really.
} }
ConcreteEnvironment::ConcreteEnvironment(const ConcreteEnvironment& ce) : ConcreteEnvironment::ConcreteEnvironment (const ConcreteEnvironment &ce)
Environment(ce), _resources(ce._resources), _processes(), _sched_queue(), _sreq_queues(ce._sreq_queues) : 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 ReadyQueue won't be copied. Pointers to objects contained into
// the ready queue _will_ have changed in the new one. The ready queue // 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. // 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 :-) // 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++)
{ {
const v3_t& reqs = (*it2)->get_requests(); for (Resources::iterator it = _resources.begin (); it != _resources.end (); it++)
for (it3_t it3 = reqs.begin(); it3 != reqs.end(); it3++) it->second = new DynamicResource (down_cast<const DynamicResource &> (*it->second));
{ }
// an optimization here: there is no reason in iterating through
// future or exausted requests. (Do you know why?) // DynamicProcess object need to be copied.
const v4_t& subr = (*it3)->get_subrequests(); // The deep copy is guaranteed by the DynamicProcess copy constructor
for (it4_t it4 = subr.begin(); it4 != subr.end(); it4++) {
{ const Processes &ce_proc = ce._processes;
SubRequest::state curr_state = (*it4)->get_state(); insert_iterator<Processes> dest (_processes, _processes.begin ());
if (curr_state != Request::state_future && curr_state != Request::state_exhausted) for (Iseq<Processes::const_iterator> orig = iseq (ce_proc); orig; orig++)
{ *dest++ = new DynamicProcess (down_cast<const DynamicProcess &> (**orig));
// 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;
}
}
}
}
}
} }
}
// 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 &
const Environment::Processes& ConcreteEnvironment::get_processes () const
ConcreteEnvironment::get_processes() const
{ {
return _processes; return _processes;
} }
ConcreteEnvironment::Processes &
ConcreteEnvironment::Processes& ConcreteEnvironment::get_processes ()
ConcreteEnvironment::get_processes()
{ {
return _processes; return _processes;
} }
const Environment::Resources &
const Environment::Resources& ConcreteEnvironment::get_resources () const
ConcreteEnvironment::get_resources() const
{ {
return _resources; return _resources;
} }
ConcreteEnvironment::Resources &
ConcreteEnvironment::Resources& ConcreteEnvironment::get_resources ()
ConcreteEnvironment::get_resources()
{ {
return _resources; return _resources;
} }
const Environment::SubRequestQueue &
const Environment::SubRequestQueue& ConcreteEnvironment::get_request_queue (resource_key_t resource_key) const
ConcreteEnvironment::get_request_queue(resource_key_t resource_key) const
{ {
// Should always return something... // Should always return something...
return _sreq_queues.find(resource_key)->second; return _sreq_queues.find (resource_key)->second;
} }
Environment::SubRequestQueue& Environment::SubRequestQueue &
ConcreteEnvironment::get_request_queue(resource_key_t resource_key) ConcreteEnvironment::get_request_queue (resource_key_t resource_key)
{ {
// Inserts a new element in none is there! // Inserts a new element in none is there!
return _sreq_queues[resource_key]; return _sreq_queues[resource_key];
} }
ConcreteEnvironment::SubRequestQueues& ConcreteEnvironment::SubRequestQueues &
ConcreteEnvironment::get_subrequest_queues() ConcreteEnvironment::get_subrequest_queues ()
{ {
return _sreq_queues; return _sreq_queues;
} }
const ReadyQueue &
const ReadyQueue& ConcreteEnvironment::get_sorted_queue () const
ConcreteEnvironment::get_sorted_queue() const
{ {
return _sched_queue; return _sched_queue;
} }
ReadyQueue &
ReadyQueue& ConcreteEnvironment::get_sorted_queue ()
ConcreteEnvironment::get_sorted_queue()
{ {
return _sched_queue; return _sched_queue;
} }
ConcreteEnvironment::~ConcreteEnvironment ()
ConcreteEnvironment::~ConcreteEnvironment()
{ {
// This call will invoke the DynamicProcess virtual destructor // This call will invoke the DynamicProcess virtual destructor
// Which will delete on cascade all DynamicThreads and so on. // Which will delete on cascade all DynamicThreads and so on.
for_each(_processes.begin(), _processes.end(), for_each (_processes.begin (), _processes.end (), [](auto *p) { delete p; });
[] (auto *p) { delete p; });
// We do the same with Resources. // We do the same with Resources.
for (Resources::iterator it = _resources.begin(); it != _resources.end(); it++) for (Resources::iterator it = _resources.begin (); it != _resources.end (); it++)
delete it->second; delete it->second;
// After this, the destructor of _sched_queue 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 _processes is invoked (only invalid pointers)
// After that, the destructor of _resources is invoked (only invalid pointers) // After that, the destructor of _resources is invoked (only invalid pointers)
} }
// -------------------------------- TO BE FIXED ---------------- // -------------------------------- TO BE FIXED ----------------

View File

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

View File

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

View File

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

View File

@ -20,11 +20,11 @@
#include "concrete_process_statistics.hh" #include "concrete_process_statistics.hh"
#include "concrete_thread_statistics.hh" #include "concrete_thread_statistics.hh"
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh> #include <sgpemv2/environment.hh>
#include <sgpemv2/schedulable.hh> #include <sgpemv2/history.hh>
#include <sgpemv2/process.hh> #include <sgpemv2/process.hh>
#include <sgpemv2/schedulable.hh>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/thread.hh> #include <sgpemv2/thread.hh>
#include <iostream> #include <iostream>
@ -41,167 +41,165 @@ using namespace sgpem;
\param _threads_stats The statistics of the threads belonging to "core" \param _threads_stats The statistics of the threads belonging to "core"
*/ */
ConcreteProcessStatistics::ConcreteProcessStatistics(const Process* core, const int& instant): ConcreteProcessStatistics::ConcreteProcessStatistics (const Process *core, const int &instant) : _core (core)
_core(core)
{ {
//retrieve threads statistics necessary to calculate "core"'s statistics //retrieve threads statistics necessary to calculate "core"'s statistics
vector<const Thread*> threads = core->get_threads(); vector<const Thread *> threads = core->get_threads ();
for (unsigned int i_t = 0; i_t < threads.size(); i_t++) for (unsigned int i_t = 0; i_t < threads.size (); i_t++)
_threads_stats.push_back(ConcreteThreadStatistics(threads[i_t], instant)); _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 //inizialize variables
if(core->get_total_cpu_time() != 0) _total_inactivity = 0;
_execution_progress = (_execution_time*100) / core->get_total_cpu_time(); _execution_time = 0;
else _response_time = -1;
_execution_progress = 0; _turn_around = 0;
_resource_usage_time = 0;
_total_inactivity = _turn_around - _execution_time; _resource_waitings_time = 0;
_average_response_time = 0;
if (_turn_around == 0) int min_reponse = -1; //useful for _response_time
_efficiency = -1; int arrived_threads = 0; //useful for _average_response_time
else bool someone_began = false; //useful for _response_time
_efficiency = (_execution_time*100)/_turn_around;
//iterate through threads statistics
_response_time = min_reponse; vector<ConcreteThreadStatistics>::const_iterator i;
for (i = _threads_stats.begin (); i != _threads_stats.end (); i++)
if (arrived_threads != 0) {
_average_response_time = (float)((int)((_average_response_time/arrived_threads)*100))/100; 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() ConcreteProcessStatistics::~ConcreteProcessStatistics ()
{
}
int
ConcreteProcessStatistics::get_execution_time() const
{ {
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 int
ConcreteProcessStatistics::get_efficiency() const ConcreteProcessStatistics::get_execution_time () const
{ {
return _efficiency; return _execution_time;
} }
int int
ConcreteProcessStatistics::get_resource_usage_time() const ConcreteProcessStatistics::get_execution_progress () const
{ {
return _resource_usage_time; return _execution_progress;
} }
int 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 float
ConcreteProcessStatistics::get_average_response_time() const ConcreteProcessStatistics::get_average_response_time () const
{ {
return _average_response_time; return _average_response_time;
} }
const Process* const Process *
ConcreteProcessStatistics::get_core() const ConcreteProcessStatistics::get_core () const
{ {
return _core; return _core;
} }
/** /**
\warning Don't delete these pointers!! \warning Don't delete these pointers!!
\warning These pointers are not valid anymore after the destruction of "this" \warning These pointers are not valid anymore after the destruction of "this"
*/ */
vector<const ThreadStatistics*> vector<const ThreadStatistics *>
ConcreteProcessStatistics::get_threads_statistics() const ConcreteProcessStatistics::get_threads_statistics () const
{ {
vector<const ThreadStatistics*> rit; vector<const ThreadStatistics *> rit;
for (unsigned int i=0; i < _threads_stats.size(); i++) for (unsigned int i = 0; i < _threads_stats.size (); i++)
rit.push_back(&_threads_stats[i]); rit.push_back (&_threads_stats[i]);
return rit; return rit;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,9 +24,9 @@
#include "gettext.h" #include "gettext.h"
#include <sgpemv2/process.hh>
#include "dynamic_schedulable.hh" #include "dynamic_schedulable.hh"
#include "static_process.hh" #include "static_process.hh"
#include <sgpemv2/process.hh>
#include <glibmm/ustring.h> #include <glibmm/ustring.h>
@ -35,40 +35,40 @@
namespace sgpem namespace sgpem
{ {
class DynamicProcess; class DynamicProcess;
class StaticProcess; class StaticProcess;
class DynamicThread; class DynamicThread;
class Thread; class Thread;
class SG_DLLLOCAL DynamicProcess : public DynamicSchedulable, public Process class SG_DLLLOCAL DynamicProcess : public DynamicSchedulable, public Process
{ {
public: public:
DynamicProcess(StaticProcess* core); DynamicProcess (StaticProcess *core);
DynamicProcess(const DynamicProcess &other); DynamicProcess (const DynamicProcess &other);
virtual ~DynamicProcess(); virtual ~DynamicProcess ();
std::vector<Thread*> get_threads(); std::vector<Thread *> get_threads ();
std::vector<const Thread*> get_threads() const; 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_acquisition () const;
int get_last_release() const; int get_last_release () const;
unsigned int get_elapsed_time() const; unsigned int get_elapsed_time () const;
virtual StaticProcess& get_core(); virtual StaticProcess &get_core ();
virtual const StaticProcess& get_core() const; virtual const StaticProcess &get_core () const;
// Does also the job of "add_thread" and "remove_thread" // 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::shared_ptr<StaticProcess> _core;
std::vector<DynamicThread*> _dynamic_threads; std::vector<DynamicThread *> _dynamic_threads;
}; };
} } // namespace sgpem
#endif #endif

View File

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

View File

@ -23,14 +23,14 @@
namespace sgpem namespace sgpem
{ {
class DynamicRequest; class DynamicRequest;
class SerializeVisitor; class SerializeVisitor;
class SubRequest; class SubRequest;
class DynamicSubRequest; class DynamicSubRequest;
} } // namespace sgpem
#include "static_request.hh"
#include "dynamic_thread.hh" #include "dynamic_thread.hh"
#include "static_request.hh"
#include <sgpemv2/request.hh> #include <sgpemv2/request.hh>
@ -39,46 +39,45 @@ namespace sgpem
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 * of a request at a particular temporal instant
*/ */
class SG_DLLLOCAL DynamicRequest : public Request class SG_DLLLOCAL DynamicRequest : public Request
{ {
public: public:
DynamicRequest(StaticRequest *core, DynamicThread* owner); DynamicRequest (StaticRequest *core, DynamicThread *owner);
DynamicRequest(const DynamicRequest& other, DynamicThread* owner); DynamicRequest (const DynamicRequest &other, DynamicThread *owner);
~DynamicRequest(); ~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(); StaticRequest &get_core ();
const StaticRequest& get_core() const; const StaticRequest &get_core () const;
/// \internal Since this method is visible only by the backend, /// \internal Since this method is visible only by the backend,
/// return directly a reference that lets us to /// return directly a reference that lets us to
/// add and remove subrequests at will. /// add and remove subrequests at will.
std::vector<DynamicSubRequest*>& get_dynamic_subrequests(); std::vector<DynamicSubRequest *> &get_dynamic_subrequests ();
private: private:
// Undefined // Undefined
DynamicRequest(const DynamicRequest& other); DynamicRequest (const DynamicRequest &other);
std::shared_ptr<StaticRequest> _static_request; std::shared_ptr<StaticRequest> _static_request;
DynamicThread* _dynamic_thread; DynamicThread *_dynamic_thread;
std::vector<DynamicSubRequest*> _dynamic_subrequests; std::vector<DynamicSubRequest *> _dynamic_subrequests;
}; };
} } // namespace sgpem
#endif #endif

View File

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

View File

@ -23,76 +23,73 @@
#include "glibmm/ustring.h" #include "glibmm/ustring.h"
#include <sgpemv2/resource.hh>
#include "static_resource.hh" #include "static_resource.hh"
#include <sgpemv2/resource.hh>
#include <memory> #include <memory>
namespace sgpem 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 virtual bool operator== (const Resource &op2) const;
/// 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;
/// \brief Returns the name of the Resource. /// \brief Returns the name of the Resource.
/// ///
/// Returns the name of the Resource. /// Returns the name of the Resource.
/// \return 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. /// \brief Returns the number of places of the Resource.
/// ///
/// Returns the number of places of the Resource. /// Returns the number of places of the Resource.
/// \return 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. /// \brief Serializes this object via the provided translator.
/// ///
/// Calls translator->from_resource(this). /// Calls translator->from_resource(this).
void serialize(SerializeVisitor& translator) const; void serialize (SerializeVisitor &translator) const;
/// \brief Returns a reference to the static resource object. /// \brief Returns a reference to the static resource object.
/// ///
/// This function returns a reference to the actual schedable object /// This function returns a reference to the actual schedable object
/// represented, along with its status, by this instance. /// represented, along with its status, by this instance.
StaticResource& get_core(); StaticResource &get_core ();
/// \brief Returns a constant reference to the static schedulable object. /// \brief Returns a constant reference to the static schedulable object.
/// ///
/// This function returns a constant reference to the actual schedable object /// This function returns a constant reference to the actual schedable object
/// represented, along with its status, by this instance. /// 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; std::shared_ptr<StaticResource> _static_resource;
}; };
} } // namespace sgpem
#endif #endif

View File

@ -27,56 +27,56 @@
using namespace sgpem; using namespace sgpem;
using namespace std; using namespace std;
DynamicSchedulable::DynamicSchedulable() DynamicSchedulable::DynamicSchedulable () : _priority_push (0)
: _priority_push(0) {
{} }
bool 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 Glib::ustring
DynamicSchedulable::get_name() const DynamicSchedulable::get_name () const
{ {
return get_core().get_name(); return get_core ().get_name ();
} }
unsigned int 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 int
DynamicSchedulable::get_base_priority() const DynamicSchedulable::get_base_priority () const
{ {
return get_core().get_priority(); return get_core ().get_priority ();
} }
unsigned int 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 int
DynamicSchedulable::set_priority_push(int new_value) DynamicSchedulable::set_priority_push (int new_value)
{ {
int old_priority_push = _priority_push; int old_priority_push = _priority_push;
_priority_push = new_value; _priority_push = new_value;
return old_priority_push; return old_priority_push;
} }
int int
DynamicSchedulable::get_priority_push() const DynamicSchedulable::get_priority_push () const
{ {
return _priority_push; return _priority_push;
} }
int int
DynamicSchedulable::get_current_priority() const DynamicSchedulable::get_current_priority () const
{ {
return get_base_priority() + get_priority_push(); return get_base_priority () + get_priority_push ();
} }

View File

@ -22,31 +22,30 @@
#define DYNAMIC_SCHEDULABLE_HH 1 #define DYNAMIC_SCHEDULABLE_HH 1
#include <sgpemv2/schedulable.hh>
#include "static_schedulable.hh" #include "static_schedulable.hh"
#include <sgpemv2/schedulable.hh>
namespace sgpem 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 class SG_DLLLOCAL DynamicSchedulable : public virtual Schedulable
/// of the simulation. {
/// public:
/// 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:
/** \brief Object constructor */ /** \brief Object constructor */
DynamicSchedulable(); DynamicSchedulable ();
//DynamicSchedulable(const DynamicSchedulable& obj); //copy constructor //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 * actual represented process is the same, and if the status is also the
* same. * same.
*/ */
virtual bool operator==(const Schedulable&) const; virtual bool operator== (const Schedulable &) const;
/// \brief Returns the name of the Schedulable. /// \brief Returns the name of the Schedulable.
/// ///
/// Returns the name of the Schedulable. /// Returns the name of the Schedulable.
/// It is fetched from the associated ::StaticSchedulable object. /// It is fetched from the associated ::StaticSchedulable object.
/// \return the name of the Schedulable. /// \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. /// \brief Returns the arrival time of the Schedulable.
/// ///
@ -72,10 +71,10 @@ namespace sgpem
/// the state of the Schedulable is switched from future to /// the state of the Schedulable is switched from future to
/// ready. /// 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. /// It is fetched from the associated ::StaticSchedulable object.
/// \return the arrival time of the Schedulable. /// \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. /// \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. /// The base priority is a static (respect to the simulation) property.
/// It is fetched from the associated ::StaticSchedulable object. /// It is fetched from the associated ::StaticSchedulable object.
/// \return the base priority of the Schedulable. /// \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. /// \brief Returns the total required CPU time of the Schedulable.
/// ///
/// 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. /// complete its work.
/// ///
/// When a Schedulable's elapsed CPU time equals the total required CPU time /// 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. /// The total required CPU time is a static (respect to the simulation) property.
/// It is fetched from the associated ::StaticSchedulable object. /// It is fetched from the associated ::StaticSchedulable object.
/// \return the total required CPU time of the Schedulable. /// \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. /// \brief Returns the current priority push of the Schedulable.
/// ///
/// 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 /// importance of the Schedulable. Priority-sensitive policies usually give
/// better services to more important Schedulables. /// better services to more important Schedulables.
/// ///
@ -118,12 +117,12 @@ namespace sgpem
/// ///
/// The priority push is a dynamic (respect to the simulation) property. /// The priority push is a dynamic (respect to the simulation) property.
/// \return the current priority push of the Schedulable. /// \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. /// \brief Sets the priority push of the Schedulable, returning the old one.
/// ///
/// Sets the current priority push of the Schedulable. /// 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 /// importance of the Schedulable. Priority-sensitive policies usually give
/// better services to more important Schedulables. /// better services to more important Schedulables.
/// ///
@ -133,7 +132,7 @@ namespace sgpem
/// The priority push is a dynamic (respect to the simulation) property. /// The priority push is a dynamic (respect to the simulation) property.
/// \param new_value the new push to be set. /// \param new_value the new push to be set.
/// \return the old priority push of the Schedulable. /// \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. /// \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. /// The current priority is a dynamic (respect to the simulation) property.
/// \return the dynamic priority of the Schedulable. /// \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. /// \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. /// The elapsed time is a dynamic (respect to the simulation) property.
/// \return the elapsed time of the Schedulable. /// \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. /// \brief Returns a reference to the static schedulable object.
/// ///
/// This function returns a reference to the actual schedable object. /// This function returns a reference to the actual schedable object.
/// represented, along with its status, by this instance. /// represented, along with its status, by this instance.
virtual StaticSchedulable& get_core() = 0; virtual StaticSchedulable &get_core () = 0;
/// \brief Returns a constant reference to the static schedulable object. /// \brief Returns a constant reference to the static schedulable object.
/// ///
/// This function returns a constant reference to the actual schedable object. /// This function returns a constant reference to the actual schedable object.
/// represented, along with its status, by this instance. /// 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; int _priority_push;
}; };
} } // namespace sgpem
#endif #endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,62 +24,62 @@
using namespace std; using namespace std;
using namespace sgpem; using namespace sgpem;
ResourcePolicyFiFo::~ResourcePolicyFiFo() ResourcePolicyFiFo::~ResourcePolicyFiFo ()
{} {
}
void void
ResourcePolicyFiFo::configure() ResourcePolicyFiFo::configure ()
{ {
} }
void 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. // the last inserted request goes on the last free place.
SubRequestQueue old_queue(queue); SubRequestQueue old_queue (queue);
queue.clear(); queue.clear ();
typedef SubRequestQueue::iterator It; typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++) for (It i = old_queue.begin (); i != old_queue.end (); i++)
{ {
// allocated ones remain allocated // allocated ones remain allocated
if((**i).get_state() == Request::state_allocated) if ((**i).get_state () == Request::state_allocated)
queue.push_back(*i); queue.push_back (*i);
} }
typedef SubRequestQueue::iterator It;
typedef SubRequestQueue::iterator It; for (It i = old_queue.begin (); i != old_queue.end (); i++)
for (It i = old_queue.begin(); i != old_queue.end(); i++) if ((**i).get_state () != Request::state_allocated && *i != &sr)
if((**i).get_state() != Request::state_allocated && *i != &sr) queue.push_back (*i);
queue.push_back(*i); queue.push_back (&sr);
queue.push_back(&sr);
} }
Glib::ustring 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 Glib::ustring
ResourcePolicyFiFo::get_name() const ResourcePolicyFiFo::get_name () const
{ {
return _("First In, First Out"); return _ ("First In, First Out");
} }
void void
ResourcePolicyFiFo::activate() ResourcePolicyFiFo::activate ()
{ {
} }
void void
ResourcePolicyFiFo::deactivate() ResourcePolicyFiFo::deactivate ()
{ {
} }

View File

@ -30,16 +30,16 @@
namespace sgpem namespace sgpem
{ {
class ResourcePolicyFiFo; class ResourcePolicyFiFo;
/** \brief /** \brief
It's a Strategy wich stay for a resource allocating algorithm. It's a Strategy wich stay for a resource allocating algorithm.
It implements the related resource allocation policy. It implements the related resource allocation policy.
*/ */
class SG_DLLLOCAL ResourcePolicyFiFo : public ResourcePolicy class SG_DLLLOCAL ResourcePolicyFiFo : public ResourcePolicy
{ {
public: public:
virtual ~ResourcePolicyFiFo(); virtual ~ResourcePolicyFiFo ();
/** /**
Initialize the inner components of the policy. Initialize the inner components of the policy.
@ -47,7 +47,7 @@ namespace sgpem
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. in concrete derived classes.
*/ */
virtual void configure(); virtual void configure ();
/** /**
Mixes the queues. Mixes the queues.
@ -55,7 +55,7 @@ namespace sgpem
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. 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. Gets a string description of the policy.
@ -64,16 +64,16 @@ namespace sgpem
in concrete derived classes. in concrete derived classes.
\return String description of the policy. \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 #endif //~ RESOURCE_POLICY_FIFO_HH

View File

@ -23,74 +23,74 @@
using namespace std; using namespace std;
using namespace sgpem; using namespace sgpem;
ResourcePolicyLiFo::~ResourcePolicyLiFo() ResourcePolicyLiFo::~ResourcePolicyLiFo ()
{} {
}
void void
ResourcePolicyLiFo::configure() ResourcePolicyLiFo::configure ()
{ {
} }
void 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. // the last inserted request goes on the first free place.
SubRequestQueue old_queue(queue); SubRequestQueue old_queue (queue);
queue.clear(); queue.clear ();
typedef SubRequestQueue::iterator It; typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++) 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)
{ {
// non-allocated ones go after the newly arrived // allocated ones remain allocated
if(!inserted) if ((**i).get_state () == Request::state_allocated)
{ queue.push_back (*i);
queue.push_back(&sr); }
inserted = true;
}
if (*i != &sr) bool inserted = false;
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)
{
// 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 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 Glib::ustring
ResourcePolicyLiFo::get_name() const ResourcePolicyLiFo::get_name () const
{ {
return _("Last In, First Out"); return _ ("Last In, First Out");
} }
void void
ResourcePolicyLiFo::activate() ResourcePolicyLiFo::activate ()
{ {
} }
void void
ResourcePolicyLiFo::deactivate() ResourcePolicyLiFo::deactivate ()
{ {
} }

View File

@ -31,30 +31,30 @@
namespace sgpem namespace sgpem
{ {
class ResourcePolicyLiFo; class ResourcePolicyLiFo;
/** \brief /** \brief
It's a Strategy wich stay for a resource allocating algorithm. It's a Strategy wich stay for a resource allocating algorithm.
It implements the related resource allocation policy. It implements the related resource allocation policy.
*/ */
class SG_DLLLOCAL ResourcePolicyLiFo : public ResourcePolicy class SG_DLLLOCAL ResourcePolicyLiFo : public ResourcePolicy
{ {
public: public:
virtual ~ResourcePolicyLiFo(); virtual ~ResourcePolicyLiFo ();
/** \brief Initialize the inner components of the policy. /** \brief Initialize 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. * in concrete derived classes.
*/ */
virtual void configure(); virtual void configure ();
/** \brief Mixes the queues. /** \brief Mixes the queues.
* *
* 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. * 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. /** \brief Gets a string description of the policy.
* *
@ -62,26 +62,26 @@ namespace sgpem
* in concrete derived classes. * in concrete derived classes.
* \return String description of the policy. * \return String description of the policy.
*/ */
virtual Glib::ustring get_description() const; virtual Glib::ustring get_description () const;
/** \brief Returns the policy name /** \brief Returns the policy name
*/ */
virtual Glib::ustring get_name() const; virtual Glib::ustring get_name () const;
/** \brief No-op method. /** \brief No-op method.
* *
* \see ResourcePolicy::activate() * \see ResourcePolicy::activate()
*/ */
virtual void activate(); virtual void activate ();
/** \brief No-op method. /** \brief No-op method.
* *
* \see ResourcePolicy::deactivate() * \see ResourcePolicy::deactivate()
*/ */
virtual void deactivate(); virtual void deactivate ();
}; };
}//~ namespace sgpem } // namespace sgpem
#endif #endif

View File

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

View File

@ -24,77 +24,76 @@
using namespace sgpem; using namespace sgpem;
ResourcePolicyPriority::~ResourcePolicyPriority() ResourcePolicyPriority::~ResourcePolicyPriority ()
{ {
} }
void void
ResourcePolicyPriority::configure() ResourcePolicyPriority::configure ()
{ {
} }
void 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); SubRequestQueue old_queue (queue);
queue.clear(); queue.clear ();
typedef SubRequestQueue::iterator It; typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++) 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)
{ {
// non-allocated ones with lower priority go after the newly arrived // allocated ones remain allocated
int pthat = (**i).get_request().get_thread().get_current_priority(); if ((**i).get_state () == Request::state_allocated)
if(!inserted && pthis <= pthat) queue.push_back (*i);
{ }
queue.push_back(&sr);
inserted = true;
} int pthis = sr.get_request ().get_thread ().get_current_priority ();
if (*i != &sr) // assume they are ordered by priority.
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 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 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 Glib::ustring
ResourcePolicyPriority::get_name() const ResourcePolicyPriority::get_name () const
{ {
return _("Higher Priority First"); return _ ("Higher Priority First");
} }
void void
ResourcePolicyPriority::activate() ResourcePolicyPriority::activate ()
{ {
} }
void void
ResourcePolicyPriority::deactivate() ResourcePolicyPriority::deactivate ()
{ {
} }

View File

@ -23,36 +23,34 @@
#include "gettext.h" #include "gettext.h"
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/policy_parameters.hh> #include <sgpemv2/policy_parameters.hh>
#include <sgpemv2/resource_policy.hh>
#include <sgpemv2/user_interrupt_exception.hh> #include <sgpemv2/user_interrupt_exception.hh>
#include <glibmm/ustring.h> #include <glibmm/ustring.h>
namespace sgpem 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 class SG_DLLLOCAL ResourcePolicyPriority : public ResourcePolicy
/// to higer priority threads. {
/// public:
/// 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:
/// \brief Standard virtual destructor. /// \brief Standard virtual destructor.
/// ///
/// Standard virtual destructor. /// Standard virtual destructor.
virtual ~ResourcePolicyPriority(); virtual ~ResourcePolicyPriority ();
/// \brief Initializes the inner components of the policy. /// \brief Initializes the inner components of the policy.
/// ///
/// Does nothing. /// Does nothing.
virtual void configure(); virtual void configure ();
/// \brief Sorts the subrequest queue letting higher priority threads to be the first ones /// \brief Sorts the subrequest queue letting higher priority threads to be the first ones
/// to get the resources. /// to get the resources.
@ -63,33 +61,33 @@ namespace sgpem
/// \param environment the environment on which the policy applies. /// \param environment the environment on which the policy applies.
/// \param queue the queue where a subrequest has just been added. /// \param queue the queue where a subrequest has just been added.
/// \param sr the subrequest which 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. /// \brief Returns a description of the policy.
/// ///
/// Returns a description of the policy. /// Returns a description of the policy.
/// \return 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. /// \brief Returns the name of the policy.
/// ///
/// Returns the name of the policy. /// Returns the name of the policy.
/// \return 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. /// \brief Activates the policy.
/// ///
/// Does nothing. /// Does nothing.
virtual void activate(); virtual void activate ();
/// \brief Deactivates the policy. /// \brief Deactivates the policy.
/// ///
/// Does nothing. /// Does nothing.
virtual void deactivate(); virtual void deactivate ();
}; };
}//~ namespace sgpem } // namespace sgpem
#endif #endif

View File

@ -25,88 +25,91 @@
using namespace std; using namespace std;
using namespace sgpem; using namespace sgpem;
ResourcePolicyPriorityInheritance::~ResourcePolicyPriorityInheritance() ResourcePolicyPriorityInheritance::~ResourcePolicyPriorityInheritance ()
{} {
}
void void
ResourcePolicyPriorityInheritance::configure() ResourcePolicyPriorityInheritance::configure ()
{ {
} }
void 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); SubRequestQueue old_queue (queue);
queue.clear(); queue.clear ();
// the priority may only rise! // the priority may only rise!
int pmax = sr.get_request().get_thread().get_current_priority(); int pmax = sr.get_request ().get_thread ().get_current_priority ();
typedef SubRequestQueue::iterator It; typedef SubRequestQueue::iterator It;
for (It i = old_queue.begin(); i != old_queue.end(); i++) 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)
{ {
// non-allocated ones with lower priority go after the newly arrived // determine the max priority
int pthat = (**i).get_request().get_thread().get_current_priority(); int pthat = (**i).get_request ().get_thread ().get_current_priority ();
if(!inserted && pthis <= pthat) if (pthat < pmax)
{ pmax = pthat;
queue.push_back(&sr); // allocated ones remain allocated
inserted = true; if ((**i).get_state () == Request::state_allocated)
} queue.push_back (*i);
if (*i != &sr)
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 // allocated ones remain allocated
int push = pmax - (**i).get_request().get_thread().get_current_priority(); if ((**i).get_state () != Request::state_allocated)
(**i).get_request().get_thread().set_priority_push(push); {
// 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 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 Glib::ustring
ResourcePolicyPriorityInheritance::get_name() const ResourcePolicyPriorityInheritance::get_name () const
{ {
return _("Basic Priority Inheritance Protocol"); return _ ("Basic Priority Inheritance Protocol");
} }
void void
ResourcePolicyPriorityInheritance::activate() ResourcePolicyPriorityInheritance::activate ()
{ {
} }
void void
ResourcePolicyPriorityInheritance::deactivate() ResourcePolicyPriorityInheritance::deactivate ()
{ {
} }

View File

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

View File

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

View File

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

View File

@ -18,7 +18,6 @@
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/. // along with SGPEMv2. If not, see http://www.gnu.org/licenses/.
/* /*
// DISCLAIMER FOR THE RAMPANT CODER: \\ // DISCLAIMER FOR THE RAMPANT CODER: \\
// ----------------------------------------------------\\ // ----------------------------------------------------\\
@ -36,8 +35,8 @@
#include <sgpemv2/scheduler.hh> #include <sgpemv2/scheduler.hh>
// Do not include full template definition in the header file // Do not include full template definition in the header file
#include <sgpemv2/templates/singleton.tcc>
#include <sgpemv2/templates/sequences.tcc> #include <sgpemv2/templates/sequences.tcc>
#include <sgpemv2/templates/singleton.tcc>
#include <glibmm/thread.h> #include <glibmm/thread.h>
@ -52,81 +51,78 @@ using namespace sgpem;
template class sgpem::Singleton<Scheduler>; template class sgpem::Singleton<Scheduler>;
typedef std::vector<DynamicProcess*> Processes; typedef std::vector<DynamicProcess *> Processes;
typedef std::vector<DynamicRequest*> Requests; typedef std::vector<DynamicRequest *> Requests;
typedef std::vector<DynamicSubRequest*> SubRequests; typedef std::vector<DynamicSubRequest *> SubRequests;
typedef std::vector<DynamicThread*> Threads; typedef std::vector<DynamicThread *> Threads;
typedef Environment::Resources Resources; typedef Environment::Resources Resources;
typedef Environment::SubRequestQueue SubRequestQueue; typedef Environment::SubRequestQueue SubRequestQueue;
// ------------------ Static helper functions -------------- // ------------------ Static helper functions --------------
inline bool is_running(const Thread* running_thread); inline bool is_running (const Thread *running_thread);
static void collect_threads(const std::vector<Process*>& procs, Threads& collected_threads); 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 prepare_ready_queue (ConcreteEnvironment &snapshot, const Threads &all_threads);
static void terminate_all_requests_of(DynamicThread& thread, ConcreteEnvironment& environment); static void terminate_all_requests_of (DynamicThread &thread, ConcreteEnvironment &environment);
static void update_allocated_requests(DynamicThread& running_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 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 look_for_mutant_request_states (ConcreteEnvironment &environment, unsigned int &alive_threads);
static void determine_subr_allocable_status(const Resource& res, const SubRequestQueue& queue); static void determine_subr_allocable_status (const Resource &res, const SubRequestQueue &queue);
// --------------------------------------------------------- // ---------------------------------------------------------
bool 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 // Collects all threads of an environment into a single vector
void void
collect_threads(const std::vector<Process*>& procs, collect_threads (const std::vector<Process *> &procs, Threads &collected_threads)
Threads& collected_threads)
{ {
collected_threads.clear(); collected_threads.clear ();
for (Iseq<vector<Process*>::const_iterator> seq = iseq(procs); seq; ++seq) for (Iseq<vector<Process *>::const_iterator> seq = iseq (procs); seq; ++seq)
{ {
const Threads& ts = ((DynamicProcess&) **seq).get_dynamic_threads(); const Threads &ts = ((DynamicProcess &) **seq).get_dynamic_threads ();
collected_threads.insert(collected_threads.end(), ts.begin(), ts.end()); collected_threads.insert (collected_threads.end (), ts.begin (), ts.end ());
} }
} }
void void
prepare_ready_queue(ConcreteEnvironment& snapshot, prepare_ready_queue (ConcreteEnvironment &snapshot, const Threads &all_threads)
const Threads& all_threads)
{ {
ReadyQueue& queue = snapshot.get_sorted_queue(); ReadyQueue &queue = snapshot.get_sorted_queue ();
assert(queue.size() == 0); assert (queue.size () == 0);
for (Iseq<Threads::const_iterator> seq = iseq(all_threads); seq; ++seq) for (Iseq<Threads::const_iterator> seq = iseq (all_threads); seq; ++seq)
{ {
if ((*seq)->get_state() == Schedulable::state_ready) if ((*seq)->get_state () == Schedulable::state_ready)
queue.append(**seq); queue.append (**seq);
} }
} }
// When a thread terminates, unconditionally kill all its requests // When a thread terminates, unconditionally kill all its requests
void void
terminate_all_requests_of(DynamicThread& thread, terminate_all_requests_of (DynamicThread &thread, ConcreteEnvironment &environment)
ConcreteEnvironment& environment)
{ {
Requests& reqs = thread.get_dynamic_requests(); Requests &reqs = thread.get_dynamic_requests ();
for (Iseq<Requests::iterator> r_it = iseq(reqs); r_it; ++r_it) for (Iseq<Requests::iterator> r_it = iseq (reqs); r_it; ++r_it)
{ {
SubRequests& subreqs = (*r_it)->get_dynamic_subrequests(); SubRequests &subreqs = (*r_it)->get_dynamic_subrequests ();
for (Iseq<SubRequests::iterator> s_it = iseq(subreqs); s_it; ++s_it) for (Iseq<SubRequests::iterator> s_it = iseq (subreqs); s_it; ++s_it)
{ {
(*s_it)->set_state(Request::state_exhausted); (*s_it)->set_state (Request::state_exhausted);
Environment::resource_key_t rkey = (*s_it)->get_resource_key(); Environment::resource_key_t rkey = (*s_it)->get_resource_key ();
SubRequestQueue& queue = environment.get_request_queue(rkey); SubRequestQueue &queue = environment.get_request_queue (rkey);
SubRequestQueue::iterator removable = find(queue.begin(), queue.end(), *s_it); SubRequestQueue::iterator removable = find (queue.begin (), queue.end (), *s_it);
if(removable != queue.end()) queue.erase(removable); 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 // For the current thread, see if there are requests that are exhausted
void void
update_allocated_requests(DynamicThread& running_thread, update_allocated_requests (DynamicThread &running_thread, ConcreteEnvironment &environment)
ConcreteEnvironment& environment)
{ {
// Go for all dynamic requests of this thread // Go for all dynamic requests of this thread
Requests& reqs = running_thread.get_dynamic_requests(); Requests &reqs = running_thread.get_dynamic_requests ();
for (Iseq<Requests::iterator> req_it = iseq(reqs); req_it; ++req_it) for (Iseq<Requests::iterator> req_it = iseq (reqs); req_it; ++req_it)
{ {
SubRequests& cur_request = (*req_it)->get_dynamic_subrequests(); SubRequests &cur_request = (*req_it)->get_dynamic_subrequests ();
for (Iseq<SubRequests::iterator> subr_it = iseq(cur_request); subr_it; ++subr_it) for (Iseq<SubRequests::iterator> subr_it = iseq (cur_request); subr_it; ++subr_it)
{ {
DynamicSubRequest& cur_subr = **subr_it; DynamicSubRequest &cur_subr = **subr_it;
if(cur_subr.get_state() == Request::state_allocated) if (cur_subr.get_state () == Request::state_allocated)
{ {
cur_subr.decrease_remaining_time(); cur_subr.decrease_remaining_time ();
if(cur_subr.get_remaining_time() == 0) if (cur_subr.get_remaining_time () == 0)
{ {
cur_subr.set_state(Request::state_exhausted); cur_subr.set_state (Request::state_exhausted);
Environment::resource_key_t rkey = cur_subr.get_resource_key(); Environment::resource_key_t rkey = cur_subr.get_resource_key ();
SubRequestQueue& queue = environment.get_request_queue(rkey); SubRequestQueue &queue = environment.get_request_queue (rkey);
SubRequestQueue::iterator removable = find(queue.begin(), queue.end(), &cur_subr); SubRequestQueue::iterator removable = find (queue.begin (), queue.end (), &cur_subr);
if(removable != queue.end()) queue.erase(removable); if (removable != queue.end ())
} queue.erase (removable);
} }
} //~ for(over subrequests) }
} //~ for(over requests) } //~ 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, // Remember that a thread may run only if all of its requests are either FUTURE,
// ALLOCATED or EXHAUSTED. // ALLOCATED or EXHAUSTED.
void 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 // Go for all dynamic requests of this thread
Requests& reqs = running_thread.get_dynamic_requests(); Requests &reqs = running_thread.get_dynamic_requests ();
for (Iseq<Requests::iterator> req_it = iseq(reqs); req_it; ++req_it) for (Iseq<Requests::iterator> req_it = iseq (reqs); req_it; ++req_it)
{ {
DynamicRequest& cur_req = **req_it; DynamicRequest &cur_req = **req_it;
SubRequests& subreqs = (*req_it)->get_dynamic_subrequests(); SubRequests &subreqs = (*req_it)->get_dynamic_subrequests ();
// Add to the queue only requests passing from future to another state: // Add to the queue only requests passing from future to another state:
if(cur_req.get_state() == Request::state_future && if (cur_req.get_state () == Request::state_future && cur_req.get_instant () == running_thread.get_elapsed_time ())
cur_req.get_instant() == running_thread.get_elapsed_time()) {
{ for (Iseq<SubRequests::iterator> subr_it = iseq (subreqs); subr_it; ++subr_it)
for (Iseq<SubRequests::iterator> subr_it = iseq(subreqs); subr_it; ++subr_it) {
{ // Do the proper adding:
// Do the proper adding: DynamicSubRequest &cur_subr = **subr_it;
DynamicSubRequest& cur_subr = **subr_it; Environment::resource_key_t rkey = cur_subr.get_resource_key ();
Environment::resource_key_t rkey = cur_subr.get_resource_key(); SubRequestQueue &queue = environment.get_request_queue (rkey);
SubRequestQueue& queue = environment.get_request_queue(rkey); queue.push_back (&cur_subr);
queue.push_back(&cur_subr);
/// TODO: right here, right now we should call the resource policy to /// TODO: right here, right now we should call the resource policy to
/// update the queue. Updates the state of the subrequest depending /// update the queue. Updates the state of the subrequest depending
/// on the position in the queue, as explained before. /// on the position in the queue, as explained before.
resource_policy.enforce(environment, queue, cur_subr); resource_policy.enforce (environment, queue, cur_subr);
// Get the number of places for the corresponding resource // Get the number of places for the corresponding resource
Resource& resource = *environment.get_resources().find(rkey)->second; Resource &resource = *environment.get_resources ().find (rkey)->second;
// WARNING: adding a new request may require updating the status of ALL other // WARNING: adding a new request may require updating the status of ALL other
// requests in the queue // requests in the queue
determine_subr_allocable_status(resource, queue); determine_subr_allocable_status (resource, queue);
// after that, check if it is globally allocable. // after that, check if it is globally allocable.
// See if the subrequest is allocable or unallocable, and set its state. // 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. // It's important that the subrequest has already been added to the queue.
// determine_subr_allocable_status(cur_req, cur_subr, resource, queue); // determine_subr_allocable_status(cur_req, cur_subr, resource, queue);
} //~ for(over subrequests) } //~ for(over subrequests)
} //~ if(request is future and is time to allocate it) } //~ 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 // 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 // are ALLOCABLE. A request is allocated when all its subrequests are either TERMINATED
// or ALLOCATED, but at least one is ALLOCATED. // or ALLOCATED, but at least one is ALLOCATED.
// Now, since the thread is willing to run, we must allocate the request if possible. // 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 // 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 // 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 // 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 // If it is actually allocable, allocate it
switch(cur_req.get_state()) switch (cur_req.get_state ())
{
case Request::state_allocable:
{ {
const SubRequests& const_subreqs = subreqs; case Request::state_allocable:
for(Iseq<SubRequests::const_iterator> it_dsrs = iseq(const_subreqs); it_dsrs; ++it_dsrs) {
const SubRequests &const_subreqs = subreqs;
for (Iseq<SubRequests::const_iterator> it_dsrs = iseq (const_subreqs); it_dsrs; ++it_dsrs)
{ {
DynamicSubRequest &subreq = **it_dsrs;
DynamicSubRequest& subreq = **it_dsrs; assert (subreq.get_state () == Request::state_allocable);
assert(subreq.get_state() == Request::state_allocable); /*
/*
// Move this request up the queue, to the back of the allocated // Move this request up the queue, to the back of the allocated
// subrequests. This is mainly for display. :-) // subrequests. This is mainly for display. :-)
// The rest of the queue sorting business is up to the resource policy. // 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()); assert(this_subreq != queue.end());
swap(*alloc_it, *this_subreq); swap(*alloc_it, *this_subreq);
*/ */
subreq.set_state(Request::state_allocated); subreq.set_state (Request::state_allocated);
} }
} }
break; break;
case Request::state_unallocable: case Request::state_unallocable:
// If it does exist at least one unallocable request, the thread may not run! // If it does exist at least one unallocable request, the thread may not run!
running_thread.set_state(Schedulable::state_blocked); running_thread.set_state (Schedulable::state_blocked);
break; break;
default: default:
break; break;
}//~ switch(request state) } //~ switch(request state)
} //~ for(over requests) } //~ for(over requests)
} }
// The following loop updates the states of the subrequests depending // The following loop updates the states of the subrequests depending
// on their position in the queue // on their position in the queue
void 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 total_places = res.get_places ();
unsigned int position_in_queue = 0; unsigned int position_in_queue = 0;
for(Iseq<SubRequestQueue::const_iterator> queue_it = iseq(queue); for (Iseq<SubRequestQueue::const_iterator> queue_it = iseq (queue); queue_it; queue_it++, position_in_queue++)
queue_it; queue_it++, position_in_queue++)
{ {
DynamicSubRequest& sr = (DynamicSubRequest&) **queue_it; DynamicSubRequest &sr = (DynamicSubRequest &) **queue_it;
if (sr.get_state() == Request::state_allocated) if (sr.get_state () == Request::state_allocated)
continue; continue;
if(position_in_queue + 1 > total_places) if (position_in_queue + 1 > total_places)
{ {
sr.set_state(Request::state_unallocable); sr.set_state (Request::state_unallocable);
// Kludge: // Kludge:
sr.get_request().get_thread().set_state(Schedulable::state_blocked); sr.get_request ().get_thread ().set_state (Schedulable::state_blocked);
} }
else else
sr.set_state(Request::state_allocable); sr.set_state (Request::state_allocable);
} //~ for(over subrequest queue) } //~ 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 // step of the simulation. It also put previously blocked threads
// back into ready state if need arises. // back into ready state if need arises.
void void
look_for_mutant_request_states(ConcreteEnvironment& environment, look_for_mutant_request_states (ConcreteEnvironment &environment, unsigned int &alive_threads)
unsigned int& alive_threads)
{ {
// Now listening to: Testament's ``First Strike Is Still Deadly'' // Now listening to: Testament's ``First Strike Is Still Deadly''
// The name of this function evokes mighty monsters from the abyss. In // 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, // fact, it's what it actually does (okay, okay, pull the other one,
// it's got brass bells on). // it's got brass bells on).
// We start assuming that SubRequestsQueues are up-to-date // We start assuming that SubRequestsQueues are up-to-date
Resources& resources = environment.get_resources(); Resources &resources = environment.get_resources ();
for(Iseq<Resources::iterator> res_it = iseq(resources); res_it; ++res_it) for (Iseq<Resources::iterator> res_it = iseq (resources); res_it; ++res_it)
{ {
Environment::resource_key_t rkey = res_it->first; Environment::resource_key_t rkey = res_it->first;
SubRequestQueue& queue = environment.get_request_queue(rkey); SubRequestQueue &queue = environment.get_request_queue (rkey);
unsigned int queue_pos = 0; unsigned int queue_pos = 0;
for(Iseq<SubRequestQueue::iterator> subr_it = iseq(queue); subr_it; ++subr_it, ++queue_pos) for (Iseq<SubRequestQueue::iterator> subr_it = iseq (queue); subr_it; ++subr_it, ++queue_pos)
{ {
DynamicSubRequest& subr = (DynamicSubRequest&) **subr_it; DynamicSubRequest &subr = (DynamicSubRequest &) **subr_it;
DynamicRequest& req = subr.get_request(); DynamicRequest &req = subr.get_request ();
Request::state prev_req_state = req.get_state(); Request::state prev_req_state = req.get_state ();
// If a request is already allocated, we don't have to touch it! // If a request is already allocated, we don't have to touch it!
if(prev_req_state == Request::state_allocated) if (prev_req_state == Request::state_allocated)
continue; continue;
// Update the state of the subrequest, either from allocable to // Update the state of the subrequest, either from allocable to
// unallocable or vice-versa // unallocable or vice-versa
// determine_subr_allocable_status(req, subr, *res_it->second, queue); // determine_subr_allocable_status(req, subr, *res_it->second, queue);
determine_subr_allocable_status(*res_it->second, queue); determine_subr_allocable_status (*res_it->second, queue);
// TODO: The following is a moderately expensive operation // TODO: The following is a moderately expensive operation
// to do here. See if we can move it somewhere else. // to do here. See if we can move it somewhere else.
// If a request changes state from allocable to unallocable, // If a request changes state from allocable to unallocable,
// the corresponding thread should be blocked, and vice-versa // the corresponding thread should be blocked, and vice-versa
DynamicThread& thread = req.get_thread(); DynamicThread &thread = req.get_thread ();
if(prev_req_state == Request::state_allocable && if (prev_req_state == Request::state_allocable && req.get_state () == Request::state_unallocable)
req.get_state() == Request::state_unallocable)
{ {
if(thread.get_state() != Schedulable::state_blocked) if (thread.get_state () != Schedulable::state_blocked)
alive_threads--; alive_threads--;
thread.set_state(Schedulable::state_blocked); thread.set_state (Schedulable::state_blocked);
} }
else if(prev_req_state == Request::state_unallocable && else if (prev_req_state == Request::state_unallocable && req.get_state () == Request::state_allocable)
req.get_state() == Request::state_allocable)
{ {
if(thread.get_state() == Schedulable::state_blocked) if (thread.get_state () == Schedulable::state_blocked)
alive_threads++; alive_threads++;
thread.set_state(Schedulable::state_ready); thread.set_state (Schedulable::state_ready);
} }
} //~ for(over subrequests in the queue) } //~ for(over subrequests in the queue)
} //~ for(over resources) } //~ for(over resources)
} }
// --------------------------------------------------------- // ---------------------------------------------------------
//private constructor. //private constructor.
Scheduler::Scheduler() Scheduler::Scheduler () : _ready_queue (NULL), _policy (NULL), _step_mutex ()
: _ready_queue(NULL), _policy(NULL), _step_mutex()
{}
ReadyQueue*
Scheduler::get_ready_queue()
{ {
return _ready_queue;
} }
CPUPolicy* ReadyQueue *
Scheduler::get_policy() Scheduler::get_ready_queue ()
{ {
return _policy; return _ready_queue;
} }
CPUPolicy *
Scheduler::get_policy ()
{
return _policy;
}
bool 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 // 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 // store a readyqueue and policy pointer for the user-policy to retrieve, to when
// the policy returns // the policy returns
Glib::Mutex::Lock lock (_step_mutex); 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. unsigned int alive_threads = 0; // Assume we've finished. Then prove me wrong.
int current_instant = history.get_size() - 1; /* They should be equivalent */ int current_instant = history.get_size () - 1; /* They should be equivalent */
// Safe cast: // Safe cast:
ConcreteHistory& concrete_history = static_cast<ConcreteHistory&>(history); ConcreteHistory &concrete_history = static_cast<ConcreteHistory &> (history);
// Use an auto_ptr since we've some exceptions in the coming... // 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))); unique_ptr<ConcreteEnvironment> new_snapshot (new ConcreteEnvironment (concrete_history.get_environment_at (current_instant)));
Threads all_threads; Threads all_threads;
DynamicThread* running_thread = nullptr; 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 // The first thing we've to do is to update the state of the old
// running thread, if there's one. // running thread, if there's one.
for (Iseq<Threads::iterator> it = iseq(all_threads); it; ++it) for (Iseq<Threads::iterator> it = iseq (all_threads); it; ++it)
{
DynamicThread &current = **it;
// Save the current running thread for future usage, if it hasn't ended
// its allotted time
if (current.get_state () == Schedulable::state_running)
{ {
DynamicThread& current = **it; running_thread = &current; // Even if we can change its state to terminate
// Save the current running thread for future usage, if it hasn't ended // increasing the time elapsed of the running thread + process
// its allotted time // should be done here as the first thing, instead than
if (current.get_state() == Schedulable::state_running) // directly after selecting them
{ if (current.get_total_cpu_time () - current.get_elapsed_time () > 0)
running_thread = &current; // Even if we can change its state to terminate current.decrease_remaining_time ();
// increasing the time elapsed of the running thread + process // 4a. Look for exhausted requests for the running thread
// should be done here as the first thing, instead than update_allocated_requests (current, *new_snapshot);
// 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 // 2. mark threads that used all their allotted time as terminated,
update_allocated_requests(current, *new_snapshot); // 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_state (Schedulable::state_terminated);
current.set_last_release(current_instant); current.set_last_release (current_instant);
terminate_all_requests_of(current, *new_snapshot); terminate_all_requests_of (current, *new_snapshot);
running_thread = nullptr; running_thread = nullptr;
} }
// if we found the running thread, there isn't another one, // if we found the running thread, there isn't another one,
// so we can safely exit the for loop. // so we can safely exit the for loop.
break; break;
} //~ if state == running } //~ if state == running
} //~ for over all threads } //~ 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 // 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 // threads to make them ready. We also keep a count of alive threads
for (Iseq<Threads::iterator> it = iseq(all_threads); it; ++it) for (Iseq<Threads::iterator> it = iseq (all_threads); it; ++it)
{
DynamicThread &current = **it;
// 1. mark future threads as ready, if appropriate
if (current.get_state () == Schedulable::state_future)
{ {
DynamicThread& current = **it; Process &parent = current.get_process ();
if ((long) parent.get_arrival_time () <= current_instant && parent.get_elapsed_time () == current.get_arrival_time ())
current.set_state (Schedulable::state_ready);
}
// 1. mark future threads as ready, if appropriate // 3. check for simulation termination (we can directly use threads
if (current.get_state() == Schedulable::state_future) // for this check, since processes' state is based upon threads' one)
{ Schedulable::state cur_state = current.get_state ();
Process& parent = current.get_process(); if ((cur_state & (Schedulable::state_blocked | Schedulable::state_terminated)) == 0 &&
if ((long) parent.get_arrival_time() <= current_instant && (current.get_process ().get_state () & (Schedulable::state_terminated | Schedulable::state_blocked)) == 0) // check for holes
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)
{ {
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 // Reset values that the policy doesn't need anymore
_policy = nullptr; _policy = nullptr;
_ready_queue = nullptr; _ready_queue = nullptr;
// Do we need to update/reset something else? // If we got there, a step has been performed.
// Return if we can perform another step.
// Going up unwinding the stack, tell: return alive_threads != 0;
// - 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;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,7 +23,7 @@
namespace sgpem namespace sgpem
{ {
class CPUPolicyManager; class CPUPolicyManager;
} }
#include <sgpemv2/sgpemv2-visibility.hh> #include <sgpemv2/sgpemv2-visibility.hh>
@ -35,29 +35,29 @@ namespace sgpem
namespace sgpem namespace sgpem
{ {
/** /**
\brief CPUPolicyManager is the Abstract Factory for \brief CPUPolicyManager is the Abstract Factory for
\ref CPUPolicy objects. \ref CPUPolicy objects.
*/ */
class SG_DLLEXPORT CPUPolicyManager class SG_DLLEXPORT CPUPolicyManager
{ {
public: public:
typedef CPUPolicy Policy; typedef CPUPolicy Policy;
typedef std::vector<Policy*> Policies; typedef std::vector<Policy *> Policies;
/** \brief CPUPolicyManager constructor /** \brief CPUPolicyManager constructor
* *
* Registers the \b this pointer to the CPUPoliciesGatekeeper, so it can be accessed * 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 * 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. * 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 * \brief Collects available policies
* *
@ -68,12 +68,11 @@ namespace sgpem
* method will be called at some time during the initialization of * method will be called at some time during the initialization of
* the manager (usually inside the constructor). * 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 #endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -30,71 +30,69 @@
namespace sgpem 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 class SG_DLLEXPORT Module : public Glib::Module
/// {
/// When a plugin is found, PluginManager::rescan_dirs() tries to load it by public:
/// 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:
/// \brief Constructor taking an identifier. /// \brief Constructor taking an identifier.
/// ///
/// Constructor taking an identifier. /// Constructor taking an identifier.
/// \throw InvalidPluginException If the DSO you're trying to load /// \throw InvalidPluginException If the DSO you're trying to load
/// doesn't export a valid SGPEMv2 backend::Plugin interface. /// 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(). /// suffix. This is retrieved by PluginManager::rescan_dirs().
Module(const Glib::ustring& identifier); Module (const Glib::ustring &identifier);
/// \brief Enables or disables a plugin /// \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. /// functions where appropriate.
/// \param enabled whether to enable or disable the module. /// \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. /// \brief Returns the name of the module.
/// ///
/// Calls Plugin::get_name() /// Calls Plugin::get_name()
/// \return the name of the module. /// \return the name of the module.
Glib::ustring get_name() const; Glib::ustring get_name () const;
/// \brief Returns the author of the module. /// \brief Returns the author of the module.
/// ///
/// Calls Plugin::get_author() /// Calls Plugin::get_author()
/// \return the author of the module. /// \return the author of the module.
Glib::ustring get_author() const; Glib::ustring get_author () const;
/// \brief Returns a description of the module. /// \brief Returns a description of the module.
/// ///
/// Calls Plugin::describe() /// Calls Plugin::describe()
/// \return a description of the module. /// \return a description of the module.
Glib::ustring describe() const; Glib::ustring describe () const;
/// \brief Returns the version of the module. /// \brief Returns the version of the module.
/// ///
/// Calls Plugin::get_version() /// Calls Plugin::get_version()
/// \return the version of the module. /// \return the version of the module.
float get_version() const; float get_version () const;
/// \brief Returns whether the module is enabled or disabled. /// \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. /// functions where appropriate.
/// \param enabled whether to enable or disable the module. /// \param enabled whether to enable or disable the module.
bool get_enabled() const; bool get_enabled () const;
private: private:
typedef void (*f_void)(void); typedef void (*f_void) (void);
typedef const char* (*f_ustring)(void); typedef const char *(*f_ustring) (void);
typedef float (*f_float)(void); typedef float (*f_float) (void);
/// True if the plugin is enabled, false otherwise /// True if the plugin is enabled, false otherwise
/// ///
@ -104,17 +102,15 @@ namespace sgpem
/// ///
Glib::ustring _id; Glib::ustring _id;
f_void on_init_ptr; f_void on_init_ptr;
f_void on_exit_ptr; f_void on_exit_ptr;
f_ustring describe_ptr; f_ustring describe_ptr;
f_ustring get_name_ptr; f_ustring get_name_ptr;
f_ustring get_author_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 #endif

View File

@ -31,16 +31,16 @@
namespace sgpem 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 * an operation that involves scheduling is requested
*/ */
class SG_DLLEXPORT NullPolicyException : public std::runtime_error class SG_DLLEXPORT NullPolicyException : public std::runtime_error
{ {
public: public:
explicit NullPolicyException(const char* msg = ""); explicit NullPolicyException (const char *msg = "");
}; };
} //~ namespace sgpem } // namespace sgpem
#endif #endif

View File

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

View File

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

View File

@ -24,45 +24,43 @@
#include <sgpemv2/sgpemv2-visibility.hh> #include <sgpemv2/sgpemv2-visibility.hh>
#include <map> #include <map>
#include <string>
#include <stdexcept> #include <stdexcept>
#include <string>
#include "glibmm/ustring.h" #include "glibmm/ustring.h"
namespace sgpem namespace sgpem
{ {
class SG_DLLEXPORT PolicyParametersException : public std::runtime_error
class SG_DLLEXPORT PolicyParametersException : public std::runtime_error {
{ public:
public: PolicyParametersException (std::string msg) : std::runtime_error (msg)
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 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. interface: it serves to know which parameters the user will be asked for.
Each Policy object owns only one instance of this class. Each Policy object owns only one instance of this class.
*/ */
class SG_DLLEXPORT PolicyParameters class SG_DLLEXPORT PolicyParameters
{ {
public: public:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** \brief This class represents a sigle parameter of type \c T /** \brief This class represents a sigle parameter of type \c T
This class is useful only to store informations about each parameter. No checks This class is useful only to store informations about each parameter. No checks
on the values entered are done. on the values entered are done.
*/ */
template<typename T> template <typename T>
class SG_DLLEXPORT Parameter class SG_DLLEXPORT Parameter
{ {
public: public:
/** \brief Constructs the parameter
/** \brief Constructs the parameter
\param name The name of the parameter. This string will be used to refer to this parameter, thus it MUST \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) be uniqe (one string identifies \b only ONE parameter)
\param value The initial value of this 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 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). \param default_value The initial value of this parameter. (If not specified it's set to 0).
*/ */
Parameter(Glib::ustring name, const T& value, Parameter (Glib::ustring name, const T &value, const T &lower_bound, const T &upper_bound, const bool &required,
const T& lower_bound, const T& upper_bound, const T &default_value = 0);
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!! \warning NO CHECK is done whether the value repects its bounds!!
*/ */
void set_value(const T&); void set_value (const T &);
private: private:
Glib::ustring _name; Glib::ustring _name;
T _value; T _value;
T _lower_bound; T _lower_bound;
T _upper_bound; T _upper_bound;
bool _is_required; bool _is_required;
T _default; T _default;
}; };
@ -132,7 +129,8 @@ namespace sgpem
\param required Denotes if this parameter is required by the policy. \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). \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. /**\brief Registers a FLOAT parameter.
@ -146,7 +144,8 @@ namespace sgpem
\param required Denotes if this parameter is required by the policy. \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). \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. /**\brief Registers a STRING parameter.
@ -159,12 +158,12 @@ namespace sgpem
\param required Denotes if this parameter is required by the policy. \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). \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. /**\brief Deletes all registered parameters.
*/ */
void clear(); void clear ();
//############################################# //#############################################
@ -174,17 +173,17 @@ namespace sgpem
/** \brief Permits to retrieve all registered INTEGER parameters /** \brief Permits to retrieve all registered INTEGER parameters
\returns a map of INTEGER parameters identfied by their name \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 /** \brief Permits to retrieve all registered FLOAT parameters
\returns a map of FLOAT parameters identfied by their name \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 /** \brief Permits to retrieve all registered STRING parameters
\returns a map of STRING parameters identfied by their name \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 exceed the bounds proper to that parameter
\returns FALSE if the parameter named "name" is not found or if "value" exceeds the bounds \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 /** \brief Sets the value of a registred FLOAT parameter
@ -209,7 +208,7 @@ namespace sgpem
exceed the bounds proper to that parameter exceed the bounds proper to that parameter
\returns FALSE if the parameter named "name" is not found or if "value" exceeds the bounds \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 /** \brief Sets the value of a registred STRING parameter
@ -219,7 +218,7 @@ namespace sgpem
exceed the bounds proper to that parameter exceed the bounds proper to that parameter
\returns FALSE if the parameter named "name" is not found or if "value" exceeds the bounds \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 \returns the INTEGER value of the parameter named \e name
\throws PolicyParametersException if the parameter named \e name has not been registered \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 /** \brief Returns the value of an FLOAT parameter
\returns the FLOAT value of the parameter named \e name \returns the FLOAT value of the parameter named \e name
\throws PolicyParametersException if the parameter named \e name has not been registered \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 /** \brief Returns the value of an STRING parameter
\returns the STRING value of the parameter named \e name \returns the STRING value of the parameter named \e name
\throws PolicyParametersException if the parameter named \e name has not been registered \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: } // namespace sgpem
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
#endif #endif

View File

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

View File

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

View File

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

View File

@ -23,44 +23,43 @@
namespace sgpem namespace sgpem
{ {
class Request; class Request;
class SerializeVisitor; class SerializeVisitor;
class SubRequest; class SubRequest;
class Thread; class Thread;
} } // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh> #include <sgpemv2/sgpemv2-visibility.hh>
#include <vector> #include <vector>
namespace sgpem namespace sgpem
{ {
class SG_DLLEXPORT Request class SG_DLLEXPORT Request
{ {
public: public:
enum state enum state
{ {
state_unallocable = 1 << 0, state_unallocable = 1 << 0,
state_allocated = 1 << 1, state_allocated = 1 << 1,
state_future = 1 << 2, state_future = 1 << 2,
state_exhausted = 1 << 3, state_exhausted = 1 << 3,
state_allocable = 1 << 4 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 std::vector<SubRequest *> get_subrequests () = 0;
virtual unsigned int get_instant() const = 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 #endif

View File

@ -21,29 +21,29 @@
#ifndef RESOURCE_HH #ifndef RESOURCE_HH
#define RESOURCE_HH 1 #define RESOURCE_HH 1
#include <sgpemv2/sgpemv2-visibility.hh>
#include "glibmm/ustring.h" #include "glibmm/ustring.h"
#include <sgpemv2/sgpemv2-visibility.hh>
namespace sgpem namespace sgpem
{ {
class Resource; class Resource;
class SerializeVisitor; 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 resource in a real operating system could be a printer,
* a socket, a chunk of memory, or a simple file. * a socket, a chunk of memory, or a simple file.
*/ */
class SG_DLLEXPORT Resource class SG_DLLEXPORT Resource
{ {
public: public:
virtual ~Resource(); virtual ~Resource ();
/** \brief See if two different states point to the same 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 */ /** \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 /** \brief Return the number of places this resource has available
* before becoming unavailable * before becoming unavailable
@ -51,13 +51,12 @@ namespace sgpem
* E.g. if a resource has two places, it can fulfill only two * E.g. if a resource has two places, it can fulfill only two
* ::SubRequests at each instant * ::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 */ /** \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 #endif

View File

@ -23,49 +23,49 @@
namespace sgpem namespace sgpem
{ {
class ResourcePolicyManager; class ResourcePolicyManager;
class ResourcePolicy; class ResourcePolicy;
class History; class History;
} } // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh> #include <sgpemv2/sgpemv2-visibility.hh>
#include <vector>
#include <map> #include <map>
#include <stdexcept> #include <stdexcept>
#include <vector>
#include <sgpemv2/templates/singleton.hh> #include <sgpemv2/templates/singleton.hh>
namespace sgpem 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>; friend class Singleton<ResourcePoliciesGatekeeper>;
public: public:
typedef ResourcePolicyManager Manager; typedef ResourcePolicyManager Manager;
typedef std::vector<Manager*> Managers; typedef std::vector<Manager *> Managers;
/** /**
* \brief Returns registered resources policy managers. * \brief Returns registered resources policy managers.
* *
* \return 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. * \brief Register a new resources policy manager.
* A no-op if a manager of the same type already exists. * 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. * \brief Unregister a given manager. If not present, it is a no-op.
* When unregistering a manager, care should be taken to ensure that * 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. * \param manager The resource policy manager to remove.
*/ */
void unregister_manager(ResourcePolicyManager* manager); void unregister_manager (ResourcePolicyManager *manager);
/** /**
* \brief Returns the currently active policy. * \brief Returns the currently active policy.
@ -83,40 +83,39 @@ namespace sgpem
* *
* \return The current policy. * \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. \brief Given a policy, sets it as the history current one.
Also deactivates the old policy if present, and then activates 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. 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. \brief Private constructor.
*/ */
ResourcePoliciesGatekeeper(); //private constructor. ResourcePoliciesGatekeeper (); //private constructor.
/** /**
\brief Private copy constructor. \brief Private copy constructor.
*/ */
ResourcePoliciesGatekeeper(const ResourcePoliciesGatekeeper&); ResourcePoliciesGatekeeper (const ResourcePoliciesGatekeeper &);
/** /**
\brief Private assignment operator. \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. \brief Container of registered managers.
*/ */
Managers _registered; Managers _registered;
/** /**
\brief Container of active policies. \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 #endif //RESOURCE_POLICIES_GATEKEEPER_HH

View File

@ -23,92 +23,90 @@
namespace sgpem namespace sgpem
{ {
class ResourcePolicy; class ResourcePolicy;
} }
#include "gettext.h" #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/environment.hh>
#include <sgpemv2/policy_parameters.hh>
#include <sgpemv2/sgpemv2-visibility.hh>
#include <sgpemv2/sub_request.hh> #include <sgpemv2/sub_request.hh>
#include <sgpemv2/user_interrupt_exception.hh>
#include <glibmm/ustring.h> #include <glibmm/ustring.h>
namespace sgpem namespace sgpem
{ {
/// \brief A resource allocation policy.
/// \brief A resource allocation policy. ///
/// /// A resource allocation policy manages the queues of requests.
/// A resource allocation policy manages the queues of requests. /// Its purpose is to decide which threads may use the available
/// Its purpose is to decide which threads may use the available /// resources first.
/// resources first. class SG_DLLEXPORT ResourcePolicy
class SG_DLLEXPORT ResourcePolicy {
{ public:
public:
/// \brief Standard virtual destructor. /// \brief Standard virtual destructor.
/// ///
/// Standard virtual destructor. /// Standard virtual destructor.
virtual ~ResourcePolicy(); virtual ~ResourcePolicy ();
/// \brief Initializes the inner components of the policy. /// \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. /// in concrete derived classes.
virtual void configure() = 0; virtual void configure () = 0;
/// \brief Sorts the subrequest queue. /// \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. /// in concrete derived classes.
/// ///
/// \param environment the environment on which the policy applies. /// \param environment the environment on which the policy applies.
/// \param queue the queue where a subrequest has just been added. /// \param queue the queue where a subrequest has just been added.
/// \param sr the subrequest which 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. /// \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. /// in concrete derived classes.
/// Returns a description of the policy. /// Returns a description of the policy.
/// \return 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. /// \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. /// in concrete derived classes.
/// Returns the name of the policy. /// Returns the name of the policy.
/// \return 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. /// \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. /// in concrete derived classes.
virtual void activate() = 0; virtual void activate () = 0;
/// \brief Deactivates the policy. /// \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. /// in concrete derived classes.
virtual void deactivate() = 0; virtual void deactivate () = 0;
/// \brief Returns the parameters used to customize the policy. /// \brief Returns the parameters used to customize the policy.
/// ///
/// Returns the parameters used to customize the policy. /// Returns the parameters used to customize the policy.
/// The user may modify them directly. /// The user may modify them directly.
/// \return the parameters used to customize the policy. /// \return the parameters used to customize the policy.
PolicyParameters& get_parameters(); PolicyParameters &get_parameters ();
protected: protected:
PolicyParameters _parameters; PolicyParameters _parameters;
}; };
}//~ namespace sgpem } // namespace sgpem
#endif #endif

View File

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

View File

@ -27,22 +27,21 @@
namespace sgpem namespace sgpem
{ {
/// \brief Represents a schedulable entity within the simulated system. /// \brief Represents a schedulable entity within the simulated system.
/// ///
/// 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 /// Real world schedulable entities are, for example: batch jobs, processes
/// threads, fibers. /// threads, fibers.
/// This class factors out some of their features. /// This class factors out some of their features.
/// ///
/// This is an abstract class. Known subclasses are ::Process, and ::Thread /// This is an abstract class. Known subclasses are ::Process, and ::Thread
class Schedulable; class Schedulable;
class SerializeVisitor; class SerializeVisitor;
class SG_DLLEXPORT Schedulable
{
public:
class SG_DLLEXPORT Schedulable
{
public:
/// \brief This flag describes the actual state of the schedulable. /// \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 /// 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. /// processes. These are emulated in a single list by this flag.
enum state enum state
{ {
state_running = 1 << 0, state_running = 1 << 0,
state_ready = 1 << 1, state_ready = 1 << 1,
state_blocked = 1 << 2, state_blocked = 1 << 2,
state_future = 1 << 3, state_future = 1 << 3,
state_terminated = 1 << 4 state_terminated = 1 << 4
}; };
/// \brief Virtual destructor /// \brief Virtual destructor
/// ///
/// Abstract virtual destructor /// Abstract virtual destructor
virtual ~Schedulable() = 0; virtual ~Schedulable () = 0;
/// \brief Redefined operator equals (static equality). /// \brief Redefined operator equals (static equality).
/// ///
@ -69,18 +68,18 @@ namespace sgpem
/// By design, a Schedulable entity equals an other schedulable entity /// By design, a Schedulable entity equals an other schedulable entity
/// when their static (respect to the simulation) properties are equal. /// when their static (respect to the simulation) properties are equal.
/// This means, for example, that the priority push does not count when /// 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. /// time and elapsed time do count.
/// \param op2 the Schedulable to compare this with. /// \param op2 the Schedulable to compare this with.
/// \return true if the Schedulable equal, false otherwise. /// \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. /// \brief Returns the name of the Schedulable.
/// ///
/// Returns the name of the Schedulable. /// Returns the name of the Schedulable.
/// \return 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. /// \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. /// The arrival time is a static (respect to the simulation) property.
/// \return the arrival time of the Schedulable. /// \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. /// \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. /// The elapsed time is a dynamic (respect to the simulation) property.
/// \return the elapsed time of the Schedulable. /// \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. /// \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. /// The remaining time is a dynamic (respect to the simulation) property.
/// \return the remaining time of the Schedulable. /// \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. /// \brief Returns the last aquisition instant of the Schedulable.
/// ///
/// 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 /// 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. /// received the cpu.
/// ///
/// Its dual feature is the last release instant. /// Its dual feature is the last release instant.
/// ///
/// The last aquisition instant is a dynamic (respect to the simulation) property. /// The last aquisition instant is a dynamic (respect to the simulation) property.
/// \return the last aquisition instant of the Schedulable. /// \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. /// \brief Returns the last release instant of the Schedulable.
/// ///
/// 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 /// 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. /// abandoned the cpu.
/// ///
/// Its dual feature is the last aquisition instant. /// Its dual feature is the last aquisition instant.
/// ///
/// The last release instant is a dynamic (respect to the simulation) property. /// The last release instant is a dynamic (respect to the simulation) property.
/// \return the last release instant of the Schedulable. /// \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. /// \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. /// The base priority is a static (respect to the simulation) property.
/// \return the base priority of the Schedulable. /// \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. /// \brief Returns the total required CPU time of the Schedulable.
/// ///
/// 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. /// complete its work.
/// ///
/// When a Schedulable's elapsed CPU time equals the total required CPU time /// 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. /// The total required CPU time is a static (respect to the simulation) property.
/// \return the total required CPU time of the Schedulable. /// \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. /// \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. /// The current priority is a dynamic (respect to the simulation) property.
/// \return the dynamic priority of the Schedulable. /// \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. /// \brief Returns the current priority push of the Schedulable.
/// ///
/// 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 /// importance of the Schedulable. Priority-sensitive policies usually give
/// better services to more important Schedulables. /// better services to more important Schedulables.
/// ///
@ -195,12 +194,12 @@ namespace sgpem
/// ///
/// The priority push is a dynamic (respect to the simulation) property. /// The priority push is a dynamic (respect to the simulation) property.
/// \return the current priority push of the Schedulable. /// \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. /// \brief Sets the priority push of the Schedulable, returning the old one.
/// ///
/// Sets the current priority push of the Schedulable. /// 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 /// importance of the Schedulable. Priority-sensitive policies usually give
/// better services to more important Schedulables. /// better services to more important Schedulables.
/// ///
@ -210,7 +209,7 @@ namespace sgpem
/// The priority push is a dynamic (respect to the simulation) property. /// The priority push is a dynamic (respect to the simulation) property.
/// \param new_value the new push to be set. /// \param new_value the new push to be set.
/// \return the old priority push of the Schedulable. /// \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. /// \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. /// The current state is a dynamic (respect to the simulation) property.
/// \return the current state of the Schedulable. /// \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. /// \brief Serializes this entity using a visitor pattern.
/// ///
/// \param translator the visitor used to serialize this entity. /// \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 #endif

View File

@ -29,80 +29,79 @@
namespace sgpem 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 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 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 internal results calulated at construction time. To retrieve these results the whole History
(until the instant specified through Statistics::calculateStatisticsAt(int)) is scanned. (until the instant specified through Statistics::calculateStatisticsAt(int)) is scanned.
*/ */
class SchedulableStatistics class SchedulableStatistics
{ {
public: public:
virtual ~SchedulableStatistics(); 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" \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" \returns the number of instants during which the state of the schedulable was "running"
divided by the total running time of the schedulable 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" \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" \returns the number of instants during which the state of the schedulable was "ready" or "blocked"
before the first execution instant 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" \returns the number of instants during which the state of the schedulable was "ready" or "blocked"
or "running" 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 \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 \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. 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" \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 \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 _execution_time; int _total_inactivity;
int _execution_progress; int _response_time;
int _total_inactivity; int _turn_around;
int _response_time; int _efficiency;
int _turn_around; int _resource_usage_time;
int _efficiency; int _resource_waitings_time;
int _resource_usage_time; };
int _resource_waitings_time; } // namespace sgpem
};
}
#endif #endif

View File

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

View File

@ -23,14 +23,14 @@
namespace sgpem namespace sgpem
{ {
class History; class History;
class Environment; class Environment;
class Resource; class Resource;
class Process; class Process;
class Thread; class Thread;
class Request; class Request;
class SubRequest; class SubRequest;
} } // namespace sgpem
#include <sgpemv2/sgpemv2-visibility.hh> #include <sgpemv2/sgpemv2-visibility.hh>
@ -40,63 +40,62 @@ namespace sgpem
namespace sgpem namespace sgpem
{ {
class SerializeVisitor; class SerializeVisitor;
/** /**
\brief Interface class to serialize data \brief Interface class to serialize data
This class is a virtual class and each method must be reimplemented This class is a virtual class and each method must be reimplemented
in derived classes to have effective serialization. in derived classes to have effective serialization.
*/ */
class SG_DLLEXPORT SerializeVisitor class SG_DLLEXPORT SerializeVisitor
{ {
public: public:
virtual ~SerializeVisitor() = 0; virtual ~SerializeVisitor () = 0;
/** /**
\brief Add output to the serializer taking data from history \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 \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 \brief Add output to the serializer taking data from resource
BUG: a resource must be saved with her own associated key. 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 \brief Add output to the serializer taking data from resource and key
BUG FIXED: This save a resource with her own associated 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 \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 \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 \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 \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 #endif

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