- Pretty-indenting code

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@674 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-06-29 08:44:30 +00:00
parent 7aecc910ba
commit 6b27a8461b
94 changed files with 3073 additions and 3066 deletions

11
config/indenter Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
#find . -name "*.cc" -or -name "*.hh" -or -name "*.tcc" | \
# xargs indent -v -sc -psl -bls -bad -bap -bbb -nsob \
# -bli0 -cli0 -cbi0 -npcs -cs -nsaf -nsai -nsaw \
# -nprs -i2 -lp -ppi2 -l80 -nbbo -hnl -ss -di8 -nbc
find . -name "*.cc" -or -name "*.hh" -or -name "*.tcc" | \
xargs astyle --style=ansi -s2 -b -N -L -p -O -V \
--mode=c

View File

@ -33,24 +33,25 @@
#include "config.h" #include "config.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
#define SG_CONSTRUCTOR __attribute__ ((constructor)) #define SG_CONSTRUCTOR __attribute__ ((constructor))
#define SG_DESTRUCTOR __attribute__ ((destructor)) #define SG_DESTRUCTOR __attribute__ ((destructor))
#define _libpyloader_LTX__global_pm (_global_pm); #define _libpyloader_LTX__global_pm (_global_pm);
PolicyManager* _global_pm = NULL; PolicyManager* _global_pm = NULL;
void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void) void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void)
{ {
_global_pm = PythonPolicyManager::get_instance(); _global_pm = PythonPolicyManager::get_instance();
} }
void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void) void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void)
{ {
delete _global_pm; delete _global_pm;
} }
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -31,7 +31,7 @@ using namespace std;
// *strong* exception checking / handling! // *strong* exception checking / handling!
PythonPolicy::PythonPolicy(const char* name) PythonPolicy::PythonPolicy(const char* name)
: _upolicy_dict(NULL), _adapter(NULL), _name(name) : _upolicy_dict(NULL), _adapter(NULL), _name(name)
{ {
PyObject* pLoadmeStr = PyString_FromString(name); PyObject* pLoadmeStr = PyString_FromString(name);
PyObject* pUserPolicyModule = PyImport_Import(pLoadmeStr); PyObject* pUserPolicyModule = PyImport_Import(pLoadmeStr);
@ -80,10 +80,10 @@ PythonPolicy::~PythonPolicy()
{ {
if(_adapter) Py_DECREF(_adapter); if(_adapter) Py_DECREF(_adapter);
// We keep this alive until dtor time, because // We keep this alive until dtor time, because
// the user may have defined some static global-space // the user may have defined some static global-space
// variables and they make use of them. // variables and they make use of them.
if(_upolicy_dict) Py_DECREF(_upolicy_dict); if(_upolicy_dict) Py_DECREF(_upolicy_dict);
} }
@ -187,33 +187,33 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException)
{ {
PyThreadState* _save; PyThreadState* _save;
int i = 0; // We give the sort_queue() three seconds max time, then... int i = 0; // We give the sort_queue() three seconds max time, then...
// we shot it stone dead! Bang. // we shot it stone dead! Bang.
bool still_locked; bool still_locked;
do do
{
Py_UNBLOCK_THREADS;
usleep(WAIT_FOR); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
Py_BLOCK_THREADS;
PyObject* retval = PyObject_CallMethod(_adapter, "mutex_test_lock", NULL);
assert(retval);
still_locked = PyObject_IsTrue(retval);
Py_DECREF(retval);
if(i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
{ {
PyThreadState_Clear(_save);
// As the API documentation says, the caller of PyEval_RestoreThread
// should NOT possess the interpreter lock
Py_UNBLOCK_THREADS; Py_UNBLOCK_THREADS;
usleep(WAIT_FOR); // hack'a'ton! magggggiccc nummmbeeerrrrrs!! PyEval_RestoreThread(_save);
Py_BLOCK_THREADS;
PyObject* retval = PyObject_CallMethod(_adapter, "mutex_test_lock", NULL);
assert(retval);
still_locked = PyObject_IsTrue(retval);
Py_DECREF(retval);
if(i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
{
PyThreadState_Clear(_save);
// As the API documentation says, the caller of PyEval_RestoreThread
// should NOT possess the interpreter lock
Py_UNBLOCK_THREADS;
PyEval_RestoreThread(_save);
throw UserInterruptException("User-defined policy is " throw UserInterruptException("User-defined policy is "
"taking too long to terminate."); "taking too long to terminate.");
}
} }
}
while(still_locked); while(still_locked);
// What we should really do here: // What we should really do here:
@ -226,9 +226,9 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException)
...if he has, break ...if he has, break
...else: ...else:
if the global lock is set: if the global lock is set:
stay in this loop stay in this loop
else: else:
all's went okay, can exit loop all's went okay, can exit loop
} */ } */
} }

View File

@ -37,46 +37,46 @@ namespace sgpem
class PythonPolicyManager; class PythonPolicyManager;
class UserInterruptException; class UserInterruptException;
/** \brief A specialization of abstract class Policy /** \brief A specialization of abstract class Policy
This class represents a policy written in Python. Its methods interact with Python interpreter. This class represents a policy written in Python. Its methods interact with Python interpreter.
See the documentation of class Policy for more detailed informations. See the documentation of class Policy for more detailed informations.
*/ */
class SG_DLLEXPORT PythonPolicy : public Policy class SG_DLLEXPORT PythonPolicy : public Policy
{ {
public: public:
PythonPolicy(const char* name); PythonPolicy(const char* name);
virtual ~PythonPolicy(); virtual ~PythonPolicy();
/** /**
Calls the method \c async_configure Calls the method \c async_configure
*/ */
void configure() throw(UserInterruptException); void configure() throw(UserInterruptException);
/** /**
Calls the method \c async_sort_queue Calls the method \c async_sort_queue
*/ */
void sort_queue() const throw(UserInterruptException); void sort_queue() const throw(UserInterruptException);
/** /**
\returns A textual description of this policy. \returns A textual description of this policy.
*/ */
Glib::ustring get_description() const; Glib::ustring get_description() const;
Glib::ustring get_name() const; Glib::ustring get_name() const;
/** /**
\returns \c TRUE if the policy is preemptive. \returns \c TRUE if the policy is preemptive.
\returns \c FALSE if the policy is not preemptive. \returns \c FALSE if the policy is not preemptive.
*/ */
bool is_pre_emptive() const throw(UserInterruptException); bool is_pre_emptive() const throw(UserInterruptException);
/** /**
\returns The integer value of its time-slice. \returns The integer value of its time-slice.
*/ */
int get_time_slice() const throw(UserInterruptException); int get_time_slice() const throw(UserInterruptException);
policy_sorts_type wants() const throw(UserInterruptException); policy_sorts_type wants() const throw(UserInterruptException);
void activate() void activate()
{ {

View File

@ -45,15 +45,15 @@ using std::endl;
struct pol_dirs_concat : public std::unary_function<void, const Glib::ustring&> struct pol_dirs_concat : public std::unary_function<void, const Glib::ustring&>
{ {
public: public:
pol_dirs_concat(Glib::ustring& cat) : _cat(cat) {} pol_dirs_concat(Glib::ustring& cat) : _cat(cat) {}
void operator()(const Glib::ustring& add) void operator()(const Glib::ustring& add)
{ {
// Please note that this string will end finishing with // Please note that this string will end finishing with
// and additional ","! // and additional ","!
_cat += "'" + add + "', "; _cat += "'" + add + "', ";
} }
private: private:
Glib::ustring& _cat; Glib::ustring& _cat;
}; };
@ -63,7 +63,7 @@ PythonPolicyManager* PythonPolicyManager::_instance = NULL;
PythonPolicyManager::PythonPolicyManager() PythonPolicyManager::PythonPolicyManager()
: _initialized(false) : _initialized(false)
{ {
PyEval_InitThreads(); PyEval_InitThreads();
} }
@ -94,9 +94,9 @@ PythonPolicyManager::get_instance()
void void
PythonPolicyManager::init() PythonPolicyManager::init()
{ {
if(_initialized) if(_initialized)
// No-op // No-op
return; return;
Py_Initialize(); Py_Initialize();
_initialized = true; _initialized = true;
@ -109,10 +109,10 @@ PythonPolicyManager::init()
GlobalPreferences& prefs = GlobalPreferences::get_instance(); GlobalPreferences& prefs = GlobalPreferences::get_instance();
Glib::ustring importdirs = "import sys\n" Glib::ustring importdirs = "import sys\n"
"sys.path[:0] = [ "; "sys.path[:0] = [ ";
for_each(prefs.policies_dir_begin(), for_each(prefs.policies_dir_begin(),
prefs.policies_dir_end(), prefs.policies_dir_end(),
pol_dirs_concat(importdirs)); pol_dirs_concat(importdirs));
importdirs += " '" SHAREDIR "' ]\n"; importdirs += " '" SHAREDIR "' ]\n";
PyRun_SimpleString(importdirs.c_str()); PyRun_SimpleString(importdirs.c_str());
@ -152,19 +152,19 @@ PythonPolicyManager::collect_policies()
{ {
cout << "\t\tIt is.\n"; cout << "\t\tIt is.\n";
//strip extension //strip extension
std::string policy_name = (*file_it).substr(0, (*file_it).size() - 3); std::string policy_name = (*file_it).substr(0, (*file_it).size() - 3);
PythonPolicy *pypolicy = new PythonPolicy(policy_name.c_str()); PythonPolicy *pypolicy = new PythonPolicy(policy_name.c_str());
_policies.push_back(pypolicy); _policies.push_back(pypolicy);
//FIXME remove me when get_policy is dropped //FIXME remove me when get_policy is dropped
if(policy_name == "fcfs") if(policy_name == "fcfs")
{ {
_python_policy = pypolicy; _python_policy = pypolicy;
PoliciesGatekeeper::get_instance().activate_policy(&History::get_instance(), pypolicy); PoliciesGatekeeper::get_instance().activate_policy(&History::get_instance(), pypolicy);
} }
} }
} }
} }

View File

@ -61,13 +61,13 @@ namespace sgpem
std::vector<Policy*> get_avail_policies(); std::vector<Policy*> get_avail_policies();
/** \brief Returns the singleton instance of /** \brief Returns the singleton instance of
* PythonPolicyManager. * PythonPolicyManager.
* *
* Please note that the first time you'll request * Please note that the first time you'll request
* it, it will be still uninitialized. * it, it will be still uninitialized.
* @see init() * @see init()
*/ */
static PythonPolicyManager* const get_instance(); static PythonPolicyManager* const get_instance();
protected: protected:

View File

@ -39,88 +39,93 @@
// FIXME: Eeeeh? Why does this work without explicit namespace resolving? // FIXME: Eeeeh? Why does this work without explicit namespace resolving?
// Is there some using declaration in included HEADERS?? Aaaaagh! // Is there some using declaration in included HEADERS?? Aaaaagh!
class TestPythonPolicyManager : public PythonPolicyManager { class TestPythonPolicyManager : public PythonPolicyManager
{
public: public:
void test_init(const char* policy_name) { void test_init(const char* policy_name)
{
init(); init();
_python_policy = new PythonPolicy(policy_name); _python_policy = new PythonPolicy(policy_name);
} }
Policy& get_policy() { Policy& get_policy()
{
return *_python_policy; return *_python_policy;
} }
}; };
int int
main(int argc, char** argv) { main(int argc, char** argv)
using namespace sgpem; {
using namespace std; using namespace sgpem;
using namespace std;
int successes = 0; int successes = 0;
if(argc != 2) { if(argc != 2)
std::cout << "[EE] Usage:\n\t" << argv[0] << {
" path/to/uninstalled/policies" << std::endl; std::cout << "[EE] Usage:\n\t" << argv[0] <<
exit(-1); " path/to/uninstalled/policies" << std::endl;
} exit(-1);
else }
// Add argv[1] as the directory to search for uninstalled policies else
sgpem::GlobalPreferences::get_instance().add_policies_dir(argv[1]); // Add argv[1] as the directory to search for uninstalled policies
sgpem::GlobalPreferences::get_instance().add_policies_dir(argv[1]);
// Self-register itself to Scheduler, however we don't care about it // Self-register itself to Scheduler, however we don't care about it
TestPythonPolicyManager polman; TestPythonPolicyManager polman;
try try
{ {
polman.test_init("python_loader_configure"); polman.test_init("python_loader_configure");
polman.get_policy().configure(); polman.get_policy().configure();
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
cout << "configure: Caught UserInterruptException" << endl; cout << "configure: Caught UserInterruptException" << endl;
successes++; successes++;
} }
try try
{ {
polman.test_init("python_loader_is_preemptive"); polman.test_init("python_loader_is_preemptive");
polman.get_policy().is_pre_emptive(); polman.get_policy().is_pre_emptive();
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
cout << "is_preemptive: Caught UserInterruptException" << endl; cout << "is_preemptive: Caught UserInterruptException" << endl;
successes++; successes++;
} }
try try
{ {
polman.test_init("python_loader_get_time_slice"); polman.test_init("python_loader_get_time_slice");
polman.get_policy().get_time_slice(); polman.get_policy().get_time_slice();
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
cout << "get_time_slice: Caught UserInterruptException" << endl; cout << "get_time_slice: Caught UserInterruptException" << endl;
successes++; successes++;
} }
try try
{ {
SchedulableQueue sl; SchedulableQueue sl;
polman.test_init("python_loader_sort_queue"); polman.test_init("python_loader_sort_queue");
polman.get_policy().sort_queue(); polman.get_policy().sort_queue();
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
cout << "sort_queue: Caught UserInterruptException" << endl; cout << "sort_queue: Caught UserInterruptException" << endl;
successes++; successes++;
} }
cout << "Result: catched " << successes cout << "Result: catched " << successes
<< " exceptions out of 4." << endl; << " exceptions out of 4." << endl;
exit(0); exit(0);
} }

View File

@ -29,7 +29,8 @@
therein. See "info libtool": "dlopened modules" therein. See "info libtool": "dlopened modules"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
#include "config.h" #include "config.h"
@ -37,13 +38,11 @@ extern "C" {
#define SG_CONSTRUCTOR __attribute__ ((constructor)) #define SG_CONSTRUCTOR __attribute__ ((constructor))
#define SG_DESTRUCTOR __attribute__ ((destructor)) #define SG_DESTRUCTOR __attribute__ ((destructor))
void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void) void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void)
{ {}
}
void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void) void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void)
{ {}
}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -29,12 +29,11 @@ using namespace sgpem;
using std::vector; using std::vector;
DynamicProcess::DynamicProcess(StaticProcess* core) : DynamicProcess::DynamicProcess(StaticProcess* core) :
DynamicSchedulable(*core) DynamicSchedulable(*core)
{ {}
}
DynamicProcess::DynamicProcess(const DynamicProcess &other) : DynamicProcess::DynamicProcess(const DynamicProcess &other) :
Schedulable(), DynamicSchedulable(other), Process() Schedulable(), DynamicSchedulable(other), Process()
{ {
typedef vector<DynamicThread*>::const_iterator ThreadIt; typedef vector<DynamicThread*>::const_iterator ThreadIt;
@ -85,7 +84,8 @@ DynamicProcess::get_state() const
// TODO Is this OK? Must be tested... // TODO Is this OK? Must be tested...
switch(thread_state) { switch(thread_state)
{
case state_running: // (a) case state_running: // (a)
return state_running; return state_running;
case state_ready: // (b) case state_ready: // (b)
@ -98,9 +98,9 @@ DynamicProcess::get_state() const
result = state_future; result = state_future;
int thread_starts_at = (*it)->get_arrival_time(); int thread_starts_at = (*it)->get_arrival_time();
if(next_thread_starts_at == uninitialized) // (d1) if(next_thread_starts_at == uninitialized) // (d1)
next_thread_starts_at = thread_starts_at; next_thread_starts_at = thread_starts_at;
else else
next_thread_starts_at = std::min(thread_starts_at, next_thread_starts_at); next_thread_starts_at = std::min(thread_starts_at, next_thread_starts_at);
continue; continue;
default: // (e) default: // (e)
result = state_terminated; result = state_terminated;

View File

@ -31,8 +31,8 @@ using std::vector;
DynamicRequest::DynamicRequest(StaticRequest *core, DynamicRequest::DynamicRequest(StaticRequest *core,
DynamicThread* owner) : DynamicThread* owner) :
_static_request(core), _dynamic_thread(owner), _static_request(core), _dynamic_thread(owner),
_state(state_ready) _state(state_ready)
{ {
assert(core != NULL); assert(core != NULL);
assert(owner != NULL); assert(owner != NULL);
@ -81,8 +81,8 @@ DynamicRequest::remove_subrequest(SubRequest* subreq)
if(it != _dynamic_subrequests.end()) if(it != _dynamic_subrequests.end())
{ {
_dynamic_subrequests.erase(it); _dynamic_subrequests.erase(it);
delete *it; delete *it;
} }
} }

View File

@ -26,9 +26,8 @@
using namespace sgpem; using namespace sgpem;
DynamicResource::DynamicResource(StaticResource *core) : DynamicResource::DynamicResource(StaticResource *core) :
_static_resource(core) _static_resource(core)
{ {}
}
Glib::ustring Glib::ustring
DynamicResource::get_name() const DynamicResource::get_name() const

View File

@ -26,11 +26,10 @@ using namespace sgpem;
using namespace std; using namespace std;
DynamicSchedulable::DynamicSchedulable(StaticSchedulable& obj) : DynamicSchedulable::DynamicSchedulable(StaticSchedulable& obj) :
_time_left(obj.get_total_cpu_time()), _ref(&obj), _last_acquisition(-1), _time_left(obj.get_total_cpu_time()), _ref(&obj), _last_acquisition(-1),
_last_release(-1), _priority_push(0), _last(-1), _last_release(-1), _priority_push(0), _last(-1),
_my_state(state_future) _my_state(state_future)
{ {}
}
bool bool
DynamicSchedulable::operator==(const DynamicSchedulable& dx) const DynamicSchedulable::operator==(const DynamicSchedulable& dx) const

View File

@ -46,7 +46,7 @@ namespace sgpem
/** \brief Object constructor */ /** \brief Object constructor */
DynamicSchedulable(StaticSchedulable& obj); DynamicSchedulable(StaticSchedulable& obj);
//DynamicSchedulable(const DynamicSchedulable& obj); //copy constructor //DynamicSchedulable(const DynamicSchedulable& obj); //copy constructor
/** \brief Verify if two instances represents the same situation /** \brief Verify if two instances represents the same situation
* *
@ -112,8 +112,7 @@ namespace sgpem
void set_state(state s); void set_state(state s);
void serialize(SerializeVisitor& translator) const void serialize(SerializeVisitor& translator) const
{ {}
}
/** \brief Returns a pointer to the schedulable object /** \brief Returns a pointer to the schedulable object
* *

View File

@ -28,8 +28,8 @@ using namespace sgpem;
DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core, DynamicSubRequest::DynamicSubRequest(StaticSubRequest* core,
DynamicResource* resource) : DynamicResource* resource) :
_static_subrequest(core), _dynamic_resource(resource), _static_subrequest(core), _dynamic_resource(resource),
_queue_position(-1) _queue_position(-1)
{ {
assert(core != NULL); assert(core != NULL);
assert(resource != NULL); assert(resource != NULL);

View File

@ -30,12 +30,11 @@ using std::vector;
DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) : DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) :
DynamicSchedulable(*core), _state(state_future), _parent(parent) DynamicSchedulable(*core), _state(state_future), _parent(parent)
{ {}
}
DynamicThread::DynamicThread(const DynamicThread &other) : DynamicThread::DynamicThread(const DynamicThread &other) :
Schedulable(), DynamicSchedulable(other), Thread() Schedulable(), DynamicSchedulable(other), Thread()
{ {
typedef vector<DynamicRequest*>::const_iterator ReqIt; typedef vector<DynamicRequest*>::const_iterator ReqIt;

View File

@ -36,41 +36,41 @@ GlobalPreferences::GlobalPreferences()
GlobalPreferences::dir_iterator GlobalPreferences::dir_iterator
GlobalPreferences::policies_dir_begin() const GlobalPreferences::policies_dir_begin() const
{ {
return _pol_dirs.begin(); return _pol_dirs.begin();
} }
GlobalPreferences::dir_iterator GlobalPreferences::dir_iterator
GlobalPreferences::policies_dir_end() const GlobalPreferences::policies_dir_end() const
{ {
return _pol_dirs.end(); return _pol_dirs.end();
} }
GlobalPreferences::dir_iterator GlobalPreferences::dir_iterator
GlobalPreferences::modules_dir_begin() const GlobalPreferences::modules_dir_begin() const
{ {
return _mod_dirs.begin(); return _mod_dirs.begin();
} }
GlobalPreferences::dir_iterator GlobalPreferences::dir_iterator
GlobalPreferences::modules_dir_end() const GlobalPreferences::modules_dir_end() const
{ {
return _mod_dirs.end(); return _mod_dirs.end();
} }
void void
GlobalPreferences::add_modules_dir(const Glib::ustring& moddir) GlobalPreferences::add_modules_dir(const Glib::ustring& moddir)
{ {
_mod_dirs.insert(_mod_dirs.begin(), moddir); _mod_dirs.insert(_mod_dirs.begin(), moddir);
} }
void void
GlobalPreferences::add_policies_dir(const Glib::ustring& poldir) GlobalPreferences::add_policies_dir(const Glib::ustring& poldir)
{ {
_pol_dirs.insert(_pol_dirs.begin(), poldir); _pol_dirs.insert(_pol_dirs.begin(), poldir);
} }

View File

@ -29,37 +29,39 @@
// Do not include complete template definition here: // Do not include complete template definition here:
#include "singleton.hh" #include "singleton.hh"
namespace sgpem { namespace sgpem
class GlobalPreferences; {
class GlobalPreferences;
} }
#include "config.h" #include "config.h"
namespace sgpem { namespace sgpem
{
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>::const_iterator dir_iterator; typedef std::vector<Glib::ustring>::const_iterator dir_iterator;
dir_iterator modules_dir_begin() const; dir_iterator modules_dir_begin() const;
dir_iterator modules_dir_end() const; dir_iterator modules_dir_end() const;
dir_iterator policies_dir_begin() const; dir_iterator policies_dir_begin() const;
dir_iterator policies_dir_end() const; dir_iterator policies_dir_end() const;
void add_modules_dir(const Glib::ustring& moddir); void add_modules_dir(const Glib::ustring& moddir);
void add_policies_dir(const Glib::ustring& poldir); void add_policies_dir(const Glib::ustring& poldir);
private: private:
GlobalPreferences(); GlobalPreferences();
GlobalPreferences(const GlobalPreferences&); GlobalPreferences(const GlobalPreferences&);
GlobalPreferences& operator=(const GlobalPreferences&); GlobalPreferences& operator=(const GlobalPreferences&);
std::vector<Glib::ustring> _mod_dirs; std::vector<Glib::ustring> _mod_dirs;
std::vector<Glib::ustring> _pol_dirs; std::vector<Glib::ustring> _pol_dirs;
}; };
} }
#endif #endif

View File

@ -38,11 +38,12 @@ template class SG_DLLEXPORT smart_ptr<SchedulableQueue>;
template class SG_DLLEXPORT smart_ptr<DynamicSchedulable>; template class SG_DLLEXPORT smart_ptr<DynamicSchedulable>;
/** /**
The constructor sets _total_time_elapsed to -1: this permits to insert the INITIAL STATUS The constructor sets _total_time_elapsed to -1: this permits to insert the INITIAL STATUS
of the simulation which must begin at instant -1 and live for 1 instant. of the simulation which must begin at instant -1 and live for 1 instant.
*/ */
History::History() //private constructor. History::History() //private constructor.
:_total_time_elapsed(-1) :
_total_time_elapsed(-1)
{} {}
@ -54,15 +55,15 @@ History::History() //private constructor.
smart_ptr<DynamicSchedulable> smart_ptr<DynamicSchedulable>
History::get_scheduled_at(int time) const History::get_scheduled_at(int time) const
{ {
if (time > _total_time_elapsed || time < 0) //out of range if (time > _total_time_elapsed || time < 0) //out of range
return smart_ptr<DynamicSchedulable>(NULL); return smart_ptr<DynamicSchedulable>(NULL);
//look for a runing entity //look for a runing entity
smart_ptr<SchedulableQueue> p = get_simulation_status_at(time); smart_ptr<SchedulableQueue> p = get_simulation_status_at(time);
for (uint i = 0; i < p->size(); i++) for (uint i = 0; i < p->size(); i++)
if (p->get_item_at(i)->get_state() == DynamicSchedulable::state_running) if (p->get_item_at(i)->get_state() == DynamicSchedulable::state_running)
return smart_ptr<DynamicSchedulable>(new DynamicSchedulable(*(p->get_item_at(i)))); return smart_ptr<DynamicSchedulable>(new DynamicSchedulable(*(p->get_item_at(i))));
return smart_ptr<DynamicSchedulable>(NULL); return smart_ptr<DynamicSchedulable>(NULL);
} }
@ -74,18 +75,18 @@ History::get_scheduled_at(int time) const
smart_ptr<SchedulableQueue> smart_ptr<SchedulableQueue>
History::get_simulation_status_at(int time) const History::get_simulation_status_at(int time) const
{ {
if (time > _total_time_elapsed || time < 0) //out of range if (time > _total_time_elapsed || time < 0) //out of range
return smart_ptr<SchedulableQueue>(NULL); return smart_ptr<SchedulableQueue>(NULL);
int trascorso = -1; int trascorso = -1;
for(vector<Slice>::const_iterator i=_slices.begin(); i < _slices.end(); i++) for(vector<Slice>::const_iterator i = _slices.begin(); i < _slices.end(); i++)
if (time <= trascorso + i->get_duration()) //FOUND!! if (time <= trascorso + i->get_duration()) //FOUND!!
return smart_ptr<SchedulableQueue>(new SchedulableQueue(*i->get_simulation_status())); return smart_ptr<SchedulableQueue>(new SchedulableQueue(*i->get_simulation_status()));
else //Go on... else //Go on...
trascorso += i->get_duration(); trascorso += i->get_duration();
//never reached if all slices are CONTIGUOUS (ans THIS shoul be!!)!!! //never reached if all slices are CONTIGUOUS (ans THIS shoul be!!)!!!
return smart_ptr<SchedulableQueue>(NULL); return smart_ptr<SchedulableQueue>(NULL);
} }
int int
@ -111,39 +112,39 @@ History::enqueue_slice(const SchedulableQueue& status)
//check the last slice //check the last slice
Slice& last = _slices[_slices.size()-1]; Slice& last = _slices[_slices.size()-1];
if (last.get_simulation_status()->has_same_objects(status)) //increments the duration by ONE unit if (last.get_simulation_status()->has_same_objects(status)) //increments the duration by ONE unit
{ {
last.set_duration(last.get_duration()+1); last.set_duration(last.get_duration() + 1);
} }
else //insert a new slice CONTIGUOUS to the last one else //insert a new slice CONTIGUOUS to the last one
{ {
_slices.push_back(Slice(last.get_started_at() + last.get_duration(), 1, status)); _slices.push_back(Slice(last.get_started_at() + last.get_duration(), 1, status));
} }
_total_time_elapsed++; //one instant is passed... _total_time_elapsed++; //one instant is passed...
notify(); notify();
} }
/** /**
Removes all the informations about the simulation following the specified instant. Removes all the informations about the simulation following the specified instant.
Ex. truncate_at(0); removes all scheduled slices Ex. truncate_at(0); removes all scheduled slices
Ex. truncate_at(-1); removes all scheduled slices and the initial status Ex. truncate_at(-1); removes all scheduled slices and the initial status
*/ */
void void
History::truncate_at(int instant) History::truncate_at(int instant)
{ {
vector<Slice>::iterator i = _slices.begin(); vector<Slice>::iterator i = _slices.begin();
//reach the instant //reach the instant
while (i != _slices.end()) while (i != _slices.end())
if (i->get_started_at() < instant) if (i->get_started_at() < instant)
i++; i++;
else else
{ {
//replaces the current vector with the "trimmed" one. //replaces the current vector with the "trimmed" one.
_slices = vector<Slice>(_slices.begin(),i); _slices = vector<Slice>(_slices.begin(), i);
_total_time_elapsed = instant; _total_time_elapsed = instant;
break; break;
} }
notify(); notify();
} }

View File

@ -38,14 +38,14 @@
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.
In particoular it's possible to know which entity was running at a precise moment. In particoular it's possible to know which entity was running at a precise moment.
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;
@ -55,46 +55,46 @@ namespace sgpem
friend class Singleton<History>; friend class Singleton<History>;
public: public:
/** /**
Gets the \ref Schedulable object running at the specified time. Gets the \ref Schedulable object running at the specified time.
\param time The inquired time instant. \param time The inquired time instant.
\return The Schedulable object running at the given time. \return The Schedulable object running at the given time.
*/ */
virtual memory::smart_ptr<sgpem::DynamicSchedulable> get_scheduled_at(int time) const; virtual memory::smart_ptr<sgpem::DynamicSchedulable> get_scheduled_at(int time) const;
/** /**
Gets the status of simulation at the specified time. Gets the status of simulation at the specified time.
\param time The inquired time instant. \param time The inquired time instant.
\return The list of Schedulable status objects at the specified time. \return The list of Schedulable status objects at the specified time.
*/ */
virtual memory::smart_ptr<sgpem::SchedulableQueue> get_simulation_status_at(int time) const; virtual memory::smart_ptr<sgpem::SchedulableQueue> get_simulation_status_at(int time) const;
/** /**
Gets the current time. Gets the current time.
\return The current history time. \return The current history time.
*/ */
virtual int get_current_time() const; virtual int get_current_time() const;
/** /**
Sets the status of simulation at the current time. Sets the status of simulation at the current time.
\param status The list of \ref Schedulable status objects at the current time. \param status The list of \ref Schedulable status objects at the current time.
*/ */
virtual void enqueue_slice(const sgpem::SchedulableQueue& status); virtual void enqueue_slice(const sgpem::SchedulableQueue& status);
/** /**
Remove all data in History following the specified time. Remove all data in History following the specified time.
\param instant Desired cutting time. \param instant Desired cutting time.
*/ */
virtual void truncate_at(int instant); virtual void truncate_at(int instant);
protected: protected:
History(); //private constructor. History(); //private constructor.
History(const History&); History(const History&);
History& operator=(const History&); History& operator=(const History&);
private: private:
int _total_time_elapsed; int _total_time_elapsed;
std::vector<sgpem::Slice> _slices; std::vector<sgpem::Slice> _slices;
}; };
}//~ namespace sgpem }//~ namespace sgpem

View File

@ -24,8 +24,7 @@ using namespace sgpem;
ObservedSubject::~ObservedSubject() ObservedSubject::~ObservedSubject()
{ {}
}
/** /**
Calls update() in each Observer Calls update() in each Observer
@ -34,7 +33,7 @@ void
ObservedSubject::notify() ObservedSubject::notify()
{ {
for(vector<Observer*>::iterator i = _attached.begin(); i < _attached.end(); i++) for(vector<Observer*>::iterator i = _attached.begin(); i < _attached.end(); i++)
(*i)->update(); (*i)->update();
} }
@ -58,7 +57,7 @@ ObservedSubject::detach(Observer* o)
if (i == _attached.end()) if (i == _attached.end())
return false; return false;
_attached.erase(i); // FOUND and POPPED _attached.erase(i); // FOUND and POPPED
return true; return true;
} }

View File

@ -35,8 +35,8 @@ namespace sgpem
/** \brief Represents an observed entity. /** \brief Represents an observed entity.
Abstract class which represents an observed entity. It calls Update() in all Observer objects Abstract class which represents an observed entity. It calls Update() in all Observer objects
which are attached to it. See the "Observer Pattern" for more informations. which are attached to it. See the "Observer Pattern" for more informations.
*/ */
class SG_DLLEXPORT ObservedSubject class SG_DLLEXPORT ObservedSubject
{ {
@ -44,23 +44,23 @@ namespace sgpem
virtual ~ObservedSubject() = 0; virtual ~ObservedSubject() = 0;
/** /**
This method calls Update() on each attached Observer. It should be called when the internal state This method calls Update() on each attached Observer. It should be called when the internal state
of the ObservedSubject is changed and Observers have to be updated. of the ObservedSubject is changed and Observers have to be updated.
*/ */
void notify(); void notify();
/** /**
\brief Adds an Observer object to the internal list. \brief Adds an Observer object to the internal list.
*/ */
void attach(sgpem::Observer*); void attach(sgpem::Observer*);
/** /**
\brief Removes an Observer object from the internal list. \brief Removes an Observer object from the internal list.
\returns TRUE if the Observer object has been previously attached (is found in the list); \returns TRUE if the Observer object has been previously attached (is found in the list);
\returns FALSE otherwise. \returns FALSE otherwise.
*/ */
bool detach(sgpem::Observer*); bool detach(sgpem::Observer*);

View File

@ -32,32 +32,33 @@
namespace sgpem namespace sgpem
{ {
/** \brief The interface a specific plugin should implement /** \brief The interface a specific plugin should implement
* *
* Only the header file containing this interface * Only the header file containing this interface
* should be provided by the backend library. Every plugin * should be provided by the backend library. Every plugin
* will then implement its set of static functions. * will then implement its set of static functions.
* Thus every plugin will export these very symbols * Thus every plugin will export these very symbols
* outside its DSO. * outside its DSO.
*/ */
class SG_DLLEXPORT Plugin class SG_DLLEXPORT Plugin
{ {
/** \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.
*/ */
static void on_init(); static void on_init();
static void on_exit(); static void on_exit();
static Glib::ustring describe(); static Glib::ustring describe();
static Glib::ustring get_name(); static Glib::ustring get_name();
static Glib::ustring get_author(); static Glib::ustring get_author();
static float get_version(); static float get_version();
private: private:
SG_DLLLOCAL Plugin(); SG_DLLLOCAL Plugin();
}; //~ class Plugin }
; //~ class Plugin
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -107,8 +107,7 @@ PoliciesGatekeeper::activate_policy(History *history, Policy* policy)
} }
PoliciesGatekeeper::PoliciesGatekeeper() PoliciesGatekeeper::PoliciesGatekeeper()
{ {}
}
void void
PoliciesGatekeeper::deactivate_policies(PolicyManager* manager) PoliciesGatekeeper::deactivate_policies(PolicyManager* manager)
@ -130,8 +129,8 @@ PoliciesGatekeeper::deactivate_policies(PolicyManager* manager)
{ {
if(act_it->second == *avail_it) if(act_it->second == *avail_it)
{ {
act_it->second->deactivate(); act_it->second->deactivate();
_active_policies.erase(act_it); _active_policies.erase(act_it);
} }
} }
} }

View File

@ -40,7 +40,7 @@ namespace sgpem
{ {
class PoliciesGatekeeper; class PoliciesGatekeeper;
/** \brief FIXME document me /** \brief FIXME document me
*/ */
@ -50,26 +50,26 @@ namespace sgpem
friend class Singleton<PoliciesGatekeeper>; friend class Singleton<PoliciesGatekeeper>;
public: public:
std::vector<PolicyManager*> get_registered() const; std::vector<PolicyManager*> get_registered() const;
void register_manager(PolicyManager* manager); void register_manager(PolicyManager* manager);
void unregister_manager(PolicyManager* manager); void unregister_manager(PolicyManager* manager);
Policy* get_current_policy(History* history) throw(std::runtime_error); Policy* get_current_policy(History* history) throw(std::runtime_error);
void activate_policy(History* history, Policy* policy); void activate_policy(History* history, Policy* policy);
private: private:
PoliciesGatekeeper(); //private constructor. PoliciesGatekeeper(); //private constructor.
PoliciesGatekeeper(const PoliciesGatekeeper&); PoliciesGatekeeper(const PoliciesGatekeeper&);
PoliciesGatekeeper& operator=(const PoliciesGatekeeper&); PoliciesGatekeeper& operator=(const PoliciesGatekeeper&);
// Deactivates active policies managed by the specified manager. // Deactivates active policies managed by the specified manager.
void deactivate_policies(PolicyManager* manager); void deactivate_policies(PolicyManager* manager);
std::vector<PolicyManager*> _registered; std::vector<PolicyManager*> _registered;
std::map<History*, Policy*> _active_policies; std::map<History*, Policy*> _active_policies;
}; };
}//~ namespace sgpem }//~ namespace sgpem

View File

@ -24,18 +24,17 @@ using namespace sgpem;
using namespace memory; using namespace memory;
Policy::~Policy() Policy::~Policy()
{ {}
}
int int
Policy::get_id() const Policy::get_id() const
{ {
return _id; return _id;
} }
PolicyParameters& PolicyParameters&
Policy::get_parameters() Policy::get_parameters()
{ {
return _parameters; return _parameters;
} }

View File

@ -33,105 +33,105 @@
namespace sgpem namespace sgpem
{ {
enum policy_sorts_type enum policy_sorts_type
{ {
policy_sorts_threads, policy_sorts_threads,
policy_sorts_processes policy_sorts_processes
}; };
class Policy; class Policy;
/** \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 SchedulableQueue. mantained in a SchedulableQueue.
*/ */
class SG_DLLEXPORT Policy class SG_DLLEXPORT Policy
{ {
public: public:
virtual ~Policy(); virtual ~Policy();
/** /**
Initialize the inner components of the policy. 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() throw(UserInterruptException) = 0; virtual void configure() throw(UserInterruptException) = 0;
/** /**
Sort the \ref SchedulableQueue object that contain all the Schedulable objects Sort the \ref SchedulableQueue object that contain all the Schedulable objects
(Processes, Threads) still active managed by the scheduler. (Processes, Threads) still active managed by the scheduler.
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 throw(UserInterruptException) = 0; virtual void sort_queue() const throw(UserInterruptException) = 0;
/** /**
Gets the unique identifier (id) of this Policy. Gets the unique identifier (id) of this Policy.
\return The Policy id. \return The Policy id.
*/ */
int get_id() const; int get_id() const;
/** /**
Gets a string description of the policy. Gets a string 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.
\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.
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.
\return True if this policy is preemptible. \return True if this policy is preemptible.
*/ */
virtual bool is_pre_emptive() const throw(UserInterruptException) = 0; virtual bool is_pre_emptive() const throw(UserInterruptException) = 0;
/** /**
Gets the time quantum for the policy. Gets the time quantum for 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.
\return Time quantum for the policy. \return Time quantum for the policy.
*/ */
virtual int get_time_slice() const throw(UserInterruptException) = 0; virtual int get_time_slice() const throw(UserInterruptException) = 0;
/** /**
Tell what kind of entities are scheduled by this policy. Tell what kind of entities are scheduled by this 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.
\return A SortsType value identifying the desired type for the objects \return A SortsType value identifying the desired type for the objects
composing the queue passed to the sort_queue method. composing the queue passed to the sort_queue method.
*/ */
virtual policy_sorts_type wants() const throw(UserInterruptException) = 0; virtual policy_sorts_type wants() const throw(UserInterruptException) = 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.
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.
\return The policy parameters. \return The policy parameters.
*/ */
PolicyParameters& get_parameters(); PolicyParameters& get_parameters();
protected: protected:
PolicyParameters _parameters; PolicyParameters _parameters;
int _id; int _id;
}; };
}//~ namespace sgpem }//~ namespace sgpem

View File

@ -28,59 +28,59 @@
namespace sgpem namespace sgpem
{ {
class PolicyManager; class PolicyManager;
/** /**
PolicyManager is the Abstract Factory for \ref Policy objects. PolicyManager is the Abstract Factory for \ref Policy objects.
*/ */
class SG_DLLEXPORT PolicyManager class SG_DLLEXPORT PolicyManager
{ {
public: public:
/** \brief PolicyManager constructor /** \brief PolicyManager constructor
* *
* Saves ``this'' pointer into the _registered attribute, so it can access * Saves ``this'' pointer into the _registered attribute, so it can access
* it when requested. This is done so that concrete subclasses can be defined * it when requested. 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.
* *
* For the moment, just an instance of PolicyManager can be saved. This will * For the moment, just an instance of PolicyManager can be saved. This will
* be expanded in next milestones. * be expanded in next milestones.
*/ */
PolicyManager(); PolicyManager();
virtual ~PolicyManager() = 0; virtual ~PolicyManager() = 0;
/** /**
Gets THE policy (the only today) used. Gets THE policy (the only today) used.
Next versions will implement some other kind. Next versions will implement some other kind.
\return A reference to the policy. \return A reference to the policy.
FIXME deprecated FIXME deprecated
*/ */
//virtual Policy& get_policy() = 0; //virtual Policy& get_policy() = 0;
/** /**
Init (or reset if yet initialized) the manager. Init (or reset if yet initialized) the manager.
FIXME deprecated FIXME deprecated
*/ */
virtual void init() = 0; virtual void init() = 0;
virtual std::vector<Policy*> get_avail_policies() = 0; virtual std::vector<Policy*> get_avail_policies() = 0;
/** \brief Get the registered manager instance /** \brief Get the registered manager instance
* FIXME deprecated * FIXME deprecated
* *
* \return The registered policy manager instance. * \return The registered policy manager instance.
*/ */
static PolicyManager& get_registered_manager(); static PolicyManager& get_registered_manager();
protected: protected:
virtual void collect_policies() = 0; virtual void collect_policies() = 0;
std::vector<Policy*> _policies; std::vector<Policy*> _policies;
private: private:
/** A pointer to the registered instance */ /** A pointer to the registered instance */
static PolicyManager* _registered; static PolicyManager* _registered;
}; };
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -24,198 +24,198 @@ using namespace sgpem;
using Glib::ustring; using Glib::ustring;
/** /**
Register a new parameter of type integer. Register a new parameter of type integer.
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,const int& lower_bound, const int& upper_bound, const bool& required, const int& default_value) PolicyParameters::register_int(Glib::ustring name, const int& lower_bound, const int& upper_bound, const bool& required, const int& default_value)
{ {
//there is a parameter with the same name!! //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)); map<ustring, Parameter<int> >::value_type v(name, Parameter<int>(name, default_value, lower_bound, upper_bound, required, default_value));
int_map.insert(v); int_map.insert(v);
} }
/** /**
Register a new parameter of type float. Register a new parameter of type float.
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,const float& lower_bound, const float& upper_bound, const bool& required, const float& default_value) PolicyParameters::register_float(Glib::ustring name, const float& lower_bound, const float& upper_bound, const bool& required, const float& default_value)
{ {
//there is a parameter with the same name!! //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, default_value, lower_bound, upper_bound, required, default_value)); map<ustring, Parameter<float> >::value_type v(name, Parameter<float>(name, default_value, lower_bound, upper_bound, required, default_value));
float_map.insert(v); float_map.insert(v);
} }
/** /**
Register a new parameter of type string. Register a new parameter of type string.
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, default_value, "", "", required, default_value)); map<ustring, Parameter<Glib::ustring> >::value_type v(name, Parameter<Glib::ustring>(name, default_value, "", "", required, default_value));
string_map.insert(v); string_map.insert(v);
} }
/** /**
Deletes all registred parameters. Deletes all registred parameters.
*/ */
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;
} }
/** /**
Tries to set the value to the parameter named "name". Tries to set the value to the parameter named "name".
\returns TRUE if the parameter named "name" has been previously registered and the value \returns TRUE if the parameter named "name" has been previously registered and the value
stays in the range permitted by the parameter. stays in the range permitted by the parameter.
\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;
} }
/** /**
Tries to set the value to the parameter named "name". Tries to set the value to the parameter named "name".
\returns TRUE if the parameter named "name" has been previously registered and the value \returns TRUE if the parameter named "name" has been previously registered and the value
stays in the range permitted by the parameter. stays in the range permitted by the parameter.
\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;
} }
/** /**
Tries to set the value to the parameter named "name". For the type "string" there are Tries to set the value to the parameter named "name". For the type "string" there are
no upper/lower bound limitations. no upper/lower bound limitations.
\returns TRUE if the parameter named "name" has been previously registered. \returns TRUE if the parameter named "name" has been previously registered.
\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;
} }
/** /**
Looks for a parameter of integer type named "name". Looks for a parameter of integer type named "name".
\returns The value of the parameter \returns The value of the parameter
\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();
} }
/** /**
Looks for a parameter of float type named "name". Looks for a parameter of float type named "name".
\returns The value of the parameter \returns The value of the parameter
\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();
} }
/** /**
Looks for a parameter of string type named "name". Looks for a parameter of string type named "name".
\returns The value of the parameter \returns The value of the parameter
\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

@ -30,221 +30,220 @@
namespace sgpem namespace sgpem
{ {
class PolicyParametersException : public std::runtime_error class PolicyParametersException : public std::runtime_error
{ {
public: public:
PolicyParametersException(char* msg): std::runtime_error(msg) {} PolicyParametersException(char* msg): std::runtime_error(msg) {}};
}; class PolicyParameters;
class PolicyParameters;
/** \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:
template<typename T> template<typename T>
class Parameter; class Parameter;
//####################################### //#######################################
//########## methods to CREATE PARAMETERS //########## methods to CREATE PARAMETERS
//####################################### //#######################################
/**\brief Registers an INTEGER parameter. /**\brief Registers an INTEGER parameter.
This method adds an INTEGER parameter to the list of parameters represented by this class. This method adds an INTEGER parameter to the list of parameters represented by this class.
\warning If a parameter named \e name already exists it will be replaced by this one. \warning If a parameter named \e name already exists it will be replaced by this one.
\param name The name of the parameter. This string will be used to refer to this parameter \param name The name of the parameter. This string will be used to refer to this parameter
in the methods set_int(...), get_int(...) and get_registered_int_parameters(...). in the methods set_int(...), get_int(...) and get_registered_int_parameters(...).
\param lower_bound The lower limitation of the value which can be set with set_int(...). \param lower_bound The lower limitation of the value which can be set with set_int(...).
\param upper_bound The upper limitation of the value which can be set with set_int(...). \param upper_bound The upper limitation of the value which can be set with set_int(...).
\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.
This method adds a FLOAT parameter to the list of parameters represented by this class. This method adds a FLOAT parameter to the list of parameters represented by this class.
\warning If a parameter named \e name already exists it will be replaced by this one. \warning If a parameter named \e name already exists it will be replaced by this one.
\param name The name of the parameter. This string will be used to refer to this parameter \param name The name of the parameter. This string will be used to refer to this parameter
in the methods set_float(...), get_float(...) and get_registered_float_parameters(...). in the methods set_float(...), get_float(...) and get_registered_float_parameters(...).
\param lower_bound The lower limitation of the value which can be set with set_int(...). \param lower_bound The lower limitation of the value which can be set with set_int(...).
\param upper_bound The upper limitation of the value which can be set with set_int(...). \param upper_bound The upper limitation of the value which can be set with set_int(...).
\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.
This method adds a STRING parameter to the list of parameters represented by this class. This method adds a STRING parameter to the list of parameters represented by this class.
Note that there are no limitations to the value thath this parameter can assume. Note that there are no limitations to the value thath this parameter can assume.
\warning If a parameter named \e name already exists it will be replaced by this one. \warning If a parameter named \e name already exists it will be replaced by this one.
\param name The name of the parameter. This string will be used to refer to this parameter \param name The name of the parameter. This string will be used to refer to this parameter
in the methods set_string(...), get_string(...) and get_registered_string_parameters(...). in the methods set_string(...), get_string(...) and get_registered_string_parameters(...).
\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();
//############################################# //#############################################
//###### methods to RETRIEVE CREATED PARAMETERS //###### methods to RETRIEVE CREATED PARAMETERS
//############################################# //#############################################
/** \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;
//############################################# //#############################################
//###### methods to SET the VALUE of PARAMETERS //###### methods to SET the VALUE of PARAMETERS
//############################################# //#############################################
/** \brief Sets the value of a registred INTEGER parameter /** \brief Sets the value of a registred INTEGER parameter
Permits to change the value of a parameter identified by "name" Permits to change the value of a parameter identified by "name"
\returns TRUE if the specified "name" maps to a registered parameter and if "value" doesn't \returns TRUE if the specified "name" maps to a registered parameter and if "value" doesn't
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
Permits to change the value of a parameter identified by "name" Permits to change the value of a parameter identified by "name"
\returns TRUE if the specified "name" maps to a registered parameter and if "value" doesn't \returns TRUE if the specified "name" maps to a registered parameter and if "value" doesn't
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
Permits to change the value of a parameter identified by "name" Permits to change the value of a parameter identified by "name"
\returns TRUE if the specified "name" maps to a registered parameter and if "value" doesn't \returns TRUE if the specified "name" maps to a registered parameter and if "value" doesn't
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);
//############################################# //#############################################
//###### methods to GET the VALUE of PARAMETERS //###### methods to GET the VALUE of PARAMETERS
//############################################# //#############################################
/** \brief Returns the value of an INTEGER parameter /** \brief Returns the value of an INTEGER parameter
\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: private:
std::map<Glib::ustring, Parameter<int> > int_map; std::map<Glib::ustring, Parameter<int> > int_map;
std::map<Glib::ustring, Parameter<float> > float_map; std::map<Glib::ustring, Parameter<float> > float_map;
std::map<Glib::ustring, Parameter<Glib::ustring> > string_map; std::map<Glib::ustring, Parameter<Glib::ustring> > string_map;
}; };
/** \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 PolicyParameters::Parameter class PolicyParameters::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
\param lower_bound The lower limitation of the value which can be set with set_int(...). \param lower_bound The lower limitation of the value which can be set with set_int(...).
\param upper_bound The upper limitation of the value which can be set with set_int(...). \param upper_bound The upper limitation of the value which can be set with set_int(...).
\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, const T& lower_bound, const T& upper_bound, const bool& required, const T& default_value = 0); Parameter(Glib::ustring name, const T& value, const T& lower_bound, const T& upper_bound, const bool& required, const T& default_value = 0);
/** \returns The name of the parameter (its UNIQUE key) /** \returns The name of the parameter (its UNIQUE key)
*/ */
Glib::ustring get_name() const; Glib::ustring get_name() const;
/** \returns The lower bound /** \returns The lower bound
*/ */
T get_lower_bound() const; T get_lower_bound() const;
/** \returns The upper bound /** \returns The upper bound
*/ */
T get_upper_bound() const; T get_upper_bound() const;
/** \returns TRUE if this parameter is required /** \returns TRUE if this parameter is required
*/ */
bool is_required() const; bool is_required() const;
/** \returns Its default value /** \returns Its default value
*/ */
T get_default() const; T get_default() const;
/** \returns Its actual value /** \returns Its actual value
*/ */
T get_value() const; T get_value() const;
/** \brief Changes the value of the parameter. /** \brief Changes the value of the parameter.
\warning NO CHECK is done whether the value repects its bounds!! \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;
}; };
}//~ namespace sgpem }//~ namespace sgpem

View File

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

View File

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

View File

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

View File

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

View File

@ -41,11 +41,11 @@ namespace sgpem
*/ */
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
}; };
virtual ~Schedulable() = 0; virtual ~Schedulable() = 0;

View File

@ -27,89 +27,88 @@ using namespace std;
using namespace memory; using namespace memory;
SchedulableQueue::SchedulableQueue() SchedulableQueue::SchedulableQueue()
{ {}
}
DynamicSchedulable* DynamicSchedulable*
SchedulableQueue::top() SchedulableQueue::top()
{ {
if (_list.size() == 0) if (_list.size() == 0)
return NULL; return NULL;
return &_list.front(); return &_list.front();
} }
DynamicSchedulable* DynamicSchedulable*
SchedulableQueue::bottom() SchedulableQueue::bottom()
{ {
if (_list.size() == 0) if (_list.size() == 0)
return NULL; return NULL;
return &_list.back(); return &_list.back();
} }
/** /**
Returns a pointer to the element at position "where". If the queue is empty or "where" is Returns a pointer to the element at position "where". If the queue is empty or "where" is
out of rangethe NULL pointer will be returned. out of rangethe NULL pointer will be returned.
DON'T call delete on the returned pointer! Its destruction is managed by the queue. DON'T call delete on the returned pointer! Its destruction is managed by the queue.
*/ */
DynamicSchedulable* DynamicSchedulable*
SchedulableQueue::get_item_at(const uint& where) SchedulableQueue::get_item_at(const uint& where)
{ {
if (_list.size() == 0 || where >= _list.size()) if (_list.size() == 0 || where >= _list.size())
return NULL; return NULL;
list<DynamicSchedulable>::iterator i = _list.begin(); list<DynamicSchedulable>::iterator i = _list.begin();
for (uint f=0; f < where; f++) for (uint f = 0; f < where; f++)
i++; i++;
return &(*i); return &(*i);
} }
const DynamicSchedulable* const DynamicSchedulable*
SchedulableQueue::get_item_at(const uint& where) const SchedulableQueue::get_item_at(const uint& where) const
{ {
if (_list.size() == 0 || where >= _list.size()) if (_list.size() == 0 || where >= _list.size())
return NULL; return NULL;
list<DynamicSchedulable>::const_iterator i = _list.begin(); list<DynamicSchedulable>::const_iterator i = _list.begin();
for (uint f=0; f < where; f++) for (uint f = 0; f < where; f++)
i++; i++;
return &(*i); return &(*i);
} }
/** /**
Returns the number of elements inserted into the queue. Returns the number of elements inserted into the queue.
*/ */
uint uint
SchedulableQueue::size() const SchedulableQueue::size() const
{ {
return _list.size(); return _list.size();
} }
void void
SchedulableQueue::add_at_top(const DynamicSchedulable& ss) SchedulableQueue::add_at_top(const DynamicSchedulable& ss)
{ {
_list.push_front(ss); _list.push_front(ss);
} }
void void
SchedulableQueue::add_at_bottom(const DynamicSchedulable& ss) SchedulableQueue::add_at_bottom(const DynamicSchedulable& ss)
{ {
_list.push_back(ss); _list.push_back(ss);
} }
smart_ptr<DynamicSchedulable> smart_ptr<DynamicSchedulable>
SchedulableQueue::remove(const uint& position) SchedulableQueue::remove(const uint& position)
{ {
if (_list.size() == 0 || position >= _list.size()) if (_list.size() == 0 || position >= _list.size())
return smart_ptr<DynamicSchedulable>(NULL); return smart_ptr<DynamicSchedulable>(NULL);
//creates a copy of the first element //creates a copy of the first element
smart_ptr<DynamicSchedulable> sm = new DynamicSchedulable(*top()); smart_ptr<DynamicSchedulable> sm = new DynamicSchedulable(*top());
//pops the first element //pops the first element
_list.pop_front(); _list.pop_front();
//returns the copy //returns the copy
return sm; return sm;
} }
/** /**
@ -118,37 +117,37 @@ SchedulableQueue::remove(const uint& position)
bool bool
SchedulableQueue::insert_at(const uint& which, const uint& where) SchedulableQueue::insert_at(const uint& which, const uint& where)
{ {
//out of range //out of range
if (which >= _list.size() || where >= _list.size()) if (which >= _list.size() || where >= _list.size())
return false; return false;
//nothing to do //nothing to do
if (where == which) if (where == which)
return true; return true;
list<DynamicSchedulable>::iterator i_where = _list.begin(); list<DynamicSchedulable>::iterator i_where = _list.begin();
list<DynamicSchedulable>::iterator i_which = _list.begin(); list<DynamicSchedulable>::iterator i_which = _list.begin();
for (uint f=0; f < where; f++) for (uint f = 0; f < where; f++)
i_where++; i_where++;
for (uint f=0; f < which; f++) for (uint f = 0; f < which; f++)
i_which++; i_which++;
//save and pop WHICH //save and pop WHICH
DynamicSchedulable temp = *i_which; DynamicSchedulable temp = *i_which;
_list.erase(i_which); _list.erase(i_which);
//insert WHICH before WHERE //insert WHICH before WHERE
_list.insert(i_where, temp); _list.insert(i_where, temp);
return true; return true;
} }
/** /**
Removes all elements Removes all elements
*/ */
void void
SchedulableQueue::clear() SchedulableQueue::clear()
{ {
_list.clear(); _list.clear();
} }
@ -158,7 +157,7 @@ SchedulableQueue::clear()
bool bool
SchedulableQueue::operator==(const SchedulableQueue& dx) const SchedulableQueue::operator==(const SchedulableQueue& dx) const
{ {
return _list == dx._list; return _list == dx._list;
} }
@ -168,49 +167,49 @@ SchedulableQueue::operator==(const SchedulableQueue& dx) const
bool bool
SchedulableQueue::has_same_objects(const SchedulableQueue& dx) const SchedulableQueue::has_same_objects(const SchedulableQueue& dx) const
{ {
if (_list.size() != dx._list.size()) if (_list.size() != dx._list.size())
return false; return false;
//check if dx has ALL and ONLY the elements holded by _list with no order importance //check if dx has ALL and ONLY the elements holded by _list with no order importance
for(list<DynamicSchedulable>::const_iterator f=_list.begin(); f != _list.end(); f++) for(list<DynamicSchedulable>::const_iterator f = _list.begin(); f != _list.end(); f++)
if (find(dx._list.begin(), dx._list.end(), *f) == dx._list.end()) //element NOT found!! if (find(dx._list.begin(), dx._list.end(), *f) == dx._list.end()) //element NOT found!!
return false; return false;
return true; return true;
} }
void void
SchedulableQueue::swap(unsigned int positionA, unsigned int positionB) throw() SchedulableQueue::swap(unsigned int positionA, unsigned int positionB) throw()
{ {
if (positionA == positionB || positionA >= _list.size() || positionB >= _list.size()) if (positionA == positionB || positionA >= _list.size() || positionB >= _list.size())
return; return;
unsigned int min, max; unsigned int min, max;
if (positionA < positionB) if (positionA < positionB)
{ {
min = positionA; min = positionA;
max = positionB; max = positionB;
} }
else else
{ {
min = positionB; min = positionB;
max = positionA; max = positionA;
} }
list<DynamicSchedulable>::iterator i1 = _list.begin(); list<DynamicSchedulable>::iterator i1 = _list.begin();
list<DynamicSchedulable>::iterator i2 = _list.begin(); list<DynamicSchedulable>::iterator i2 = _list.begin();
//reach the first element; //reach the first element;
for (uint f=0; f < min; f++) for (uint f = 0; f < min; f++)
i1++; i1++;
DynamicSchedulable temp = *i1; DynamicSchedulable temp = *i1;
//reach the second element; //reach the second element;
i2 = i1; i2 = i1;
for (uint f=min; f < max; f++) for (uint f = min; f < max; f++)
i2++; i2++;
*i1 = *i2; *i1 = *i2;
*i2 = temp; *i2 = temp;
} }

View File

@ -63,13 +63,13 @@ namespace sgpem
void add_at_bottom(const DynamicSchedulable&); void add_at_bottom(const DynamicSchedulable&);
/** \brief Removes */ /** \brief Removes */
/** /**
Removes an element from the list. Returns a smart pointer a copy of it or to NULL if Removes an element from the list. Returns a smart pointer a copy of it or to NULL if
"position" is out of range. "position" is out of range.
Ex. remove(0); removes the top of the list Ex. remove(0); removes the top of the list
Ex. remove(size()-1) removes the bottom of the list Ex. remove(size()-1) removes the bottom of the list
*/ */
memory::smart_ptr<sgpem::DynamicSchedulable> remove(const unsigned int& position); memory::smart_ptr<sgpem::DynamicSchedulable> remove(const unsigned int& position);
bool insert_at(const unsigned int&, const unsigned int&); bool insert_at(const unsigned int&, const unsigned int&);
@ -92,7 +92,7 @@ namespace sgpem
* \param positionA The position of the first element to swap * \param positionA The position of the first element to swap
* \param positionB The position of the second element to swap * \param positionB The position of the second element to swap
*/ */
void swap(unsigned int positionA, unsigned int positionB) throw(); void swap(unsigned int positionA, unsigned int positionB) throw();
private: private:
std::list<DynamicSchedulable> _list; std::list<DynamicSchedulable> _list;

View File

@ -37,7 +37,7 @@ template class SG_DLLEXPORT Singleton<Scheduler>;
//private constructor. The parameter is discarded //private constructor. The parameter is discarded
Scheduler::Scheduler() Scheduler::Scheduler()
: _policy_manager(PolicyManager::get_registered_manager()) : _policy_manager(PolicyManager::get_registered_manager())
{ {
_policy_manager.init(); _policy_manager.init();
} }
@ -51,15 +51,15 @@ Scheduler::get_ready_queue()
/** \note E' fondamentale che questo metodo memorizzi localmente qualora la politica /** \note E' fondamentale che questo metodo memorizzi localmente qualora la politica
attuale sia a prerilascio o meno, e la durata del quanto di tempo, in quanto la politica attuale sia a prerilascio o meno, e la durata del quanto di tempo, in quanto la politica
e' libera di variare questi parametri a piacere durante l'esecuzione della simulazione e' libera di variare questi parametri a piacere durante l'esecuzione della simulazione
*/ */
void void
Scheduler::reset_status() Scheduler::reset_status()
{ {
_ready_queue.clear(); _ready_queue.clear();
History::get_instance().truncate_at(0); History::get_instance().truncate_at(0);
// restore the policy // restore the policy
} }
/* void /* void
@ -81,133 +81,133 @@ void
Scheduler::step_forward() throw(UserInterruptException) Scheduler::step_forward() throw(UserInterruptException)
{ {
try try
{
Policy& policy = get_policy();
History& h = History::get_instance();
//******************
//check for arrivals and prepare the queue
//******************
smart_ptr<SchedulableQueue> initial = h.get_simulation_status_at(h.get_current_time());
if (!initial)
{ {
Policy& policy = get_policy(); cout << _("\nNo initial state inserted!!\n");
return;
History& h = History::get_instance();
//******************
//check for arrivals and prepare the queue
//******************
smart_ptr<SchedulableQueue> initial = h.get_simulation_status_at(h.get_current_time());
if (!initial)
{
cout << _("\nNo initial state inserted!!\n");
return;
}
_ready_queue.clear();
//adds running schedulable
smart_ptr<DynamicSchedulable> running_ptr = h.get_scheduled_at(h.get_current_time());
if (running_ptr)
_ready_queue.add_at_top(*running_ptr);
//adds the READY ones
for(uint rea=0; rea < initial->size(); rea++)
if (initial->get_item_at(rea)->get_state() == DynamicSchedulable::state_ready)
_ready_queue.add_at_bottom(*initial->get_item_at(rea));
//adds each new ready schedulable and sorts the queue
for(uint i=0; i < initial->size(); i++)
if (initial->get_item_at(i)->get_state() == DynamicSchedulable::state_future
&& (int)initial->get_item_at(i)->get_schedulable()->get_arrival_time() == h.get_current_time())
{
//cout << "\nnuovo running: " << initial->get_item_at(i)->get_schedulable()->get_name();
//restore the old running schedulable
if (policy.is_pre_emptive() == false && running_ptr)
_ready_queue.remove(0);
//adds the NEW one
_ready_queue.add_at_bottom(*initial->get_item_at(i));
_ready_queue.get_item_at(_ready_queue.size()-1)->set_state(DynamicSchedulable::state_ready);
initial->get_item_at(i)->set_state(DynamicSchedulable::state_ready);
// Sort the queue
policy.sort_queue();
//restore the old running schedulable
if (policy.is_pre_emptive() == false && running_ptr)
_ready_queue.add_at_top(*running_ptr);
}
//****************
// Check for termination
//****************
if (running_ptr && running_ptr->get_cpu_time_left() == 0)
{
//there is a running schedulable and it's terminated. Append at the bottom with the state TERMINATED
for(uint i=0; i < _ready_queue.size(); i++)
if (*_ready_queue.get_item_at(i) == *running_ptr)
{
_ready_queue.add_at_bottom(*_ready_queue.get_item_at(i));
_ready_queue.remove(i);
_ready_queue.get_item_at(_ready_queue.size()-1)->set_state(DynamicSchedulable::state_terminated);
break;
}
//cout << "\nTERMINATO!!";
running_ptr = NULL;
//IF _ready_queue.size() == 0 sort_queue(...) is called but has no effect!!
policy.sort_queue();
}
//*****************
// Check for time slice
//*****************
if (policy.get_time_slice() != numeric_limits<int>::max()) //time-slice
policy.sort_queue();
//******************
// Create the final list of schedulable
//******************
if (_ready_queue.size() != 0 && (_ready_queue.get_item_at(0)->get_state() == DynamicSchedulable::state_ready
|| _ready_queue.get_item_at(0)->get_state() == DynamicSchedulable::state_running))
{
//the first ready element IS the running one (if != *running_ptr then there is a CONTEXT SWICH)
_ready_queue.get_item_at(0)->set_state(DynamicSchedulable::state_running);
_ready_queue.get_item_at(0)->give_cpu_time(1);
}
//all the others are ready
for (uint i = 1; i < _ready_queue.size(); i++)
if (_ready_queue.get_item_at(i)->get_state() == DynamicSchedulable::state_running)
_ready_queue.get_item_at(i)->set_state(DynamicSchedulable::state_ready);
//append blocked, future, and terminated schedulables
for (uint i = 0; i < initial->size(); i++)
if(initial->get_item_at(i)->get_state() == DynamicSchedulable::state_blocked
|| initial->get_item_at(i)->get_state() == DynamicSchedulable::state_future
|| initial->get_item_at(i)->get_state() == DynamicSchedulable::state_terminated)
_ready_queue.add_at_bottom(*initial->get_item_at(i));
cout << "\n";
/* for (uint i = 0; i < _ready_queue.size(); i++)
cout << " " << _ready_queue.get_item_at(i)->get_schedulable()->get_name()
<<"_" << _ready_queue.get_item_at(i)->get_state();
*/
h.enqueue_slice(_ready_queue);
} }
_ready_queue.clear();
//adds running schedulable
smart_ptr<DynamicSchedulable> running_ptr = h.get_scheduled_at(h.get_current_time());
if (running_ptr)
_ready_queue.add_at_top(*running_ptr);
//adds the READY ones
for(uint rea = 0; rea < initial->size(); rea++)
if (initial->get_item_at(rea)->get_state() == DynamicSchedulable::state_ready)
_ready_queue.add_at_bottom(*initial->get_item_at(rea));
//adds each new ready schedulable and sorts the queue
for(uint i = 0; i < initial->size(); i++)
if (initial->get_item_at(i)->get_state() == DynamicSchedulable::state_future
&& (int)initial->get_item_at(i)->get_schedulable()->get_arrival_time() == h.get_current_time())
{
//cout << "\nnuovo running: " << initial->get_item_at(i)->get_schedulable()->get_name();
//restore the old running schedulable
if (policy.is_pre_emptive() == false && running_ptr)
_ready_queue.remove(0);
//adds the NEW one
_ready_queue.add_at_bottom(*initial->get_item_at(i));
_ready_queue.get_item_at(_ready_queue.size() - 1)->set_state(DynamicSchedulable::state_ready);
initial->get_item_at(i)->set_state(DynamicSchedulable::state_ready);
// Sort the queue
policy.sort_queue();
//restore the old running schedulable
if (policy.is_pre_emptive() == false && running_ptr)
_ready_queue.add_at_top(*running_ptr);
}
//****************
// Check for termination
//****************
if (running_ptr && running_ptr->get_cpu_time_left() == 0)
{
//there is a running schedulable and it's terminated. Append at the bottom with the state TERMINATED
for(uint i = 0; i < _ready_queue.size(); i++)
if (*_ready_queue.get_item_at(i) == *running_ptr)
{
_ready_queue.add_at_bottom(*_ready_queue.get_item_at(i));
_ready_queue.remove(i);
_ready_queue.get_item_at(_ready_queue.size() - 1)->set_state(DynamicSchedulable::state_terminated);
break;
}
//cout << "\nTERMINATO!!";
running_ptr = NULL;
//IF _ready_queue.size() == 0 sort_queue(...) is called but has no effect!!
policy.sort_queue();
}
//*****************
// Check for time slice
//*****************
if (policy.get_time_slice() != numeric_limits<int>::max()) //time-slice
policy.sort_queue();
//******************
// Create the final list of schedulable
//******************
if (_ready_queue.size() != 0 && (_ready_queue.get_item_at(0)->get_state() == DynamicSchedulable::state_ready
|| _ready_queue.get_item_at(0)->get_state() == DynamicSchedulable::state_running))
{
//the first ready element IS the running one (if != *running_ptr then there is a CONTEXT SWICH)
_ready_queue.get_item_at(0)->set_state(DynamicSchedulable::state_running);
_ready_queue.get_item_at(0)->give_cpu_time(1);
}
//all the others are ready
for (uint i = 1; i < _ready_queue.size(); i++)
if (_ready_queue.get_item_at(i)->get_state() == DynamicSchedulable::state_running)
_ready_queue.get_item_at(i)->set_state(DynamicSchedulable::state_ready);
//append blocked, future, and terminated schedulables
for (uint i = 0; i < initial->size(); i++)
if(initial->get_item_at(i)->get_state() == DynamicSchedulable::state_blocked
|| initial->get_item_at(i)->get_state() == DynamicSchedulable::state_future
|| initial->get_item_at(i)->get_state() == DynamicSchedulable::state_terminated)
_ready_queue.add_at_bottom(*initial->get_item_at(i));
cout << "\n";
/* for (uint i = 0; i < _ready_queue.size(); i++)
cout << " " << _ready_queue.get_item_at(i)->get_schedulable()->get_name()
<<"_" << _ready_queue.get_item_at(i)->get_state();
*/
h.enqueue_slice(_ready_queue);
}
catch( UserInterruptException e ) catch( UserInterruptException e )
{ {
_policy_manager.init(); _policy_manager.init();
throw; throw;
//TODO Do we need to perform some cleanup operation here? //TODO Do we need to perform some cleanup operation here?
// Do we need to update something? // Do we need to update something?
// https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1165761&group_id=5470 // https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1165761&group_id=5470
// maybe it's that??? oh, damn. // maybe it's that??? oh, damn.
// or maybe not. see http://www.python.org/doc/2.4.2/api/initialization.html // or maybe not. see http://www.python.org/doc/2.4.2/api/initialization.html
// Tell: // Tell:
// - the user that the policy sucks // - the user that the policy sucks
// - SimulationController that everything stopped // - SimulationController that everything stopped
} }
} }

View File

@ -44,14 +44,14 @@ 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
is well-defined and does not disrupt the application inner mechanism. is well-defined and does not disrupt the application inner mechanism.
It is also responsible for the creation and the destruction of some of It is also responsible for the creation and the destruction of some of
the DynamicSchedulable objects (for further details about this, check the DynamicSchedulable objects (for further details about this, check
class DynamicSchedulable). class DynamicSchedulable).
*/ */
@ -65,34 +65,34 @@ namespace sgpem
\return a pointer to the queue containing all the ready \return 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).
*/ */
SchedulableQueue* get_ready_queue(); SchedulableQueue* get_ready_queue();
/** /**
Resets the simulation to the initial state. Resets the simulation to the initial state.
*/ */
void reset_status(); void reset_status();
/** /**
Generates a new SchedulableQueue representing the status of the processes Generates a new SchedulableQueue 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
one instant with it. one instant with it.
*/ */
void step_forward() throw(UserInterruptException); void step_forward() throw(UserInterruptException);
/** /**
Sets the policy that will be used to generate the simulation at the next instant. Sets the policy that will be used to generate the simulation at the next instant.
\param policy the policy that will be used to generate the simulation at the next instant. \param policy the policy that will be used to generate the simulation at the next instant.
*/ */
/* DISABLED until we don't have PolicyManager::set_policy() /* DISABLED until we don't have PolicyManager::set_policy()
void set_policy(Policy* policy); void set_policy(Policy* policy);
*/ */
/** /**
Returns the policy that will be used to generate the simulation at the next instant. Returns the policy that will be used to generate the simulation at the next instant.
\return the policy that will be used to generate the simulation at the next instant. \return the policy that will be used to generate the simulation at the next instant.
*/ */
Policy& get_policy(); Policy& get_policy();
private: private:
Scheduler(); //private constructor. Scheduler(); //private constructor.
SchedulableQueue _ready_queue; SchedulableQueue _ready_queue;
PolicyManager& _policy_manager; PolicyManager& _policy_manager;
}; };
}//~ namespace sgpem }//~ namespace sgpem

View File

@ -24,9 +24,8 @@ using namespace std;
Slice::Slice(const int& start, const int& duration, const SchedulableQueue& status) Slice::Slice(const int& start, const int& duration, const SchedulableQueue& status)
: _ref(status), _started_at(start), _duration(duration) : _ref(status), _started_at(start), _duration(duration)
{ {}
}
const SchedulableQueue* const SchedulableQueue*
Slice::get_simulation_status() const Slice::get_simulation_status() const

View File

@ -39,43 +39,43 @@ namespace sgpem
class SG_DLLEXPORT Slice class SG_DLLEXPORT Slice
{ {
public: public:
/** /**
Constructor for Slice. Constructor for Slice.
\param start The Slice's starting time. \param start The Slice's starting time.
\param duration Time length of Slice. \param duration Time length of Slice.
\param status Photoshot of all \ref Schedulable during this Slice. \param status Photoshot of all \ref Schedulable during this Slice.
*/ */
Slice(const int& start, const int& duration, const SchedulableQueue& status); Slice(const int& start, const int& duration, const SchedulableQueue& status);
/** /**
Gets a constant reference to the \ref SchedulableQueue object for this Slice. Gets a constant reference to the \ref SchedulableQueue object for this Slice.
\return The reference (constant) to the SchedulableQueue object for this Slice. \return The reference (constant) to the SchedulableQueue object for this Slice.
*/ */
const SchedulableQueue* get_simulation_status() const; const SchedulableQueue* get_simulation_status() const;
/** /**
Gets starting time of this Slice. Gets starting time of this Slice.
\return The starting time. \return The starting time.
*/ */
int get_started_at() const; int get_started_at() const;
/** /**
Gets duration of this Slice. Gets duration of this Slice.
\return The duration time. \return The duration time.
*/ */
int get_duration() const; int get_duration() const;
/** /**
Sets duration of this Slice. Sets duration of this Slice.
\param duration The desired duration time. \param duration The desired duration time.
*/ */
void set_duration(const int& duration); void set_duration(const int& duration);
private: private:
SchedulableQueue _ref; SchedulableQueue _ref;
int _started_at; int _started_at;
int _duration; int _duration;
}; };
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -23,13 +23,11 @@ using namespace sgpem;
StaticProcess::StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const unsigned int& total, const int& priority) StaticProcess::StaticProcess(const Glib::ustring& name, const unsigned int& arrival, const unsigned int& total, const int& priority)
: StaticSchedulable(name, arrival, total, priority) : StaticSchedulable(name, arrival, total, priority)
{ {}
}
StaticProcess::~StaticProcess() StaticProcess::~StaticProcess()
{ {}
}
Glib::ustring Glib::ustring
StaticProcess::get_type() const StaticProcess::get_type() const

View File

@ -43,7 +43,7 @@ namespace sgpem
/** \brief Destructor. */ /** \brief Destructor. */
~StaticProcess(); ~StaticProcess();
/** \brief Returns a string describing the type of the object. */ /** \brief Returns a string describing the type of the object. */
Glib::ustring get_type() const; Glib::ustring get_type() const;
private: private:
}; };

View File

@ -25,7 +25,7 @@ using namespace sgpem;
StaticRequest::StaticRequest(StaticThread* thread, StaticRequest::StaticRequest(StaticThread* thread,
unsigned int instant) : unsigned int instant) :
_thread(thread), _instant(instant) _thread(thread), _instant(instant)
{ {
assert(thread != NULL); assert(thread != NULL);
} }

View File

@ -24,9 +24,8 @@ using namespace sgpem;
StaticResource::StaticResource(const Glib::ustring& name, StaticResource::StaticResource(const Glib::ustring& name,
unsigned int places) : unsigned int places) :
_name(name), _places(places) _name(name), _places(places)
{ {}
}
Glib::ustring Glib::ustring
StaticResource::get_name() const StaticResource::get_name() const

View File

@ -23,16 +23,14 @@
using namespace sgpem; using namespace sgpem;
StaticSchedulable::StaticSchedulable(const Glib::ustring& name, StaticSchedulable::StaticSchedulable(const Glib::ustring& name,
const unsigned int& arrival, const unsigned int& arrival,
const unsigned int& total, const unsigned int& total,
const int& priority) : const int& priority) :
_name(name), _arrival_time(arrival), _total_time(total), _priority(priority) _name(name), _arrival_time(arrival), _total_time(total), _priority(priority)
{ {}
}
StaticSchedulable::~StaticSchedulable() StaticSchedulable::~StaticSchedulable()
{ {}
}
unsigned int unsigned int
StaticSchedulable::get_arrival_time() const StaticSchedulable::get_arrival_time() const

View File

@ -43,7 +43,7 @@ namespace sgpem
public: public:
/** \brief Create a new object with the given parameters */ /** \brief Create a new object with the given parameters */
StaticSchedulable(const Glib::ustring& name, const unsigned int& arrival, StaticSchedulable(const Glib::ustring& name, const unsigned int& arrival,
const unsigned int& total, const int& priority); const unsigned int& total, const int& priority);
virtual ~StaticSchedulable(); virtual ~StaticSchedulable();
/** \brief Returns the arrival time for this process /** \brief Returns the arrival time for this process

View File

@ -28,8 +28,8 @@ StaticSubRequest::StaticSubRequest(StaticRequest* req,
StaticResource* resource, StaticResource* resource,
unsigned int length, unsigned int length,
unsigned int places) : unsigned int places) :
_static_request(req), _static_resource(resource), _static_request(req), _static_resource(resource),
_length(length), _places(places) _length(length), _places(places)
{ {
assert(req != NULL && resource != NULL); assert(req != NULL && resource != NULL);
} }

View File

@ -30,11 +30,10 @@ StaticThread::StaticThread(const Glib::ustring& name,
StaticProcess& process, StaticProcess& process,
unsigned int arrival_time, unsigned int arrival_time,
int base_priority) : int base_priority) :
StaticSchedulable(name, arrival_time, 0, base_priority), StaticSchedulable(name, arrival_time, 0, base_priority),
_start_time_delta(arrival_time), _required_cpu_time(0), _start_time_delta(arrival_time), _required_cpu_time(0),
_process(&process) _process(&process)
{ {}
}
unsigned int unsigned int
StaticThread::get_total_cpu_time() const StaticThread::get_total_cpu_time() const

View File

@ -39,7 +39,7 @@ namespace sgpem
public: public:
StaticThread(const Glib::ustring& name, StaticThread(const Glib::ustring& name,
StaticProcess& process, StaticProcess& process,
unsigned int arrival_time = 0, unsigned int arrival_time = 0,
int base_priority = 0); int base_priority = 0);
unsigned int get_total_cpu_time() const; unsigned int get_total_cpu_time() const;

View File

@ -24,91 +24,91 @@ using namespace std;
using Glib::ustring; using Glib::ustring;
/** /**
\brief A function that converts a Unicode string to an integer value \brief A function that converts a Unicode string to an integer value
The string can contain ONLY digits and the "minus" character. The string can contain ONLY digits and the "minus" character.
\returns TRUE if the string is well formatted \returns TRUE if the string is well formatted
\returns FALSE otherwise \returns FALSE otherwise
*/ */
bool bool
string_to_int(const ustring& str, int& num) string_to_int(const ustring& str, int& num)
{ {
static const ustring allvalid = "0123456789-"; static const ustring allvalid = "0123456789-";
static const ustring digits = "0123456789"; static const ustring digits = "0123456789";
// the string can't be empty // the string can't be empty
if (str.length() == 0 || (str.length() == 1 && str[0] == '-')) if (str.length() == 0 || (str.length() == 1 && str[0] == '-'))
return false; return false;
//checks if the string contains only digits //checks if the string contains only digits
if (str.find_first_not_of(allvalid) < str.length()) if (str.find_first_not_of(allvalid) < str.length())
return false; return false;
if (str.substr(1).find_first_not_of(digits) < str.length()-1) if (str.substr(1).find_first_not_of(digits) < str.length() - 1)
return false; return false;
num=0; num = 0;
int multiplier = 1, val; int multiplier = 1, val;
int start; //the position of the biggest digit int start; //the position of the biggest digit
if (str[0] == '-') if (str[0] == '-')
start = 1; start = 1;
else else
start = 0; start = 0;
for (int pos = str.length() - 1; pos >= start ; pos--) for (int pos = str.length() - 1; pos >= start ; pos--)
{ {
val = str[pos] - 48; //the INTEGER value of the digit val = str[pos] - 48; //the INTEGER value of the digit
num += val*multiplier; num += val * multiplier;
multiplier *= 10; multiplier *= 10;
} }
//if there is the minus then multiply for -1 //if there is the minus then multiply for -1
if (start == 1) if (start == 1)
num *= -1; num *= -1;
return true; return true;
} }
/** /**
\brief A function that converts an integer value to an Unicode string \brief A function that converts an integer value to an Unicode string
*/ */
void void
int_to_string(const int& num, ustring& str) int_to_string(const int& num, ustring& str)
{ {
if (num == 0) if (num == 0)
{ {
str = '0'; str = '0';
return; return;
} }
str = ""; str = "";
int val = num; int val = num;
bool negative = (val < 0)? true : false; bool negative = (val < 0) ? true : false;
if (negative) val *= -1; if (negative) val *= -1;
while (true) while (true)
{ {
str = char(val % 10 + 48) + str; str = char(val % 10 + 48) + str;
if (val > 1 && val / 10 != 0) if (val > 1 && val / 10 != 0)
val /= 10; val /= 10;
else else
break; break;
} }
if (negative) if (negative)
str = '-' + str; str = '-' + str;
} }
void void
float_to_string(const float& f, Glib::ustring& str) float_to_string(const float& f, Glib::ustring& str)
{ {
stringstream ss; stringstream ss;
ss << f; ss << f;
char p[20]; char p[20];
ss.getline(p,20); ss.getline(p, 20);
str = p; str = p;
} }
void void
string_to_float(const Glib::ustring& str, float& f) string_to_float(const Glib::ustring& str, float& f)
{ {
stringstream ss; stringstream ss;
ss << str; ss << str;
ss >> f; ss >> f;
} }

View File

@ -26,38 +26,38 @@
#include <iostream> #include <iostream>
#include "glibmm/ustring.h" #include "glibmm/ustring.h"
/**\brief This function tries to convert a string into an integer value. /**\brief This function tries to convert a string into an integer value.
The string can contain only digits and the minus character (for negative numbers). The string can contain only digits and the minus character (for negative numbers).
\returns TRUE if ths string represent a valid integer number \returns TRUE if ths string represent a valid integer number
\returns FALSE otherwise \returns FALSE otherwise
*/ */
bool SG_DLLEXPORT string_to_int(const Glib::ustring&, int&); bool SG_DLLEXPORT string_to_int(const Glib::ustring&, int&);
/**\brief This function converts an integer value into a string. /**\brief This function converts an integer value into a string.
There is no return value because this function always succeeds. There is no return value because this function always succeeds.
*/ */
void SG_DLLEXPORT int_to_string(const int&, Glib::ustring&); void SG_DLLEXPORT int_to_string(const int&, Glib::ustring&);
/**\brief This function converts a float value into a string. /**\brief This function converts a float value into a string.
There is no return value because this function always succeeds. There is no return value because this function always succeeds.
*/ */
void SG_DLLEXPORT float_to_string(const float&, Glib::ustring&); void SG_DLLEXPORT float_to_string(const float&, Glib::ustring&);
/**\brief This function tries to convert a string into a float value. /**\brief This function tries to convert a string into a float value.
The string can contain only digits, the minus, plus and dot (-+.) characters. If not, The string can contain only digits, the minus, plus and dot (-+.) characters. If not,
the value 0 is assigned. the value 0 is assigned.
There is no return value because this function always succeeds, even if the string is badly formed. There is no return value because this function always succeeds, even if the string is badly formed.
*/ */
void SG_DLLEXPORT string_to_float(const Glib::ustring&, float&); void SG_DLLEXPORT string_to_float(const Glib::ustring&, float&);
#endif #endif

View File

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

View File

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

View File

@ -40,7 +40,7 @@ namespace sgpem
virtual Process& get_process() = 0; virtual Process& get_process() = 0;
virtual std::vector<Request*> get_requests() = 0; virtual std::vector<Request*> get_requests() = 0;
virtual void serialize(SerializeVisitor& translator) const= 0; virtual void serialize(SerializeVisitor& translator) const = 0;
}; };
} }

View File

@ -29,17 +29,18 @@
#include <stdexcept> #include <stdexcept>
namespace sgpem { namespace sgpem
class UserInterruptException; {
class UserInterruptException;
class SG_DLLEXPORT UserInterruptException : public std::runtime_error class SG_DLLEXPORT UserInterruptException : public std::runtime_error
{ {
public: public:
UserInterruptException(const char* msg = ""); UserInterruptException(const char* msg = "");
virtual ~UserInterruptException() throw (); virtual ~UserInterruptException() throw ();
private: private:
}; };
} //~ namespace sgpem } //~ namespace sgpem
#endif #endif

View File

@ -33,7 +33,8 @@
#include "io_manager.hh" #include "io_manager.hh"
#include "graphical_terminal_io.hh" #include "graphical_terminal_io.hh"
namespace sgpem { namespace sgpem
{
class GraphicalSimulation; class GraphicalSimulation;
@ -48,7 +49,7 @@ namespace sgpem {
GraphicalSimulation(); GraphicalSimulation();
/** /**
Visualize the state of the simulation in a graphic mode Visualize the state of the simulation in a graphic mode
*/ */
void update(); void update();

View File

@ -39,12 +39,12 @@ using namespace std;
using Glib::ustring; using Glib::ustring;
GraphicalTerminalIO::GraphicalTerminalIO(TextSimulation* sim) GraphicalTerminalIO::GraphicalTerminalIO(TextSimulation* sim)
: _sim(sim) : _sim(sim)
{ {
using namespace Gtk; using namespace Gtk;
set_title(_("Textual Simulation Log")); set_title(_("Textual Simulation Log"));
set_default_size(500,300); set_default_size(500, 300);
Box& mainbox = *manage(new VBox()); Box& mainbox = *manage(new VBox());
add(mainbox); add(mainbox);
@ -83,11 +83,11 @@ GraphicalTerminalIO::~GraphicalTerminalIO()
void void
GraphicalTerminalIO::onSend() GraphicalTerminalIO::onSend()
{ {
using Glib::Thread; using Glib::Thread;
pair<pair<TextSimulation*, IOManager*>, const ustring> p( pair<pair<TextSimulation*, IOManager*>, const ustring> p(
pair<TextSimulation*, IOManager*>(_sim, this), pair<TextSimulation*, IOManager*>(_sim, this),
read_command()); read_command());
Thread::create(sigc::bind(&TextSimulation::parse_command, p), true); Thread::create(sigc::bind(&TextSimulation::parse_command, p), true);
} }
@ -95,10 +95,10 @@ GraphicalTerminalIO::onSend()
uint uint
GraphicalTerminalIO::write_buffer(const Glib::ustring& buffer) GraphicalTerminalIO::write_buffer(const Glib::ustring& buffer)
{ {
Glib::Mutex::Lock lock(_mtx); Glib::Mutex::Lock lock(_mtx);
Glib::RefPtr<Gtk::TextBuffer> txbuf = _text_output.get_buffer(); Glib::RefPtr<Gtk::TextBuffer> txbuf = _text_output.get_buffer();
txbuf->insert_at_cursor(buffer); txbuf->insert_at_cursor(buffer);
// Force the UI update queue to flush // Force the UI update queue to flush
// while(Gtk::Main::instance()->events_pending()) // while(Gtk::Main::instance()->events_pending())
@ -117,7 +117,7 @@ GraphicalTerminalIO::read_command()
using Glib::ustring; using Glib::ustring;
static const ustring whitespaces = " \r\b\n\t\a"; static const ustring whitespaces = " \r\b\n\t\a";
// are there any other wspaces? // are there any other wspaces?
ustring command = _text_input.get_text(); ustring command = _text_input.get_text();
@ -125,16 +125,16 @@ GraphicalTerminalIO::read_command()
uint f = command.find_first_not_of(whitespaces); uint f = command.find_first_not_of(whitespaces);
uint l = command.find_last_not_of(whitespaces); uint l = command.find_last_not_of(whitespaces);
if(f == ustring::npos) if(f == ustring::npos)
return ""; return "";
_text_input.set_text(""); _text_input.set_text("");
_text_input.grab_focus(); _text_input.grab_focus();
return command.substr(f,l-f+1); return command.substr(f, l - f + 1);
} }
bool bool
GraphicalTerminalIO::is_full_duplex() GraphicalTerminalIO::is_full_duplex()
{ {
return true; return true;
} }

View File

@ -36,7 +36,8 @@
#include <memory> #include <memory>
namespace sgpem { namespace sgpem
{
// --------------------------------------------- // ---------------------------------------------
@ -55,45 +56,45 @@ namespace sgpem {
public: public:
/** /**
Creates a GraphichalTerminalIO supported by the specified TextSimulation. Creates a GraphichalTerminalIO supported by the specified TextSimulation.
\param sim the TextSimulation that will support this IOManager. \param sim the TextSimulation that will support this IOManager.
*/ */
GraphicalTerminalIO(TextSimulation* sim); GraphicalTerminalIO(TextSimulation* sim);
/** /**
Destructor. Destructor.
*/ */
virtual ~GraphicalTerminalIO(); virtual ~GraphicalTerminalIO();
/** /**
Prints on the window the provided buffer. Prints on the window the provided buffer.
\param buffer the buffer to print. \param buffer the buffer to print.
*/ */
virtual uint write_buffer(const Glib::ustring& buffer); virtual uint write_buffer(const Glib::ustring& buffer);
/** /**
Reads the user input. Reads the user input.
\return the user input. \return the user input.
*/ */
virtual Glib::ustring read_command(); virtual Glib::ustring read_command();
/** /**
Returns whether the IOManager can read user input while performing a write operation. Returns whether the IOManager can read user input while performing a write operation.
\return whether the IOManager can read user input while performing a write operation. \return whether the IOManager can read user input while performing a write operation.
*/ */
virtual bool is_full_duplex(); virtual bool is_full_duplex();
/** /**
Specifies the operations to perform at user input. Specifies the operations to perform at user input.
*/ */
void onSend(); void onSend();
private: private:
TextSimulation* _sim; TextSimulation* _sim;
Gtk::TextView _text_output; Gtk::TextView _text_output;
mutable Gtk::Entry _text_input; mutable Gtk::Entry _text_input;
Glib::Mutex _mtx; Glib::Mutex _mtx;
}; };
} }

View File

@ -26,7 +26,8 @@
#include <glibmm/ustring.h> #include <glibmm/ustring.h>
namespace sgpem { namespace sgpem
{
class IOManager; class IOManager;
@ -41,16 +42,16 @@ namespace sgpem {
/**Writes a string into an output (the console, a text widget, ...) /**Writes a string into an output (the console, a text widget, ...)
\returns the number of written characters \returns the number of written characters
*/ */
virtual uint write_buffer(const Glib::ustring& buffer) = 0; virtual uint write_buffer(const Glib::ustring& buffer) = 0;
/**Reads a command from an interactive input (the console, a text widget, ...) /**Reads a command from an interactive input (the console, a text widget, ...)
\returns a trimmed string (without blank spaces, tabs... at the extremities) \returns a trimmed string (without blank spaces, tabs... at the extremities)
*/ */
virtual Glib::ustring read_command() = 0; virtual Glib::ustring read_command() = 0;
/**Specify whether this IOManger permits to write and read at the same time /**Specify whether this IOManger permits to write and read at the same time
*/ */
virtual bool is_full_duplex() = 0; virtual bool is_full_duplex() = 0;
}; };
} }

View File

@ -55,30 +55,32 @@ using namespace memory;
using Glib::ustring; using Glib::ustring;
static void load_pyloader_plugin() { static void load_pyloader_plugin()
// FIXME: this will need to be moved to an {
// appropriate PluginManager class in the backend, // FIXME: this will need to be moved to an
// and the Makefile fixed accordingly (partly done). // appropriate PluginManager class in the backend,
using Glib::Module; // and the Makefile fixed accordingly (partly done).
using Glib::Module;
// Leaks willingly: // Leaks willingly:
Module* pyloader = 0; Module* pyloader = 0;
GlobalPreferences& prefs = GlobalPreferences::get_instance(); GlobalPreferences& prefs = GlobalPreferences::get_instance();
GlobalPreferences::dir_iterator it = prefs.modules_dir_begin(); GlobalPreferences::dir_iterator it = prefs.modules_dir_begin();
while(it != prefs.modules_dir_end()) { while(it != prefs.modules_dir_end())
std::string pyloader_path = Module::build_path(*it, "pyloader"); {
pyloader = new Module(pyloader_path); std::string pyloader_path = Module::build_path(*it, "pyloader");
if(*pyloader) break; pyloader = new Module(pyloader_path);
else delete pyloader; if(*pyloader) break;
it++; else delete pyloader;
} it++;
}
if(!*pyloader) if(!*pyloader)
std::cerr << Module::get_last_error() << std::endl; std::cerr << Module::get_last_error() << std::endl;
// For the moment, we want to be sure it has been loaded: // For the moment, we want to be sure it has been loaded:
assert(*pyloader); assert(*pyloader);
} }
int int
@ -101,18 +103,18 @@ main(int argc, char* argv[])
int a_count = argc; int a_count = argc;
char** a_ptr = argv; char** a_ptr = argv;
parse_options(a_count, a_ptr); parse_options(a_count, a_ptr);
filenames.insert(filenames.begin(), a_ptr, a_ptr+a_count); filenames.insert(filenames.begin(), a_ptr, a_ptr + a_count);
} }
load_pyloader_plugin(); load_pyloader_plugin();
// Create an INITIAL STATE // Create an INITIAL STATE
StaticProcess p1("P1", 0,5,1); StaticProcess p1("P1", 0, 5, 1);
StaticProcess p2("P2", 0,5,2); StaticProcess p2("P2", 0, 5, 2);
StaticProcess p3("P3", 5,3,3); StaticProcess p3("P3", 5, 3, 3);
StaticProcess p4("P4", 6,2,3); StaticProcess p4("P4", 6, 2, 3);
StaticProcess p5("P5", 1,2,3); StaticProcess p5("P5", 1, 2, 3);
StaticProcess p6("P6", 10,2,1); StaticProcess p6("P6", 10, 2, 1);
DynamicSchedulable ss1(p1); DynamicSchedulable ss1(p1);
DynamicSchedulable ss2(p2); DynamicSchedulable ss2(p2);
@ -131,8 +133,8 @@ main(int argc, char* argv[])
History::get_instance().enqueue_slice(initial); History::get_instance().enqueue_slice(initial);
Scheduler::get_instance(); // Forces initialization of scheduler. Scheduler::get_instance(); // Forces initialization of scheduler.
// Cross fingers (depends if PythonPolicyManager // Cross fingers (depends if PythonPolicyManager
// static object has been initialized before?). // static object has been initialized before?).
//the textual simulation //the textual simulation
TextSimulation text_sim; TextSimulation text_sim;
@ -147,79 +149,79 @@ main(int argc, char* argv[])
start_gui(argc, argv, text_sim); start_gui(argc, argv, text_sim);
//SMOKE-TEST for backend classes //SMOKE-TEST for backend classes
/* cout << "\n\n********************************"; /* cout << "\n\n********************************";
// ************** TEST HISTORY // ************** TEST HISTORY
SchedulableQueue l1; SchedulableQueue l1;
l1.add_at_top(ss1); l1.add_at_top(ss2); l1.add_at_top(ss3); l1.add_at_top(ss1); l1.add_at_top(ss2); l1.add_at_top(ss3);
SchedulableQueue l2; SchedulableQueue l2;
l2.add_at_top(ss4); l2.add_at_top(ss5); l2.add_at_top(ss6); l2.add_at_top(ss4); l2.add_at_top(ss5); l2.add_at_top(ss6);
History h(History::get_instance()); History h(History::get_instance());
h.enqueue_slice(l1); //stato iniziale h.enqueue_slice(l1); //stato iniziale
h.enqueue_slice(l2); h.enqueue_slice(l2);
smart_ptr<const sgpem::SchedulableQueue> quale; smart_ptr<const sgpem::SchedulableQueue> quale;
quale = h.get_simulation_status_at(0); //stato iniziale quale = h.get_simulation_status_at(0); //stato iniziale
cout << quale->get_item_at(0)->get_schedulable()->get_name(); cout << quale->get_item_at(0)->get_schedulable()->get_name();
smart_ptr<const sgpem::DynamicSchedulable> quale2 = h.get_scheduled_at(1); smart_ptr<const sgpem::DynamicSchedulable> quale2 = h.get_scheduled_at(1);
cout << quale2->get_schedulable()->get_name(); cout << quale2->get_schedulable()->get_name();
h.truncate_at(0); h.truncate_at(0);
quale = h.get_simulation_status_at(0); //stato iniziale quale = h.get_simulation_status_at(0); //stato iniziale
cout << bool(quale) << " " << quale->get_item_at(0)->get_schedulable()->get_name(); cout << bool(quale) << " " << quale->get_item_at(0)->get_schedulable()->get_name();
*/ */
/* /*
smart_ptr<const sgpem::SimulationStatus> quale; smart_ptr<const sgpem::SimulationStatus> quale;
quale = h.get_simulation_status_at(0); quale = h.get_simulation_status_at(0);
if (quale) cout << "\n" << quale->get_running()->get_schedulable()->get_name(); else cout << "NO"; if (quale) cout << "\n" << quale->get_running()->get_schedulable()->get_name(); else cout << "NO";
quale = h.get_simulation_status_at(1); quale = h.get_simulation_status_at(1);
if (quale) cout << "\n" << quale->get_running()->get_schedulable()->get_name(); else cout << "NO"; if (quale) cout << "\n" << quale->get_running()->get_schedulable()->get_name(); else cout << "NO";
quale = h.get_simulation_status_at(2); quale = h.get_simulation_status_at(2);
if (quale) cout << "\n" << quale->get_running()->get_schedulable()->get_name(); else cout << "NO"; if (quale) cout << "\n" << quale->get_running()->get_schedulable()->get_name(); else cout << "NO";
h.truncate_at(2); h.truncate_at(2);
smart_ptr<const sgpem::DynamicSchedulable> quale2; smart_ptr<const sgpem::DynamicSchedulable> quale2;
quale2 = h.get_scheduled_at(0); quale2 = h.get_scheduled_at(0);
if (quale2) cout << "\n" << quale2->get_schedulable()->get_name(); else cout << "NO"; if (quale2) cout << "\n" << quale2->get_schedulable()->get_name(); else cout << "NO";
quale2 = h.get_scheduled_at(1); quale2 = h.get_scheduled_at(1);
if (quale2) cout << "\n" << quale2->get_schedulable()->get_name(); else cout << "NO"; if (quale2) cout << "\n" << quale2->get_schedulable()->get_name(); else cout << "NO";
quale2 = h.get_scheduled_at(2); quale2 = h.get_scheduled_at(2);
if (quale2) cout << "\n" << quale2->get_schedulable()->get_name(); else cout << "NO"; if (quale2) cout << "\n" << quale2->get_schedulable()->get_name(); else cout << "NO";
*/ */
//************** TEST QUEUE //************** TEST QUEUE
/* cout << "\n\nTEST QUEUE\n"; /* cout << "\n\nTEST QUEUE\n";
SchedulableQueue sq; SchedulableQueue sq;
sq.add_at_bottom(ss1); sq.add_at_bottom(ss1);
sq.add_at_bottom(ss2); sq.add_at_bottom(ss2);
sq.add_at_bottom(ss3); sq.add_at_bottom(ss3);
cout << sq.get_item_at(0)->get_schedulable()->get_name() << "\n"; cout << sq.get_item_at(0)->get_schedulable()->get_name() << "\n";
cout << sq.get_item_at(1)->get_schedulable()->get_name() << "\n"; cout << sq.get_item_at(1)->get_schedulable()->get_name() << "\n";
cout << sq.get_item_at(2)->get_schedulable()->get_name() << "\n"; cout << sq.get_item_at(2)->get_schedulable()->get_name() << "\n";
sq.insert_at(2,0); sq.insert_at(2,0);
cout << sq.get_item_at(0)->get_schedulable()->get_name() << "\n"; cout << sq.get_item_at(0)->get_schedulable()->get_name() << "\n";
cout << sq.get_item_at(1)->get_schedulable()->get_name() << "\n"; cout << sq.get_item_at(1)->get_schedulable()->get_name() << "\n";
cout << sq.get_item_at(2)->get_schedulable()->get_name() << "\n"; cout << sq.get_item_at(2)->get_schedulable()->get_name() << "\n";
cout << "\n\nTEST POLICYPARAMETERS\n"; cout << "\n\nTEST POLICYPARAMETERS\n";
PolicyParameters pp; PolicyParameters pp;
pp.register_int("ciao", 0, 100, true, 50); pp.register_int("ciao", 0, 100, true, 50);
pp.set_int("ciao",1); pp.set_int("ciao",1);
cout << pp.get_int("ciao"); cout << pp.get_int("ciao");
cout << "\n\n"; cout << "\n\n";
*/ */
return 0; return 0;
} }

View File

@ -26,7 +26,8 @@
#include <gtkmm/window.h> #include <gtkmm/window.h>
namespace sgpem { namespace sgpem
{
// --------------------------------------------- // ---------------------------------------------

View File

@ -23,10 +23,8 @@
using namespace sgpem; using namespace sgpem;
Observer::Observer() Observer::Observer()
{ {}
}
Observer::~Observer() Observer::~Observer()
{ {}
}

View File

@ -37,17 +37,17 @@ namespace sgpem
class SG_DLLEXPORT Observer class SG_DLLEXPORT Observer
{ {
public: public:
Observer(); Observer();
virtual ~Observer() = 0; virtual ~Observer() = 0;
/** /**
\brief Called by observed subject. \brief Called by observed subject.
This will be called by the observed subject once something of This will be called by the observed subject once something of
interest to this observer happens. interest to this observer happens.
\see ObservedSubject \see ObservedSubject
*/ */
virtual void update() =0; virtual void update() = 0;
private: private:
}; };

View File

@ -39,103 +39,103 @@ static void display_help();
void void
parse_options(int& argc, char**& argv) parse_options(int& argc, char**& argv)
{ {
using sgpem::GlobalPreferences; using sgpem::GlobalPreferences;
print_license(); print_license();
static const char* short_options = "NhP:M:"; static const char* short_options = "NhP:M:";
#ifdef _GNU_SOURCE #ifdef _GNU_SOURCE
// Initialize the array for GNU long options // Initialize the array for GNU long options
static struct option long_options[] = static struct option long_options[] =
{ {
{"no-gui", no_argument, NULL, 'N' }, {"no-gui", no_argument, NULL, 'N' },
{"help", no_argument, NULL, 'h' }, {"help", no_argument, NULL, 'h' },
{"policies-dir", required_argument, NULL, 'P'}, {"policies-dir", required_argument, NULL, 'P'},
{"modules-dir", required_argument, NULL, 'M'} {"modules-dir", required_argument, NULL, 'M'}
}; };
int option_index = 0; int option_index = 0;
#endif #endif
int opt; int opt;
do do
{ {
#ifdef _GNU_SOURCE #ifdef _GNU_SOURCE
opt = getopt_long(argc, argv, short_options, opt = getopt_long(argc, argv, short_options,
long_options, &option_index); long_options, &option_index);
#else #else
opt = getopt(argc, argv, short_options); opt = getopt(argc, argv, short_options);
#endif #endif
switch(opt) switch(opt)
{ {
case -1: case - 1:
// We have finished normally // We have finished normally
break; break;
case 'N' : case 'N' :
// We don't return to main, instead we // We don't return to main, instead we
// initialize the command line version // initialize the command line version
// of sgpemv2 (?) // of sgpemv2 (?)
// FIXME : to be written! // FIXME : to be written!
break; break;
case 'P': case 'P':
GlobalPreferences::get_instance().add_policies_dir(optarg); GlobalPreferences::get_instance().add_policies_dir(optarg);
break; break;
case 'M': case 'M':
GlobalPreferences::get_instance().add_modules_dir(optarg); GlobalPreferences::get_instance().add_modules_dir(optarg);
break; break;
case ':': case ':':
printf(_("[EE] Wrong number of parameters. Please see \n" printf(_("[EE] Wrong number of parameters. Please see \n"
"%s --help\n"), argv[0]); "%s --help\n"), argv[0]);
exit(-1); exit(-1);
case 'h' : case 'h' :
default : default :
display_help(); display_help();
} }
} }
while( opt != -1 ); while( opt != -1 );
// Set these two to start from additional filenames on the cmdline: // Set these two to start from additional filenames on the cmdline:
argc -= optind; argc -= optind;
argv += optind; argv += optind;
} }
void void
display_help() display_help()
{ {
printf( _("SGPEMv2 is an educational software acting as a process scheduling simulator\n" printf( _("SGPEMv2 is an educational software acting as a process scheduling simulator\n"
"\n\nUsage : sgpemv2 [options] filename" "\n\nUsage : sgpemv2 [options] filename"
"\n\nOptions:\n" "\n\nOptions:\n"
"\t-h, --help this help you're reading\n" "\t-h, --help this help you're reading\n"
"\t-N, --no-gui starts the program in command line mode\n" "\t-N, --no-gui starts the program in command line mode\n"
"\t-P dir, --policies-dir=dir\n" "\t-P dir, --policies-dir=dir\n"
"\t add this directory to the default modules\n" "\t add this directory to the default modules\n"
"\t search path\n" "\t search path\n"
"\t-M dir, --modules-dir=dir\n" "\t-M dir, --modules-dir=dir\n"
"\t add this directory to default plugin\n" "\t add this directory to default plugin\n"
"\t search path\n" "\t search path\n"
"\nFilename:\n" "\nFilename:\n"
"\t a valid SGPEMv2 XML file\n" "\t a valid SGPEMv2 XML file\n"
"\t to be opened.\n" "\t to be opened.\n"
"\nLong options are available only on GNU systems.\n\n" ) ); "\nLong options are available only on GNU systems.\n\n" ) );
exit(0); exit(0);
} }
void void
print_license() print_license()
{ {
// Do _NOT_ translate this text. // Do _NOT_ translate this text.
std::cerr << std::cerr <<
"SGPEMv2, Copyright (C) 2005, 2006 University of Padova,\n" "SGPEMv2, Copyright (C) 2005, 2006 University of Padova,\n"
" dept. of Pure and Applied Mathematics.\n" " dept. of Pure and Applied Mathematics.\n"
"SGPEMv2 comes with ABSOLUTELY NO WARRANTY. This is free \n" "SGPEMv2 comes with ABSOLUTELY NO WARRANTY. This is free \n"
"software, and you are welcome to redistribute it under \n" "software, and you are welcome to redistribute it under \n"
"the terms of the GNU General Public License; for details\n" "the terms of the GNU General Public License; for details\n"
"see file COPYING contained in the source package. \n" "see file COPYING contained in the source package. \n"
<< std::endl; << std::endl;
} }

View File

@ -28,147 +28,148 @@ using namespace memory;
using Glib::usleep; using Glib::usleep;
Simulation::Simulation(): _state(state_paused), _mode(true), _timer_interval(1000) Simulation::Simulation(): _state(state_paused), _mode(true), _timer_interval(1000)
{ {}
}
void void
Simulation::set_timer(const int& t) Simulation::set_timer(const int& t)
{ {
_timer_interval = t; _timer_interval = t;
} }
int int
Simulation::get_timer() const Simulation::get_timer() const
{ {
return _timer_interval; return _timer_interval;
} }
void void
Simulation::set_mode(const bool& b) Simulation::set_mode(const bool& b)
{ {
_mode = b; _mode = b;
} }
bool bool
Simulation::get_mode() const Simulation::get_mode() const
{ {
return _mode; return _mode;
} }
void void
Simulation::pause() Simulation::pause()
{ {
_state = state_paused; _state = state_paused;
} }
void void
Simulation::stop() Simulation::stop()
{ {
_state = state_stopped; _state = state_stopped;
} }
void void
Simulation::reset() Simulation::reset()
{ {
_state = state_paused; _state = state_paused;
History::get_instance().truncate_at(0); History::get_instance().truncate_at(0);
} }
void void
Simulation::run() throw(UserInterruptException) Simulation::run() throw(UserInterruptException)
{ {
History& h = History::get_instance(); History& h = History::get_instance();
switch(_state) switch(_state)
{ {
case state_running: case state_running:
// FIXME: write out something, or just ignore user input? // FIXME: write out something, or just ignore user input?
return; return;
case state_stopped: case state_stopped:
h.truncate_at(0); h.truncate_at(0);
break; break;
default: default:
break; break;
} }
_state = state_running; _state = state_running;
//******* CONTINUOUS TIME //******* CONTINUOUS TIME
if (_mode) if (_mode)
{ {
do { do
// chech for termination {
bool all_term = true; // chech for termination
smart_ptr<SchedulableQueue> left = h.get_simulation_status_at(h.get_current_time()); bool all_term = true;
for(uint i = 0; i < left->size(); i++) smart_ptr<SchedulableQueue> left = h.get_simulation_status_at(h.get_current_time());
if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated) for(uint i = 0; i < left->size(); i++)
{ if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated)
all_term = false; {
break; all_term = false;
} break;
}
//if there are no processes left the termination message has already been notified //if there are no processes left the termination message has already been notified
//by the last execution of upadate() //by the last execution of upadate()
if (all_term) if (all_term)
{ {
_state = state_stopped; _state = state_stopped;
return; // Exit from loop return; // Exit from loop
} }
try try
{ {
//step forward //step forward
Scheduler::get_instance().step_forward(); Scheduler::get_instance().step_forward();
//sleep //sleep
Glib::usleep(_timer_interval*1000); Glib::usleep(_timer_interval*1000);
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
stop(); stop();
throw; throw;
} }
//check the state //check the state
if (_state == state_stopped || _state == state_paused) if (_state == state_stopped || _state == state_paused)
return; return;
} while(true); }
} while(true);
}
//******* STEP by STEP //******* STEP by STEP
else else
{ {
// chech for termination // chech for termination
bool all_term = true; bool all_term = true;
smart_ptr<SchedulableQueue> left = h.get_simulation_status_at(h.get_current_time()); smart_ptr<SchedulableQueue> left = h.get_simulation_status_at(h.get_current_time());
for(uint i = 0; i < left->size(); i++) for(uint i = 0; i < left->size(); i++)
if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated) if (left->get_item_at(i)->get_state() != DynamicSchedulable::state_terminated)
{ {
all_term = false; all_term = false;
break; break;
} }
if (all_term) if (all_term)
//if there are no processes left the termination message has already been notified //if there are no processes left the termination message has already been notified
//by the last execution of upadate() //by the last execution of upadate()
_state = state_paused; _state = state_paused;
else else
{ {
try try
{ {
//step forward //step forward
Scheduler::get_instance().step_forward(); Scheduler::get_instance().step_forward();
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
throw; throw;
} }
} }
} }
} }
@ -176,45 +177,45 @@ Simulation::run() throw(UserInterruptException)
void void
Simulation::jump_to(const uint& where) throw(UserInterruptException) Simulation::jump_to(const uint& where) throw(UserInterruptException)
{ {
//jump to position 0 //jump to position 0
reset(); reset();
bool old = _mode; bool old = _mode;
_mode = false; _mode = false;
try try
{ {
// executes "where" steps // executes "where" steps
for (uint i=0; i < where; i++) for (uint i = 0; i < where; i++)
run(); run();
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
_mode = old; _mode = old;
throw; throw;
} }
_state = state_paused; _state = state_paused;
_mode = old; _mode = old;
} }
/*void /*void
Simulation::set_policy(Policy* p) Simulation::set_policy(Policy* p)
{ {
Scheduler::get_instance().set_policy(p); Scheduler::get_instance().set_policy(p);
}*/ }*/
Policy* Policy*
Simulation::get_policy() Simulation::get_policy()
{ {
return &Scheduler::get_instance().get_policy(); return &Scheduler::get_instance().get_policy();
} }
vector<Policy*> vector<Policy*>
Simulation::get_avaiable_policies() Simulation::get_avaiable_policies()
{ {
vector<Policy*> v; vector<Policy*> v;
v.push_back(&Scheduler::get_instance().get_policy()); v.push_back(&Scheduler::get_instance().get_policy());
return v; return v;
} }

View File

@ -54,113 +54,113 @@ namespace sgpem
the Backend layers. the Backend layers.
*/ */
class SG_DLLEXPORT Simulation : public Observer class SG_DLLEXPORT Simulation : public Observer
{ {
public: public:
enum state enum state
{ {
state_running, state_running,
state_paused, state_paused,
state_stopped state_stopped
}; };
Simulation(); Simulation();
/** /**
\brief Runs the simulation. \brief Runs the simulation.
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() throw(UserInterruptException); void run() throw(UserInterruptException);
/** /**
\brief Pauses a running simulation. \brief Pauses a running simulation.
It is obviously useful only when the advancement mode is continue. It is obviously useful only when the advancement mode is continue.
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 Stops the simulation. \brief Stops the simulation.
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 Reset the simulation. \brief Reset the simulation.
Erases the state of the simulation, and takes care of removing any Erases the state of the simulation, and takes care of removing any
residual or temporary data to ensure the simulation has reached a residual or temporary data to ensure the simulation has reached a
clean and stable state. clean and stable state.
*/ */
void reset(); void reset();
/** /**
\brief Causes the simulation to jump to the given time unit. \brief Causes the simulation to jump to the given time unit.
*/ */
void jump_to(const uint&) throw(UserInterruptException); void jump_to(const uint&) throw(UserInterruptException);
/** /**
\brief Setter for the attribute timer_interval. \brief Setter for the attribute timer_interval.
This method is used to define how a single time unit is to be This method is used to define how a single time unit is to be
interpreted when the simulation advancement mode is continue. interpreted when the simulation advancement mode is continue.
The input value is in milliseconds, and it must be in range [0, 10000]. The input value is in milliseconds, and it must be in range [0, 10000].
*/ */
void set_timer(const int&); void set_timer(const int&);
/** /**
\see set_timer() \see set_timer()
*/ */
int get_timer() const; int get_timer() const;
/** /**
\brief This methods allows to change the way the simulation progresses. \brief This methods allows to change the way the simulation progresses.
If the input value is 0 (false), the simulation will advance a single time If the input value is 0 (false), the simulation will advance a single time
step for each call to run(). step for each call to run().
If the input value is 1 (true), the simulation will advance contiuosly, If the input value is 1 (true), the simulation will advance contiuosly,
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(const bool&); void set_mode(const bool&);
/** /**
\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.
*/ */
bool get_mode() const; bool get_mode() const;
/** /**
\brief Setup the policy to be used by the system. \brief Setup the policy to be used by the system.
The input pointer must be one of those returned by get_avaiable_policies(). The input pointer must be one of those returned by get_avaiable_policies().
*/ */
void set_policy(Policy*); void set_policy(Policy*);
/** /**
\return The policy currently in use. \return The policy currently in use.
*/ */
Policy* get_policy(); Policy* get_policy();
/** /**
\return A collection of policies (scheduling algorithms), from which a user \return A collection of policies (scheduling algorithms), from which a user
may choose. may choose.
*/ */
std::vector<Policy*> get_avaiable_policies(); std::vector<Policy*> get_avaiable_policies();
private: private:
state _state; state _state;
bool _mode; bool _mode;
int _timer_interval; int _timer_interval;
}; };
} }

View File

@ -27,37 +27,37 @@ using Glib::ustring;
uint uint
StandardIO::write_buffer(const ustring& buffer) StandardIO::write_buffer(const ustring& buffer)
{ {
cout << buffer; cout << buffer;
cout.flush(); cout.flush();
if (cout.good()) if (cout.good())
return buffer.length(); return buffer.length();
else else
return 0; return 0;
} }
ustring ustring
StandardIO::read_command() StandardIO::read_command()
{ {
using namespace std; using namespace std;
char p[2000]; char p[2000];
cin.getline(p,2000); cin.getline(p, 2000);
ustring command(p); ustring command(p);
static const ustring whitespaces = " \r\b\n\t\a"; static const ustring whitespaces = " \r\b\n\t\a";
// are there any other wspaces? // are there any other wspaces?
// trimming: // trimming:
uint f = command.find_first_not_of(whitespaces); uint f = command.find_first_not_of(whitespaces);
uint l = command.find_last_not_of(whitespaces); uint l = command.find_last_not_of(whitespaces);
if(f == ustring::npos) if(f == ustring::npos)
return ""; return "";
return command.substr(f,l-f+1); return command.substr(f, l - f + 1);
} }
bool bool
StandardIO::is_full_duplex() StandardIO::is_full_duplex()
{ {
return false; return false;
} }

View File

@ -29,7 +29,8 @@
#include "io_manager.hh" #include "io_manager.hh"
namespace sgpem { namespace sgpem
{
class StandardIO; class StandardIO;
@ -40,27 +41,27 @@ namespace sgpem {
*/ */
class StandardIO : public IOManager class StandardIO : public IOManager
{ {
public: public:
/** /**
Prints the parameter to standard output. Prints the parameter to standard output.
\param buffer The string to print. \param buffer The string to print.
\return The number of printed characters. \return The number of printed characters.
*/ */
uint write_buffer(const Glib::ustring& buffer); uint write_buffer(const Glib::ustring& buffer);
/** /**
Reads from standard input a command. Reads from standard input a command.
Whitespaces are trimmed at the beginning and at the end. Whitespaces are trimmed at the beginning and at the end.
\return The command string, trimmed of whitespaces. \return The command string, trimmed of whitespaces.
*/ */
Glib::ustring read_command(); Glib::ustring read_command();
/** /**
Returns whether this device can simultaneously read and write. Returns whether this device can simultaneously read and write.
\return true if the device can read and write simultaneously, false otherwise. \return true if the device can read and write simultaneously, false otherwise.
*/ */
bool is_full_duplex(); bool is_full_duplex();
}; };
} }

View File

@ -30,7 +30,7 @@
void void
start_gui(int argc, char** argv, TextSimulation& txt) start_gui(int argc, char** argv, TextSimulation& txt)
{ {
Gtk::Main gtk_main(argc,argv); Gtk::Main gtk_main(argc, argv);
GraphicalTerminalIO* gt = new sgpem::GraphicalTerminalIO(&txt); GraphicalTerminalIO* gt = new sgpem::GraphicalTerminalIO(&txt);
memory::smart_ptr<sgpem::IOManager> main_window(gt); memory::smart_ptr<sgpem::IOManager> main_window(gt);

View File

@ -29,22 +29,21 @@ using namespace sgpem;
template<typename T> template<typename T>
PolicyParameters::Parameter<T>::Parameter(Glib::ustring name, const T& value, const T& lower_bound, const T& upper_bound, const bool& required, const T& default_value) PolicyParameters::Parameter<T>::Parameter(Glib::ustring name, const T& value, const T& lower_bound, const T& upper_bound, const bool& required, const T& default_value)
:_name(name), _value(value), _lower_bound(lower_bound), _upper_bound(upper_bound), _is_required(required), _default(default_value) : _name(name), _value(value), _lower_bound(lower_bound), _upper_bound(upper_bound), _is_required(required), _default(default_value)
{ {}
}
template<typename T> template<typename T>
Glib::ustring Glib::ustring
PolicyParameters::Parameter<T>::get_name() const PolicyParameters::Parameter<T>::get_name() const
{ {
return _name; return _name;
} }
template<typename T> template<typename T>
T T
PolicyParameters::Parameter<T>::get_lower_bound() const PolicyParameters::Parameter<T>::get_lower_bound() const
{ {
return _lower_bound; return _lower_bound;
} }
@ -52,35 +51,35 @@ template<typename T>
T T
PolicyParameters::Parameter<T>::get_upper_bound() const PolicyParameters::Parameter<T>::get_upper_bound() const
{ {
return _upper_bound; return _upper_bound;
} }
template<typename T> template<typename T>
bool bool
PolicyParameters::Parameter<T>::is_required() const PolicyParameters::Parameter<T>::is_required() const
{ {
return _is_required; return _is_required;
} }
template<typename T> template<typename T>
T T
PolicyParameters::Parameter<T>::get_default() const PolicyParameters::Parameter<T>::get_default() const
{ {
return _default; return _default;
} }
template<typename T> template<typename T>
T T
PolicyParameters::Parameter<T>::get_value() const PolicyParameters::Parameter<T>::get_value() const
{ {
return _value; return _value;
} }
template<typename T> template<typename T>
void void
PolicyParameters::Parameter<T>::set_value(const T& val) PolicyParameters::Parameter<T>::set_value(const T& val)
{ {
_value = val; _value = val;
} }

View File

@ -48,7 +48,8 @@ namespace sgpem
private: private:
static Instantiated_class* _instance; static Instantiated_class* _instance;
static Glib::StaticMutex SG_DLLLOCAL _mutex; static Glib::StaticMutex SG_DLLLOCAL _mutex;
}; //~ class Singleton }
; //~ class Singleton
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -20,7 +20,8 @@
#include <new> #include <new>
#include <typeinfo> #include <typeinfo>
namespace memory { namespace memory
{
/** \brief A simple reference counted smart pointer /** \brief A simple reference counted smart pointer
* *
@ -36,14 +37,15 @@ namespace memory {
* *
* \param T The type of the object to store * \param T The type of the object to store
* \param isArray a boolean value telling if we're * \param isArray a boolean value telling if we're
* storing an array or a single object (the default) * storing an array or a single object (the default)
* *
* \warning This class hasn't virtual methods * \warning This class hasn't virtual methods
* to ensure greater speed. Don't inherit * to ensure greater speed. Don't inherit
* from it: its destructor isn't virtual, either. * from it: its destructor isn't virtual, either.
*/ */
template<typename T, bool isArray = false> template<typename T, bool isArray = false>
class smart_ptr { class smart_ptr
{
template<typename T2, bool isArray2> template<typename T2, bool isArray2>
friend class smart_ptr; friend class smart_ptr;
@ -133,7 +135,7 @@ namespace memory {
* the cast isn't successful or doable * the cast isn't successful or doable
*/ */
template<typename U> template<typename U>
smart_ptr<U,isArray> cast_to() throw(std::bad_cast); smart_ptr<U, isArray> cast_to() throw(std::bad_cast);
/** \brief Dynamic cast the stored pointer /** \brief Dynamic cast the stored pointer
* to another type, returning a smart_ptr * to another type, returning a smart_ptr
@ -147,16 +149,18 @@ namespace memory {
* the cast isn't successful or doable * the cast isn't successful or doable
*/ */
template<typename U> template<typename U>
const smart_ptr<U,isArray> cast_to() const throw(std::bad_cast); const smart_ptr<U, isArray> cast_to() const throw(std::bad_cast);
private: private:
template<typename U> template<typename U>
smart_ptr(const smart_ptr<U,isArray>& sptr) throw(std::bad_cast); smart_ptr(const smart_ptr<U, isArray>& sptr) throw(std::bad_cast);
struct contents_type { struct contents_type
{
T* ptr; T* ptr;
unsigned int rc; unsigned int rc;
}* _contents; }
* _contents;
}; };
} }

View File

@ -19,7 +19,8 @@
#include "smartp.hh" #include "smartp.hh"
namespace memory { namespace memory
{
template<typename T, bool isArray> template<typename T, bool isArray>
const smart_ptr<T, isArray> smart_ptr<T, isArray>::null = 0; const smart_ptr<T, isArray> smart_ptr<T, isArray>::null = 0;
@ -28,7 +29,7 @@ namespace memory {
template<typename T, bool isArray> template<typename T, bool isArray>
smart_ptr<T, isArray>::smart_ptr( T* ptr ) throw(std::bad_alloc) smart_ptr<T, isArray>::smart_ptr( T* ptr ) throw(std::bad_alloc)
: _contents(new contents_type()) : _contents(new contents_type())
{ {
_contents->rc = 1; _contents->rc = 1;
_contents->ptr = ptr; _contents->ptr = ptr;
@ -37,7 +38,7 @@ namespace memory {
template<typename T, bool isArray> template<typename T, bool isArray>
smart_ptr<T, isArray>::smart_ptr(const smart_ptr& sptr) throw() smart_ptr<T, isArray>::smart_ptr(const smart_ptr& sptr) throw()
: _contents(sptr._contents) : _contents(sptr._contents)
{ {
(_contents->rc)++; (_contents->rc)++;
} }
@ -49,7 +50,7 @@ namespace memory {
if(--(_contents->rc) == 0) if(--(_contents->rc) == 0)
{ {
if(_contents->ptr != 0) if(_contents->ptr != 0)
!isArray ? delete _contents->ptr : delete [] _contents->ptr; !isArray ? delete _contents->ptr : delete [] _contents->ptr;
delete _contents; delete _contents;
} }
} }
@ -64,9 +65,9 @@ namespace memory {
{ {
if(--(_contents->rc) == 0) if(--(_contents->rc) == 0)
{ {
if(_contents->ptr != 0) if(_contents->ptr != 0)
!isArray ? delete _contents->ptr : delete [] _contents->ptr; !isArray ? delete _contents->ptr : delete [] _contents->ptr;
delete _contents; delete _contents;
} }
_contents = sptr._contents; _contents = sptr._contents;
@ -161,14 +162,14 @@ namespace memory {
template<typename T, bool isArray> template<typename T, bool isArray>
template<typename U> template<typename U>
smart_ptr<T,isArray>::smart_ptr(const smart_ptr<U,isArray>& sptr) smart_ptr<T, isArray>::smart_ptr(const smart_ptr<U, isArray>& sptr)
throw(std::bad_cast) throw(std::bad_cast)
{ {
if(!sptr._contents->ptr || dynamic_cast<T*>(sptr._contents->ptr) == 0) if(!sptr._contents->ptr || dynamic_cast<T*>(sptr._contents->ptr) == 0)
throw std::bad_cast(); throw std::bad_cast();
// I know, I know... this is Evil(TM): // I know, I know... this is Evil(TM):
_contents = reinterpret_cast<typename smart_ptr<T,isArray>::contents_type*>(sptr._contents); _contents = reinterpret_cast<typename smart_ptr<T, isArray>::contents_type*>(sptr._contents);
(_contents->rc)++; (_contents->rc)++;
} }

View File

@ -51,245 +51,245 @@ using namespace std;
*/ */
class HistoryTester class HistoryTester
{ {
public: public:
HistoryTester(SchedulableQueue sl) HistoryTester(SchedulableQueue sl)
: _history_length(-1), _internal_schedulable_queue(sl) : _history_length(-1), _internal_schedulable_queue(sl)
{} {}
/** this method gets a sequence of operations as a parameter and performs them /** this method gets a sequence of operations as a parameter and performs them
* checking for anomalies. * checking for anomalies.
* E stands for EnqueueSlice, R for randomize input, T for truncate the last insertion * E stands for EnqueueSlice, R for randomize input, T for truncate the last insertion
*/ */
void void
test(std::string commands_sequence) test(std::string commands_sequence)
{
// prints the test sequence
std::cout << commands_sequence << endl;
// executes the test sequence
for (unsigned int i = 0; i < commands_sequence.length() && i < 400; i++)
{ {
// prints the test sequence switch(commands_sequence[i])
std::cout << commands_sequence << endl; {
// executes the test sequence case 'E':
for (unsigned int i = 0; i < commands_sequence.length() && i < 400; i++) _insert(_internal_schedulable_queue);
{ break;
switch(commands_sequence[i]) case 'R':
{ _randomize(_internal_schedulable_queue);
case 'E': break;
_insert(_internal_schedulable_queue); case 'T':
break; _truncate();
case 'R': break;
_randomize(_internal_schedulable_queue); default:
break; break;
case 'T': }
_truncate(); _standard_test();
break;
default:
break;
}
_standard_test();
}
return;
} }
return;
}
private: private:
int _history_length; // mirrors the correct length of the history int _history_length; // mirrors the correct length of the history
SchedulableQueue* _get_simulation_status_at[400]; // mirrors the correct content of the history SchedulableQueue* _get_simulation_status_at[400]; // mirrors the correct content of the history
DynamicSchedulable* _get_scheduled_at[400]; // mirrors the correct content of the history DynamicSchedulable* _get_scheduled_at[400]; // mirrors the correct content of the history
SchedulableQueue _internal_schedulable_queue; SchedulableQueue _internal_schedulable_queue;
// looks for anomalies // looks for anomalies
void void
_standard_test() _standard_test()
{
// checks if the Singleton Pattern has been actually implemented
if (&History::get_instance() != &History::get_instance()) std::cout << "\nget_instance";
// checks if the History is long how it should be
if (History::get_instance().get_current_time() != _history_length) std::cout << "\nget_current_time: real: " << History::get_instance().get_current_time() << ", expected " << _history_length << endl;
// checks if the History contains the right stuff
int min = History::get_instance().get_current_time();
min = min < _history_length ? min : _history_length;
for (int i = 0; i < min + 1; i++)
{ {
// checks if the Singleton Pattern has been actually implemented // watch out here, it's if (NOT ...) operator != was not available.
if (&History::get_instance() != &History::get_instance()) std::cout << "\nget_instance"; if
(
// checks if the History is long how it should be !(
if (History::get_instance().get_current_time() != _history_length) std::cout << "\nget_current_time: real: " << History::get_instance().get_current_time() <<", expected " << _history_length<<endl; History::get_instance().get_simulation_status_at(i)->has_same_objects( *_get_simulation_status_at[i])
)
// checks if the History contains the right stuff )
int min = History::get_instance().get_current_time(); {
min = min < _history_length ? min : _history_length; std::cout << "\nget_simulation_status_at";
for (int i = 0; i < min+1; i++) }
{ if (History::get_instance().get_scheduled_at(i) != memory::smart_ptr<DynamicSchedulable>(NULL) && !(*(History::get_instance().get_scheduled_at(i)) == *(_get_scheduled_at[i])))
// watch out here, it's if (NOT ...) operator != was not available. {
if std::cout << "\nget_scheduled_at";
( }
!(
History::get_instance().get_simulation_status_at(i)->has_same_objects( *_get_simulation_status_at[i])
)
)
{
std::cout << "\nget_simulation_status_at";
}
if (History::get_instance().get_scheduled_at(i) != memory::smart_ptr<DynamicSchedulable>(NULL) && !(*(History::get_instance().get_scheduled_at(i)) == *(_get_scheduled_at[i])))
{
std::cout << "\nget_scheduled_at";
}
}
return;
} }
return;
}
// saves the given SchedulableQueue into the history, and saves a copy of it into an array // saves the given SchedulableQueue into the history, and saves a copy of it into an array
void _insert(sgpem::SchedulableQueue& status) void _insert(sgpem::SchedulableQueue& status)
{
History::get_instance().enqueue_slice(status);
_history_length = _history_length + 1;
_get_simulation_status_at[_history_length] = new SchedulableQueue(status);
if (History::get_instance().get_scheduled_at(_history_length) != memory::smart_ptr<DynamicSchedulable>(NULL))
_get_scheduled_at[_history_length] = new DynamicSchedulable(*(History::get_instance().get_scheduled_at(_history_length)));
else
_get_scheduled_at[_history_length] = NULL;
return;
}
// modifies the given SchedulableQueue object in an arbitrary way.
void _randomize(sgpem::SchedulableQueue& status)
{
status.swap(9, 10);
status.swap(1, 16);
status.swap(3, 19);
status.swap(2, 18);
status.swap(5, 16);
status.swap(4, 11);
status.swap(6, 12);
status.swap(7, 14);
status.swap(15, 13);
status.swap(0, 10);
status.swap(9, 4);
status.swap(4, 5);
status.swap(7, 1);
for (unsigned int i = 0; i < status.size(); i++)
{ {
History::get_instance().enqueue_slice(status); status.get_item_at(i)->give_cpu_time(i % 2);
status.get_item_at(i)->set_last_scheduled(_history_length % 30);
_history_length = _history_length + 1; status.get_item_at(i)->set_state(i % 2 ? DynamicSchedulable::state_running : DynamicSchedulable::state_ready);
_get_simulation_status_at[_history_length] = new SchedulableQueue(status);
if (History::get_instance().get_scheduled_at(_history_length) != memory::smart_ptr<DynamicSchedulable>(NULL))
_get_scheduled_at[_history_length] = new DynamicSchedulable(*(History::get_instance().get_scheduled_at(_history_length)));
else
_get_scheduled_at[_history_length] = NULL;
return;
} }
return;
}
// modifies the given SchedulableQueue object in an arbitrary way. // truncates the history by one instant
void _randomize(sgpem::SchedulableQueue& status) void _truncate()
{
if (_history_length > -1)
{ {
status.swap(9, 10); if (_get_simulation_status_at[_history_length] != NULL)
status.swap(1, 16); {
status.swap(3, 19); delete _get_simulation_status_at[_history_length];
status.swap(2, 18); _get_simulation_status_at[_history_length] = NULL;
status.swap(5, 16); }
status.swap(4, 11);
status.swap(6, 12); if (_get_scheduled_at[_history_length] != NULL)
status.swap(7, 14); {
status.swap(15, 13); delete _get_scheduled_at[_history_length];
status.swap(0, 10); _get_scheduled_at[_history_length] = NULL;
status.swap(9, 4); }
status.swap(4, 5);
status.swap(7, 1); _history_length = _history_length - 1;
for (unsigned int i = 0; i < status.size(); i++) History::get_instance().truncate_at(_history_length - 1);
{
status.get_item_at(i)->give_cpu_time(i%2);
status.get_item_at(i)->set_last_scheduled(_history_length%30);
status.get_item_at(i)->set_state(i%2 ? DynamicSchedulable::state_running : DynamicSchedulable::state_ready);
}
return;
}
// truncates the history by one instant
void _truncate()
{
if (_history_length > -1)
{
if (_get_simulation_status_at[_history_length] != NULL)
{
delete _get_simulation_status_at[_history_length];
_get_simulation_status_at[_history_length] = NULL;
}
if (_get_scheduled_at[_history_length] != NULL)
{
delete _get_scheduled_at[_history_length];
_get_scheduled_at[_history_length] = NULL;
}
_history_length = _history_length - 1;
History::get_instance().truncate_at(_history_length-1);
}
return;
} }
return;
}
}; };
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
using namespace sgpem; using namespace sgpem;
using Glib::Module; using Glib::Module;
std::string command("ERERERT"); // the sequence of commands to test std::string command("ERERERT"); // the sequence of commands to test
if(argc > 1) if(argc > 1)
command = argv[1]; command = argv[1];
// sets up the test data // sets up the test data
StaticProcess p1("P1", 1,5,1); StaticProcess p1("P1", 1, 5, 1);
StaticProcess p2("P2", 5,55,2); StaticProcess p2("P2", 5, 55, 2);
StaticProcess p3("P3", 36,30,3); StaticProcess p3("P3", 36, 30, 3);
StaticProcess p4("P4", 4,26,3); StaticProcess p4("P4", 4, 26, 3);
StaticProcess p5("P5", 15,200,3); StaticProcess p5("P5", 15, 200, 3);
StaticProcess p6("P6", 6,250,1); StaticProcess p6("P6", 6, 250, 1);
StaticProcess p7("P7", 8,42,15); StaticProcess p7("P7", 8, 42, 15);
StaticProcess p8("P8", 8,56,1); StaticProcess p8("P8", 8, 56, 1);
StaticProcess p9("P9", 9,42,1); StaticProcess p9("P9", 9, 42, 1);
StaticProcess p10("PA", 12,42,1); StaticProcess p10("PA", 12, 42, 1);
StaticProcess p11("PB", 106,42,1); StaticProcess p11("PB", 106, 42, 1);
StaticProcess p12("PC", 100,42,1); StaticProcess p12("PC", 100, 42, 1);
StaticProcess p13("PD", 29,42,18); StaticProcess p13("PD", 29, 42, 18);
StaticProcess p14("PE", 0,42,1); StaticProcess p14("PE", 0, 42, 1);
StaticProcess p15("PF", 2,88,1); StaticProcess p15("PF", 2, 88, 1);
StaticProcess p16("PG", 3666,9,1); StaticProcess p16("PG", 3666, 9, 1);
StaticProcess p17("PH", 5,72,10); StaticProcess p17("PH", 5, 72, 10);
StaticProcess p18("PJ", 6,26,1); StaticProcess p18("PJ", 6, 26, 1);
StaticProcess p19("PK", 10,24,17); StaticProcess p19("PK", 10, 24, 17);
StaticProcess p20("PK2", 11,34,67); // not used! StaticProcess p20("PK2", 11, 34, 67); // not used!
DynamicSchedulable ss1(p1); DynamicSchedulable ss1(p1);
DynamicSchedulable ss2(p2); DynamicSchedulable ss2(p2);
DynamicSchedulable ss3(p3); DynamicSchedulable ss3(p3);
DynamicSchedulable ss4(p4); DynamicSchedulable ss4(p4);
DynamicSchedulable ss5(p5); DynamicSchedulable ss5(p5);
DynamicSchedulable ss6(p6); DynamicSchedulable ss6(p6);
DynamicSchedulable ss7(p7); DynamicSchedulable ss7(p7);
DynamicSchedulable ss8(p8); DynamicSchedulable ss8(p8);
DynamicSchedulable ss9(p9); DynamicSchedulable ss9(p9);
DynamicSchedulable ss10(p10); DynamicSchedulable ss10(p10);
DynamicSchedulable ss11(p11); DynamicSchedulable ss11(p11);
DynamicSchedulable ss12(p12); DynamicSchedulable ss12(p12);
DynamicSchedulable ss13(p13); DynamicSchedulable ss13(p13);
DynamicSchedulable ss14(p14); DynamicSchedulable ss14(p14);
DynamicSchedulable ss15(p15); DynamicSchedulable ss15(p15);
DynamicSchedulable ss16(p16); DynamicSchedulable ss16(p16);
DynamicSchedulable ss17(p17); DynamicSchedulable ss17(p17);
DynamicSchedulable ss18(p18); DynamicSchedulable ss18(p18);
DynamicSchedulable ss19(p19); // not used! DynamicSchedulable ss19(p19); // not used!
SchedulableQueue initial; SchedulableQueue initial;
initial.add_at_bottom(ss1); initial.add_at_bottom(ss1);
initial.add_at_bottom(ss2); initial.add_at_bottom(ss2);
initial.add_at_bottom(ss3); initial.add_at_bottom(ss3);
initial.add_at_bottom(ss4); initial.add_at_bottom(ss4);
initial.add_at_bottom(ss5); initial.add_at_bottom(ss5);
initial.add_at_bottom(ss6); initial.add_at_bottom(ss6);
initial.add_at_bottom(ss7); initial.add_at_bottom(ss7);
initial.add_at_bottom(ss8); initial.add_at_bottom(ss8);
initial.add_at_bottom(ss9); initial.add_at_bottom(ss9);
initial.add_at_bottom(ss10); initial.add_at_bottom(ss10);
initial.add_at_bottom(ss11); initial.add_at_bottom(ss11);
initial.add_at_bottom(ss12); initial.add_at_bottom(ss12);
initial.add_at_bottom(ss13); initial.add_at_bottom(ss13);
initial.add_at_bottom(ss14); initial.add_at_bottom(ss14);
initial.add_at_bottom(ss15); initial.add_at_bottom(ss15);
initial.add_at_bottom(ss16); initial.add_at_bottom(ss16);
initial.add_at_bottom(ss17); initial.add_at_bottom(ss17);
initial.add_at_bottom(ss18); initial.add_at_bottom(ss18);
HistoryTester HT(initial); HistoryTester HT(initial);
//HT.test("EEEEREREEEERERRREEEEEEEETERRERERTTT"); //HT.test("EEEEREREEEERERRREEEEEEEETERRERERTTT");
HT.test("E"); HT.test("E");
HT.test("EE"); HT.test("EE");
HT.test("EERE"); HT.test("EERE");
HT.test("EEEREE"); HT.test("EEEREE");
HT.test("EEEREE"); HT.test("EEEREE");
HT.test("EEER"); HT.test("EEER");
HT.test("EEEERER"); HT.test("EEEERER");
HT.test("EEER"); HT.test("EEER");
HT.test("EREE"); HT.test("EREE");
HT.test("EEEERERT"); HT.test("EEEERERT");
HT.test("EEEERERTEEEERERT"); HT.test("EEEERERTEEEERERT");
HT.test("EEEERERTEEETRERERT"); HT.test("EEEERERTEEETRERERT");
HT.test("EEEERERTEEEERRRERT"); HT.test("EEEERERTEEEERRRERT");
HT.test("EEEEEEERERTERERT"); HT.test("EEEEEEERERTERERT");
HT.test("EEEEREREEEERERRREEEEEEEETERRERERTTT"); HT.test("EEEEREREEEERERRREEEEEEEETERRERERTTT");
//HT.test(command); //HT.test(command);
cout << std::endl << "\nend of test!\n"; cout << std::endl << "\nend of test!\n";
exit(0); exit(0);
} }

View File

@ -46,72 +46,73 @@
namespace sgpem namespace sgpem
{ {
/* History stub: every public method does nothing except printing /* History stub: every public method does nothing except printing
in std::cout the signature and the parameters. */ in std::cout the signature and the parameters. */
class TestHistory : public History class TestHistory : public History
{ {
public: public:
memory::smart_ptr<sgpem::DynamicSchedulable> get_scheduled_at(int time) memory::smart_ptr<sgpem::DynamicSchedulable> get_scheduled_at(int time)
{ {
std::cout << "get_scheduled_at" << time; std::cout << "get_scheduled_at" << time;
return History::get_scheduled_at(time); return History::get_scheduled_at(time);
} }
memory::smart_ptr<sgpem::SchedulableQueue> get_simulation_status_at(int time) const memory::smart_ptr<sgpem::SchedulableQueue> get_simulation_status_at(int time) const
{ {
std::cout << "get_simulation_status_at" << time; std::cout << "get_simulation_status_at" << time;
return History::get_simulation_status_at(time); return History::get_simulation_status_at(time);
} }
int get_current_time() const int get_current_time() const
{ {
std::cout << "getCurrentTime"; std::cout << "getCurrentTime";
return History::get_current_time(); return History::get_current_time();
} }
void enqueue_slice(const sgpem::SchedulableQueue& status) void enqueue_slice(const sgpem::SchedulableQueue& status)
{ {
std::cout << "enqueue_slice"; std::cout << "enqueue_slice";
History::enqueue_slice(status); History::enqueue_slice(status);
} }
void truncate_at(int instant) void truncate_at(int instant)
{ {
std::cout << "TruncateAt" << instant; std::cout << "TruncateAt" << instant;
History::truncate_at(instant); History::truncate_at(instant);
} }
// The following method is not used by the user interface // The following method is not used by the user interface
static History& get_instance(); static History& get_instance();
private: private:
static TestHistory* _instance; static TestHistory* _instance;
}; };
TestHistory* TestHistory::_instance = 0; TestHistory* TestHistory::_instance = 0;
History& History&
TestHistory::get_instance() TestHistory::get_instance()
{ {
if(!_instance) if(!_instance)
_instance = new TestHistory(); _instance = new TestHistory();
return *_instance; return *_instance;
} }
}//~ namespace sgpem }//~ namespace sgpem
int int
main(int, char**) { main(int, char**)
using namespace sgpem; {
using namespace sgpem;
Scheduler::get_instance(); // Forces initialization of scheduler. Scheduler::get_instance(); // Forces initialization of scheduler.
// Cross fingers (depends if PythonPolicyManager // Cross fingers (depends if PythonPolicyManager
// static object has been initialized before?). // static object has been initialized before?).
//initialize history //initialize history
TestHistory::get_instance(); TestHistory::get_instance();
//textual IO //textual IO
memory::smart_ptr<IOManager> io(new StandardIO()); memory::smart_ptr<IOManager> io(new StandardIO());
text_sim.add_io_device(io); text_sim.add_io_device(io);
text_sim.update(); text_sim.update();
text_sim.run(); text_sim.run();
exit(0); exit(0);
} }

View File

@ -46,165 +46,162 @@
namespace sgpem namespace sgpem
{ {
/** An hard-coded Priority Round Robin policy /** An hard-coded Priority Round Robin policy
* It's actually called PRRPolicy, altough my personal taste would have suggested * It's actually called PRRPolicy, altough my personal taste would have suggested
* naming it * naming it
* Prioriy-Reliant Roughly-Realized Recently-Reimplemented Round-Robin Policy, * Prioriy-Reliant Roughly-Realized Recently-Reimplemented Round-Robin Policy,
* i.e. PRRRRRRR-Policy. * i.e. PRRRRRRR-Policy.
* it adds a new constructor taking the quantum size (time slice)*/ * it adds a new constructor taking the quantum size (time slice)*/
class PRRPolicy : public Policy class PRRPolicy : public Policy
{
public:
Policy()
{ {
public: _instance = this;
}
Policy() Policy(int quantum) : _quantum(quantum)
{
_instance = this;
}
Policy(int quantum) : _quantum(quantum)
{
_instance = this;
}
static Policy& get_instance()
{
if(!_instance) _instance = new Policy(3); // quantum size
return *_instance;
}
virtual ~Policy()
{
}
virtual void configure()
{
}
virtual void sort_queue() const throw(UserInterruptException)
{ // here a lot of fun, exactly O(n^2) fun!
SchedulableQueue sl = History.get_instance().get_simulation_status_at(get_current_time());
for (int i = 0; i < sl.size(); i++)
{
for (int j = 0; j < sl.size()-1; j++)
{
if (sl.get_item_at(j).get_schedulable().get_priority() < sl.get_item_at(j+1).get_schedulable().get_priority())
{
sl.swap(j, j+1);
}
}
}
}
int get_id() const
{
return 42;
}
virtual Glib::ustring get_description()
{
return "42";
}
virtual bool is_pre_emptive() const throw(UserInterruptException)
{
return 1;
}
virtual int get_time_slice() const throw(UserInterruptException)
{
return _quantum;
}
PolicyParameters& get_parameters()
{
return _parameters;
}
protected:
PolicyParameters _parameters;
int _id;
int _quantum;
private:
static Policy* _instance;
};
Policy*
PRRPolicy::_instance = NULL;
// A PolicyManager stub
class PolicyManager
{ {
public: _instance = this;
}
PolicyManager(); static Policy& get_instance()
virtual ~PolicyManager();
virtual Policy& get_policy()
{
return PRRPolicy.get_instance();
}
virtual void init()
{
}
static PolicyManager& get_registered_manager();
private:
static PolicyManager* _registered;
};
PolicyManager*
PolicyManager::_registered = NULL;
PolicyManager::PolicyManager()
{ {
_registered = this; if(!_instance) _instance = new Policy(3); // quantum size
return *_instance;
}
virtual ~Policy()
{}
virtual void configure()
{}
virtual void sort_queue() const throw(UserInterruptException)
{ // here a lot of fun, exactly O(n^2) fun!
SchedulableQueue sl = History.get_instance().get_simulation_status_at(get_current_time());
for (int i = 0; i < sl.size(); i++)
{
for (int j = 0; j < sl.size() - 1; j++)
{
if (sl.get_item_at(j).get_schedulable().get_priority() < sl.get_item_at(j + 1).get_schedulable().get_priority())
{
sl.swap(j, j + 1);
}
}
}
}
int get_id() const
{
return 42;
}
virtual Glib::ustring get_description()
{
return "42";
}
virtual bool is_pre_emptive() const throw(UserInterruptException)
{
return 1;
}
virtual int get_time_slice() const throw(UserInterruptException)
{
return _quantum;
}
PolicyParameters& get_parameters()
{
return _parameters;
} }
PolicyManager::~PolicyManager() protected:
{
if(_registered == this) _registered = NULL;
}
PolicyManager& PolicyParameters _parameters;
PolicyManager::get_registered_manager() int _id;
{ int _quantum;
return *_registered;
}
private:
static Policy* _instance;
// a History stub, should only save the last state included. but...
class History : public ObservedSubject
{
public:
memory::smart_ptr<sgpem::DynamicSchedulable> get_scheduled_at(int time) const {}
memory::smart_ptr<sgpem::SchedulableQueue> get_simulation_status_at(int time) const;
int get_current_time() const {return _total_time_elapsed;}
void enqueue_slice(const sgpem::SchedulableQueue& status);
void truncate_at(int instant) {}
static History& get_instance();
private:
History(int); //private constructor. The parameter is discarded
static History _instance;
int _total_time_elapsed;
std::vector<sgpem::Slice> _slices;
}; };
History&
History::get_instance()
{ Policy*
if(!_instance) _instance = new Policy(3); // quantum size PRRPolicy::_instance = NULL;
return *_instance;
}
// A PolicyManager stub
class PolicyManager
{
public:
PolicyManager();
virtual ~PolicyManager();
virtual Policy& get_policy()
{
return PRRPolicy.get_instance();
}
virtual void init()
{}
static PolicyManager& get_registered_manager();
private:
static PolicyManager* _registered;
};
PolicyManager*
PolicyManager::_registered = NULL;
PolicyManager::PolicyManager()
{
_registered = this;
}
PolicyManager::~PolicyManager()
{
if(_registered == this) _registered = NULL;
}
PolicyManager&
PolicyManager::get_registered_manager()
{
return *_registered;
}
// a History stub, should only save the last state included. but...
class History : public ObservedSubject
{
public:
memory::smart_ptr<sgpem::DynamicSchedulable> get_scheduled_at(int time) const {}
memory::smart_ptr<sgpem::SchedulableQueue> get_simulation_status_at(int time) const;
int get_current_time() const {return _total_time_elapsed;}
void enqueue_slice(const sgpem::SchedulableQueue& status);
void truncate_at(int instant) {}
static History& get_instance();
private:
History(int); //private constructor. The parameter is discarded
static History _instance;
int _total_time_elapsed;
std::vector<sgpem::Slice> _slices;
};
History&
History::get_instance()
{
if(!_instance) _instance = new Policy(3); // quantum size
return *_instance;
}
@ -217,85 +214,85 @@ namespace sgpem
class StepForwardTester class StepForwardTester
{ {
} }
// from here and further until the bottom, all to throw away I suppose // from here and further until the bottom, all to throw away I suppose
int int
main(int argc, char** argv) { main(int argc, char** argv)
{
using namespace sgpem; using namespace sgpem;
using Glib::Module; using Glib::Module;
std::string command(ERERERT); // the sequence of commands to test std::string command(ERERERT); // the sequence of commands to test
// sets up the test data // sets up the test data
StaticProcess p1("P1", 1,5,1); StaticProcess p1("P1", 1, 5, 1);
StaticProcess p2("P2", 5,55,2); StaticProcess p2("P2", 5, 55, 2);
StaticProcess p3("P3", 36,30,3); StaticProcess p3("P3", 36, 30, 3);
StaticProcess p4("P4", 4,26,3); StaticProcess p4("P4", 4, 26, 3);
StaticProcess p5("P5", 15,200,3); StaticProcess p5("P5", 15, 200, 3);
StaticProcess p6("P6", 6,250,1); StaticProcess p6("P6", 6, 250, 1);
StaticProcess p7("P7", 8,42,15); StaticProcess p7("P7", 8, 42, 15);
StaticProcess p8("P8", 8,56,1); StaticProcess p8("P8", 8, 56, 1);
StaticProcess p9("P9", 9,42,1); StaticProcess p9("P9", 9, 42, 1);
StaticProcess p10("PA", 12,42,1); StaticProcess p10("PA", 12, 42, 1);
StaticProcess p11("PB", 106,42,1); StaticProcess p11("PB", 106, 42, 1);
StaticProcess p12("PC", 100,42,1); StaticProcess p12("PC", 100, 42, 1);
StaticProcess p13("PD", 29,42,18); StaticProcess p13("PD", 29, 42, 18);
StaticProcess p14("PE", 0,42,1); StaticProcess p14("PE", 0, 42, 1);
StaticProcess p15("PF", 2,88,1); StaticProcess p15("PF", 2, 88, 1);
StaticProcess p16("PG", 3666,9,1); StaticProcess p16("PG", 3666, 9, 1);
StaticProcess p17("PH", 5,72,10); StaticProcess p17("PH", 5, 72, 10);
StaticProcess p18("PJ", 6,26,1); StaticProcess p18("PJ", 6, 26, 1);
StaticProcess p19("PK", 10,24,17); StaticProcess p19("PK", 10, 24, 17);
StaticProcess p20("PK2", 11,34,67); // not used! StaticProcess p20("PK2", 11, 34, 67); // not used!
DynamicSchedulable ss1(p1); DynamicSchedulable ss1(p1);
DynamicSchedulable ss2(p2); DynamicSchedulable ss2(p2);
DynamicSchedulable ss3(p3); DynamicSchedulable ss3(p3);
DynamicSchedulable ss4(p4); DynamicSchedulable ss4(p4);
DynamicSchedulable ss5(p5); DynamicSchedulable ss5(p5);
DynamicSchedulable ss6(p6); DynamicSchedulable ss6(p6);
DynamicSchedulable ss7(p7); DynamicSchedulable ss7(p7);
DynamicSchedulable ss8(p8); DynamicSchedulable ss8(p8);
DynamicSchedulable ss9(p9); DynamicSchedulable ss9(p9);
DynamicSchedulable ss10(p10); DynamicSchedulable ss10(p10);
DynamicSchedulable ss11(p11); DynamicSchedulable ss11(p11);
DynamicSchedulable ss12(p12); DynamicSchedulable ss12(p12);
DynamicSchedulable ss13(p13); DynamicSchedulable ss13(p13);
DynamicSchedulable ss14(p14); DynamicSchedulable ss14(p14);
DynamicSchedulable ss15(p15); DynamicSchedulable ss15(p15);
DynamicSchedulable ss16(p16); DynamicSchedulable ss16(p16);
DynamicSchedulable ss17(p17); DynamicSchedulable ss17(p17);
DynamicSchedulable ss18(p18); DynamicSchedulable ss18(p18);
DynamicSchedulable ss19(p19); // not used! DynamicSchedulable ss19(p19); // not used!
SchedulableQueue initial; SchedulableQueue initial;
initial.add_at_bottom(ss1); initial.add_at_bottom(ss1);
initial.add_at_bottom(ss2); initial.add_at_bottom(ss2);
initial.add_at_bottom(ss3); initial.add_at_bottom(ss3);
initial.add_at_bottom(ss4); initial.add_at_bottom(ss4);
initial.add_at_bottom(ss5); initial.add_at_bottom(ss5);
initial.add_at_bottom(ss6); initial.add_at_bottom(ss6);
initial.add_at_bottom(ss7); initial.add_at_bottom(ss7);
initial.add_at_bottom(ss8); initial.add_at_bottom(ss8);
initial.add_at_bottom(ss9); initial.add_at_bottom(ss9);
initial.add_at_bottom(ss10); initial.add_at_bottom(ss10);
initial.add_at_bottom(ss11); initial.add_at_bottom(ss11);
initial.add_at_bottom(ss12); initial.add_at_bottom(ss12);
initial.add_at_bottom(ss13); initial.add_at_bottom(ss13);
initial.add_at_bottom(ss14); initial.add_at_bottom(ss14);
initial.add_at_bottom(ss15); initial.add_at_bottom(ss15);
initial.add_at_bottom(ss16); initial.add_at_bottom(ss16);
initial.add_at_bottom(ss17); initial.add_at_bottom(ss17);
initial.add_at_bottom(ss18); initial.add_at_bottom(ss18);
HistoryTester HT(initial); HistoryTester HT(initial);
HT.test("ERERERERTTTETRERERETETTTTTTTTTTTTTT"); HT.test("ERERERERTTTETRERERETETTTTTTTTTTTTTT");
exit(0); exit(0);
} }

View File

@ -34,8 +34,7 @@ using Glib::ustring;
#include "smartp.tcc" #include "smartp.tcc"
TextSimulation::~TextSimulation() TextSimulation::~TextSimulation()
{ {}
}
/** /**
Adds an IO_device and creates a thread which loops the read-parse-execute process Adds an IO_device and creates a thread which loops the read-parse-execute process
@ -43,491 +42,491 @@ Adds an IO_device and creates a thread which loops the read-parse-execute proces
void void
TextSimulation::add_io_device(smart_ptr<IOManager> io) TextSimulation::add_io_device(smart_ptr<IOManager> io)
{ {
_devices.push_back(io); _devices.push_back(io);
pair<TextSimulation*, int> p(this, 0); pair<TextSimulation*, int> p(this, 0);
if (!io->is_full_duplex()) if (!io->is_full_duplex())
Thread::create( sigc::bind(&TextSimulation::_io_loop, p), true); Thread::create( sigc::bind(&TextSimulation::_io_loop, p), true);
} }
void void
TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const ustring > p) TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const ustring > p)
{ {
TextSimulation* obj = p.first.first; TextSimulation* obj = p.first.first;
ustring str = p.second; ustring str = p.second;
//looks for the IOManager who sent the command //looks for the IOManager who sent the command
uint quale = 0; uint quale = 0;
for (; quale < obj->_devices.size(); quale++) for (; quale < obj->_devices.size(); quale++)
if (p.first.second == &(*obj->_devices[quale])) if (p.first.second == &(*obj->_devices[quale]))
break; break;
if (str.length() == 0) if (str.length() == 0)
return; return;
//CAPITALIZE alla grguments //CAPITALIZE alla grguments
str = str.uppercase(); str = str.uppercase();
vector<ustring> arguments; vector<ustring> arguments;
uint f=0; uint f = 0;
static const ustring whitespaces = " \r\b\n\t\a"; static const ustring whitespaces = " \r\b\n\t\a";
//fills the vector with parameters //fills the vector with parameters
while (true) while (true)
{ {
f = str.find_first_of(whitespaces); f = str.find_first_of(whitespaces);
if (f > str.length()) if (f > str.length())
{ {
//the end of the string //the end of the string
arguments.push_back(str); arguments.push_back(str);
break; break;
} }
else else
{ {
//add the token //add the token
arguments.push_back(str.substr(0, f)); arguments.push_back(str.substr(0, f));
//trim the initial whitespaces //trim the initial whitespaces
str = str.substr(f+1); str = str.substr(f + 1);
f = str.find_first_not_of(whitespaces); f = str.find_first_not_of(whitespaces);
str = str.substr(f); str = str.substr(f);
} }
} }
if (arguments.size() == 0) if (arguments.size() == 0)
return; return;
bool show_help = false; bool show_help = false;
int param = 0; int param = 0;
check: check:
if (arguments[param] == "RUN") if (arguments[param] == "RUN")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- RUN COMMAND --\nStarts the simulation. It can be continuous or step-by-step" "\n-- RUN COMMAND --\nStarts the simulation. It can be continuous or step-by-step"
" depending on the mode configured with SetMode (default=continuous).\n\n" " depending on the mode configured with SetMode (default=continuous).\n\n"
"The output of RUN is one or more rows each of which represents the state of the " "The output of RUN is one or more rows each of which represents the state of the "
"schedulable entities. It can be RUNNING, READY, BLOCKED, FUTURE or TERMINATED." "schedulable entities. It can be RUNNING, READY, BLOCKED, FUTURE or TERMINATED."
"\nThe row begins with the number of the instant described by the following lists of states. " "\nThe row begins with the number of the instant described by the following lists of states. "
"The instant 0 represents the INITIAL STATE during which no process is running. The scheduler " "The instant 0 represents the INITIAL STATE during which no process is running. The scheduler "
"activity begins at instant 1. Each schedulable entity is represented by its name followed " "activity begins at instant 1. Each schedulable entity is represented by its name followed "
"by its priority enclosed between round parenthesis.")); "by its priority enclosed between round parenthesis."));
return; return;
} }
try try
{ {
obj->run(); obj->run();
} }
catch(UserInterruptException e) catch(UserInterruptException e)
{ {
obj->_devices[quale]->write_buffer(_("\nERROR: ")); obj->_devices[quale]->write_buffer(_("\nERROR: "));
obj->_devices[quale]->write_buffer(_(e.what())); obj->_devices[quale]->write_buffer(_(e.what()));
obj->_devices[quale]->write_buffer(_("\nSimulation is now stopped")); obj->_devices[quale]->write_buffer(_("\nSimulation is now stopped"));
} }
} }
else if (arguments[param] == "PAUSE") else if (arguments[param] == "PAUSE")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will restart it.")); "\n-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will restart it."));
return; return;
} }
obj->pause(); obj->pause();
} }
else if (arguments[param] == "STOP") else if (arguments[param] == "STOP")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- STOP COMMAND --\nStops the simulation. The next call to RUN will " "\n-- STOP COMMAND --\nStops the simulation. The next call to RUN will "
"bring the simulation to the FIRST instant and start it.")); "bring the simulation to the FIRST instant and start it."));
return; return;
} }
obj->stop(); obj->stop();
} }
else if (arguments[param] == "RESET") else if (arguments[param] == "RESET")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- RESET COMMAND --\nResets the simulation jumping back to the first instant.")); "\n-- RESET COMMAND --\nResets the simulation jumping back to the first instant."));
return; return;
} }
obj->reset(); obj->reset();
} }
else if (arguments[param] == "QUIT") else if (arguments[param] == "QUIT")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- QUIT COMMAND --\nExits the program.")); "\n-- QUIT COMMAND --\nExits the program."));
return; return;
} }
obj->_devices[quale]->write_buffer(_("\n\n*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n\n")); obj->_devices[quale]->write_buffer(_("\n\n*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n\n"));
exit(1); exit(1);
} }
else if (arguments[param] == "HELP") else if (arguments[param] == "HELP")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- Do you really want me to explain what HELP means? --" "\n-- Do you really want me to explain what HELP means? --"
"\n ************** YOU ARE JOKING ME !!! ************\n\n")); "\n ************** YOU ARE JOKING ME !!! ************\n\n"));
exit(1); exit(1);
} }
if (arguments.size() == 1) if (arguments.size() == 1)
{ {
obj->_devices[quale]->write_buffer( "\nAvaiable commands:\nRUN\nPAUSE\nSTOP\nRESET\nQUIT\nHELP" obj->_devices[quale]->write_buffer( "\nAvaiable commands:\nRUN\nPAUSE\nSTOP\nRESET\nQUIT\nHELP"
"\nGETMODE\nSETMODE\nSETTIMER\nGETTIMER\nJUMPTO\nGETPOLICY" "\nGETMODE\nSETMODE\nSETTIMER\nGETTIMER\nJUMPTO\nGETPOLICY"
"\nSETPOLICY\nGETPOLICYATTRIBUTES" "\nSETPOLICY\nGETPOLICYATTRIBUTES"
"\n\nHELP followed by a command shows help about it." "\n\nHELP followed by a command shows help about it."
"\n ex. HELP RUN shows help about the command RUN"); "\n ex. HELP RUN shows help about the command RUN");
return; return;
} }
show_help = true; show_help = true;
param = 1; param = 1;
goto check; goto check;
} }
else if (arguments[param] == "SETMODE") else if (arguments[param] == "SETMODE")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- SetMode COMMAND --\nPermits to change the mode of the simulation.\n\nSintax: Setmode <param>\n\t<param> can take values:\n" "\n-- SetMode COMMAND --\nPermits to change the mode of the simulation.\n\nSintax: Setmode <param>\n\t<param> can take values:\n"
"\n\t\tCONTINUOUS - when calling RUN the simulation will show an animation using the wait-interval set by SETTIMER\n" "\n\t\tCONTINUOUS - when calling RUN the simulation will show an animation using the wait-interval set by SETTIMER\n"
"\n\t\tSTEP - when calling RUN the simulation will show only one step of the animation\n")); "\n\t\tSTEP - when calling RUN the simulation will show only one step of the animation\n"));
return; return;
} }
if (arguments.size() != 2) if (arguments.size() != 2)
{ {
obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters." obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters."
"\nType HELP SETMODE for the description of the sintax")); "\nType HELP SETMODE for the description of the sintax"));
return; return;
} }
if (arguments[1] == "CONTINUOUS") if (arguments[1] == "CONTINUOUS")
obj->set_mode(true); obj->set_mode(true);
else if (arguments[1] == "STEP") else if (arguments[1] == "STEP")
obj->set_mode(false); obj->set_mode(false);
else else
obj->_devices[quale]->write_buffer(_("\nERROR: the second parameter can be only CONTINUOUS or STEP")); obj->_devices[quale]->write_buffer(_("\nERROR: the second parameter can be only CONTINUOUS or STEP"));
} }
else if (arguments[param] == "GETMODE") else if (arguments[param] == "GETMODE")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- GetMode COMMAND --\nReturns\n\tCONTINUOUS : if the simulation is shown with an animation" "\n-- GetMode COMMAND --\nReturns\n\tCONTINUOUS : if the simulation is shown with an animation"
"\n\tSTEP : if if the simulation is shown step-by-step")); "\n\tSTEP : if if the simulation is shown step-by-step"));
return; return;
} }
if (obj->get_mode()) if (obj->get_mode())
obj->_devices[quale]->write_buffer(_("\nCONTINUOUS")); obj->_devices[quale]->write_buffer(_("\nCONTINUOUS"));
else else
obj->_devices[quale]->write_buffer(_("\nSTEP")); obj->_devices[quale]->write_buffer(_("\nSTEP"));
} }
else if (arguments[param] == "SETTIMER") else if (arguments[param] == "SETTIMER")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- SetTimer COMMAND --\nPermits to change the interval between a step and the following one during a continuous animation." "\n-- SetTimer COMMAND --\nPermits to change the interval between a step and the following one during a continuous animation."
"\n\nSintax: SetTimer <param>\n\t<param> must be an integer value > 0 and < 10000.\n")); "\n\nSintax: SetTimer <param>\n\t<param> must be an integer value > 0 and < 10000.\n"));
return; return;
} }
if (arguments.size() != 2) if (arguments.size() != 2)
{ {
obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters." obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters."
"\nType HELP SETTIMER for the description of the sintax")); "\nType HELP SETTIMER for the description of the sintax"));
return; return;
} }
int num; int num;
if (string_to_int(arguments[1], num) && num > 0 && num < 10000) if (string_to_int(arguments[1], num) && num > 0 && num < 10000)
obj->set_timer(num); obj->set_timer(num);
else else
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\nERROR: the second parameter has a wrong value." "\nERROR: the second parameter has a wrong value."
"\nType HELP SETTIMER for the description of the sintax")); "\nType HELP SETTIMER for the description of the sintax"));
} }
else if (arguments[param] == "GETTIMER") else if (arguments[param] == "GETTIMER")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- GetTimer COMMAND --\nReturns the number of milliseconds the simulation " "\n-- GetTimer COMMAND --\nReturns the number of milliseconds the simulation "
"in the continuous mode waits between a step and the following one")); "in the continuous mode waits between a step and the following one"));
return; return;
} }
ustring ss; ustring ss;
int_to_string(obj->get_timer(), ss); int_to_string(obj->get_timer(), ss);
obj->_devices[quale]->write_buffer(ss); obj->_devices[quale]->write_buffer(ss);
} }
else if (arguments[param] == "JUMPTO") else if (arguments[param] == "JUMPTO")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- JumpTo COMMAND --\nPermits to jump to a desired instant of the simulation." "\n-- JumpTo COMMAND --\nPermits to jump to a desired instant of the simulation."
" All states of the simulation before <param> will be recalculated and printed out." " All states of the simulation before <param> will be recalculated and printed out."
"\n\nSintax: JumpTo <param>\n\t<param> must be an integer value >= 0")); "\n\nSintax: JumpTo <param>\n\t<param> must be an integer value >= 0"));
return; return;
} }
if (arguments.size() != 2) if (arguments.size() != 2)
{ {
obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters." obj->_devices[quale]->write_buffer(_("\nERROR: wrong number of parameters."
"\nType HELP JUMPTO for the description of the sintax")); "\nType HELP JUMPTO for the description of the sintax"));
return; return;
} }
int num; int num;
if (string_to_int(arguments[1], num) && num >= 0) if (string_to_int(arguments[1], num) && num >= 0)
obj->jump_to(num); obj->jump_to(num);
else else
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\nERROR: the second parameter has a wrong value." "\nERROR: the second parameter has a wrong value."
"\nType HELP JUMPTO for the description of the sintax")); "\nType HELP JUMPTO for the description of the sintax"));
} }
else if (arguments[param] == "GETPOLICY") else if (arguments[param] == "GETPOLICY")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- GetPolicy COMMAND --\nReturns the name and the description of the current applied policy.")); "\n-- GetPolicy COMMAND --\nReturns the name and the description of the current applied policy."));
return; return;
} }
obj->_devices[quale]->write_buffer(obj->get_policy()->get_description()); obj->_devices[quale]->write_buffer(obj->get_policy()->get_description());
} }
else if(arguments[param] == "SETPOLICY") else if(arguments[param] == "SETPOLICY")
{ {
if(show_help) if(show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- SetPolicy COMMAND --\nSelects the current applied policy." "\n-- SetPolicy COMMAND --\nSelects the current applied policy."
"Syntax: SetPolicy <name>")); "Syntax: SetPolicy <name>"));
return; return;
} }
//FIXME assuming only one policy manager is present, but who cares, this //FIXME assuming only one policy manager is present, but who cares, this
//is only temporary code... //is only temporary code...
PolicyManager* manager = PoliciesGatekeeper::get_instance().get_registered()[0]; PolicyManager* manager = PoliciesGatekeeper::get_instance().get_registered()[0];
vector<Policy*> available = manager->get_avail_policies(); vector<Policy*> available = manager->get_avail_policies();
obj->_devices[quale]->write_buffer(arguments[1] + "\n"); obj->_devices[quale]->write_buffer(arguments[1] + "\n");
for(vector<Policy*>::iterator it = available.begin(); it != available.end(); ++it) for(vector<Policy*>::iterator it = available.begin(); it != available.end(); ++it)
{ {
if((*it)->get_name().casefold() == arguments[1].casefold()) if((*it)->get_name().casefold() == arguments[1].casefold())
{ {
obj->stop(); obj->stop();
PoliciesGatekeeper::get_instance().activate_policy(&History::get_instance(), *it); PoliciesGatekeeper::get_instance().activate_policy(&History::get_instance(), *it);
return; return;
} }
} }
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\nERROR: no policy found with that name." "\nERROR: no policy found with that name."
"\nType HELP SETPOLICY for the description of the sintax")); "\nType HELP SETPOLICY for the description of the sintax"));
} }
else if(arguments[param] == "LISTPOLICIES") else if(arguments[param] == "LISTPOLICIES")
{ {
if(show_help) if(show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- ListPolicies COMMAND --\nShows the name of available policies.")); "\n-- ListPolicies COMMAND --\nShows the name of available policies."));
return; return;
} }
//FIXME assuming only one policy manager is present, but who cares, this //FIXME assuming only one policy manager is present, but who cares, this
//is only temporary code... //is only temporary code...
PolicyManager* manager = PoliciesGatekeeper::get_instance().get_registered()[0]; PolicyManager* manager = PoliciesGatekeeper::get_instance().get_registered()[0];
vector<Policy*> available = manager->get_avail_policies(); vector<Policy*> available = manager->get_avail_policies();
for(vector<Policy*>::iterator it = available.begin(); it != available.end(); ++it) for(vector<Policy*>::iterator it = available.begin(); it != available.end(); ++it)
{ {
// Glib::ustring str; // Glib::ustring str;
// int_to_string((int)*it, str); // int_to_string((int)*it, str);
// obj->_devices[quale]->write_buffer(str + "\n"); // obj->_devices[quale]->write_buffer(str + "\n");
obj->_devices[quale]->write_buffer("\n" + (*it)->get_name()); obj->_devices[quale]->write_buffer("\n" + (*it)->get_name());
} }
} }
else if (arguments[param] == "GETPOLICYATTRIBUTES") else if (arguments[param] == "GETPOLICYATTRIBUTES")
{ {
if (show_help) if (show_help)
{ {
obj->_devices[quale]->write_buffer(_( obj->_devices[quale]->write_buffer(_(
"\n-- GetPolicyAttributes COMMAND --\nReturns the list of attributes of the current applied policy." "\n-- GetPolicyAttributes COMMAND --\nReturns the list of attributes of the current applied policy."
"\nThe description of each parameter includes:" "\nThe description of each parameter includes:"
"\n\tthe NAME of the marameter with its type\n\tits current VALUE" "\n\tthe NAME of the marameter with its type\n\tits current VALUE"
"\n\tits LOWER and UPPER bounds\n\twhether the parameter is REQUIRED")); "\n\tits LOWER and UPPER bounds\n\twhether the parameter is REQUIRED"));
return; return;
} }
ustring temp; ustring temp;
const PolicyParameters& param = obj->get_policy()->get_parameters(); const PolicyParameters& param = obj->get_policy()->get_parameters();
map<ustring, PolicyParameters::Parameter<int> > map_i = param.get_registered_int_parameters(); map<ustring, PolicyParameters::Parameter<int> > map_i = param.get_registered_int_parameters();
map<ustring, PolicyParameters::Parameter<int> >::iterator i_i = map_i.begin(); map<ustring, PolicyParameters::Parameter<int> >::iterator i_i = map_i.begin();
for(; i_i != map_i.end(); i_i++) for(; i_i != map_i.end(); i_i++)
{ {
obj->_devices[quale]->write_buffer("\nint\t" + i_i->second.get_name()); obj->_devices[quale]->write_buffer("\nint\t" + i_i->second.get_name());
int_to_string(i_i->second.get_value(), temp); int_to_string(i_i->second.get_value(), temp);
obj->_devices[quale]->write_buffer("\tvalue=" + temp); obj->_devices[quale]->write_buffer("\tvalue=" + temp);
int_to_string(i_i->second.get_lower_bound(), temp); int_to_string(i_i->second.get_lower_bound(), temp);
obj->_devices[quale]->write_buffer("\t\tlower=" + temp); obj->_devices[quale]->write_buffer("\t\tlower=" + temp);
int_to_string(i_i->second.get_upper_bound(), temp); int_to_string(i_i->second.get_upper_bound(), temp);
obj->_devices[quale]->write_buffer("\t\tupper=" + temp); obj->_devices[quale]->write_buffer("\t\tupper=" + temp);
if (i_i->second.is_required()) if (i_i->second.is_required())
obj->_devices[quale]->write_buffer("\t\trequired=true"); obj->_devices[quale]->write_buffer("\t\trequired=true");
else else
obj->_devices[quale]->write_buffer("\t\trequired=false"); obj->_devices[quale]->write_buffer("\t\trequired=false");
} }
map<ustring, PolicyParameters::Parameter<float> > map_f = param.get_registered_float_parameters(); map<ustring, PolicyParameters::Parameter<float> > map_f = param.get_registered_float_parameters();
map<ustring, PolicyParameters::Parameter<float> >::iterator i_f = map_f.begin(); map<ustring, PolicyParameters::Parameter<float> >::iterator i_f = map_f.begin();
for(; i_f != map_f.end(); i_f++) for(; i_f != map_f.end(); i_f++)
{ {
obj->_devices[quale]->write_buffer("\nfloat\t" + i_f->second.get_name()); obj->_devices[quale]->write_buffer("\nfloat\t" + i_f->second.get_name());
float_to_string(i_f->second.get_value(), temp); float_to_string(i_f->second.get_value(), temp);
obj->_devices[quale]->write_buffer("\tvalue=" + temp); obj->_devices[quale]->write_buffer("\tvalue=" + temp);
float_to_string(i_f->second.get_lower_bound(), temp); float_to_string(i_f->second.get_lower_bound(), temp);
obj->_devices[quale]->write_buffer("\t\tlower=" + temp); obj->_devices[quale]->write_buffer("\t\tlower=" + temp);
float_to_string(i_f->second.get_upper_bound(), temp); float_to_string(i_f->second.get_upper_bound(), temp);
obj->_devices[quale]->write_buffer("\t\tupper=" + temp); obj->_devices[quale]->write_buffer("\t\tupper=" + temp);
if (i_f->second.is_required()) if (i_f->second.is_required())
obj->_devices[quale]->write_buffer("\t\trequired=true"); obj->_devices[quale]->write_buffer("\t\trequired=true");
else else
obj->_devices[quale]->write_buffer("\t\trequired=false"); obj->_devices[quale]->write_buffer("\t\trequired=false");
} }
map<ustring, PolicyParameters::Parameter<ustring> > map_s = param.get_registered_string_parameters(); map<ustring, PolicyParameters::Parameter<ustring> > map_s = param.get_registered_string_parameters();
map<ustring, PolicyParameters::Parameter<ustring> >::iterator i_s = map_s.begin(); map<ustring, PolicyParameters::Parameter<ustring> >::iterator i_s = map_s.begin();
for(; i_s != map_s.end(); i_s++) for(; i_s != map_s.end(); i_s++)
{ {
obj->_devices[quale]->write_buffer("\nustring\t" + i_s->second.get_name()); obj->_devices[quale]->write_buffer("\nustring\t" + i_s->second.get_name());
obj->_devices[quale]->write_buffer("\tvalue=" + i_s->second.get_value()); obj->_devices[quale]->write_buffer("\tvalue=" + i_s->second.get_value());
if (i_s->second.is_required()) if (i_s->second.is_required())
obj->_devices[quale]->write_buffer(" required=true"); obj->_devices[quale]->write_buffer(" required=true");
else else
obj->_devices[quale]->write_buffer(" required=false"); obj->_devices[quale]->write_buffer(" required=false");
} }
} }
else else
{ {
obj->_devices[quale]->write_buffer(_("\nCommand not recognized: ")); obj->_devices[quale]->write_buffer(_("\nCommand not recognized: "));
obj->_devices[quale]->write_buffer(arguments[param]); obj->_devices[quale]->write_buffer(arguments[param]);
obj->_devices[quale]->write_buffer(_("\nTyper HELP for a list of avaiable commands.")); obj->_devices[quale]->write_buffer(_("\nTyper HELP for a list of avaiable commands."));
return; return;
} }
} }
void void
TextSimulation::update() TextSimulation::update()
{ {
History& h = History::get_instance(); History& h = History::get_instance();
int when, arr; int when, arr;
ustring temp; ustring temp;
when = h.get_current_time(); when = h.get_current_time();
smart_ptr<SchedulableQueue> ll = h.get_simulation_status_at(when); smart_ptr<SchedulableQueue> ll = h.get_simulation_status_at(when);
for (uint dev=0; dev < _devices.size(); dev++) for (uint dev = 0; dev < _devices.size(); dev++)
{ {
int_to_string(when, temp); int_to_string(when, temp);
if (when<10) if (when < 10)
_devices[dev]->write_buffer("\n "); _devices[dev]->write_buffer("\n ");
else else
_devices[dev]->write_buffer("\n"); _devices[dev]->write_buffer("\n");
_devices[dev]->write_buffer(temp + ") [RUNS]"); _devices[dev]->write_buffer(temp + ") [RUNS]");
//insert the RUNNING ONE //insert the RUNNING ONE
smart_ptr<DynamicSchedulable> running = h.get_scheduled_at(when); smart_ptr<DynamicSchedulable> running = h.get_scheduled_at(when);
if (running) if (running)
{ {
arr = running->get_schedulable()->get_arrival_time(); arr = running->get_schedulable()->get_arrival_time();
int_to_string(arr, temp); int_to_string(arr, temp);
_devices[dev]->write_buffer(" " + running->get_schedulable()->get_name() + "_(" + temp + ")"); _devices[dev]->write_buffer(" " + running->get_schedulable()->get_name() + "_(" + temp + ")");
} }
_devices[dev]->write_buffer(" --[READY]"); _devices[dev]->write_buffer(" --[READY]");
//insert the READY ones //insert the READY ones
for (uint i = 0; i < ll->size(); i++) for (uint i = 0; i < ll->size(); i++)
if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_ready) if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_ready)
{ {
arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time(); arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
int_to_string(arr, temp); int_to_string(arr, temp);
_devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")"); _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
} }
_devices[dev]->write_buffer(" --[BLOCKED]"); _devices[dev]->write_buffer(" --[BLOCKED]");
//insert the BLOCKED ones //insert the BLOCKED ones
for (uint i = 0; i < ll->size(); i++) for (uint i = 0; i < ll->size(); i++)
if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_blocked) if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_blocked)
{ {
arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time(); arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
int_to_string(arr, temp); int_to_string(arr, temp);
_devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")"); _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
} }
_devices[dev]->write_buffer(" --[FUTURE]"); _devices[dev]->write_buffer(" --[FUTURE]");
//insert the FUTURE ones //insert the FUTURE ones
for (uint i = 0; i < ll->size(); i++) for (uint i = 0; i < ll->size(); i++)
if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_future) if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_future)
{ {
arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time(); arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
int_to_string(arr, temp); int_to_string(arr, temp);
_devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")"); _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
} }
_devices[dev]->write_buffer(" --[TERM]"); _devices[dev]->write_buffer(" --[TERM]");
//insert the TERMINATED ones //insert the TERMINATED ones
for (uint i = 0; i < ll->size(); i++) for (uint i = 0; i < ll->size(); i++)
if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_terminated) if (ll->get_item_at(i)->get_state() == DynamicSchedulable::state_terminated)
{ {
arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time(); arr = ll->get_item_at(i)->get_schedulable()->get_arrival_time();
int_to_string(arr, temp); int_to_string(arr, temp);
_devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")"); _devices[dev]->write_buffer(" " + ll->get_item_at(i)->get_schedulable()->get_name() + "_(" + temp + ")");
} }
} }
} }
void void
TextSimulation::_io_loop(pair<TextSimulation* , int > pun) TextSimulation::_io_loop(pair<TextSimulation* , int > pun)
{ {
while(true) while(true)
{ {
//reads the command //reads the command
ustring str; ustring str;
//the sgpem cursor appears only in the console //the sgpem cursor appears only in the console
//if (!pun.first->_devices[pun.second]->is_full_duplex()) //if (!pun.first->_devices[pun.second]->is_full_duplex())
pun.first->_devices[pun.second]->write_buffer("\nSGPEM=> "); pun.first->_devices[pun.second]->write_buffer("\nSGPEM=> ");
str = pun.first->_devices[pun.second]->read_command(); str = pun.first->_devices[pun.second]->read_command();
pair< pair<TextSimulation*, IOManager*>, const ustring > p pair< pair<TextSimulation*, IOManager*>, const ustring > p
(pair<TextSimulation*, IOManager*>(pun.first, &(*pun.first->_devices[pun.second])), str); (pair<TextSimulation*, IOManager*>(pun.first, &(*pun.first->_devices[pun.second])), str);
//if (pun.first->_devices[pun.second]->is_full_duplex()) //if (pun.first->_devices[pun.second]->is_full_duplex())
//if the IOManager can read AND write at the same time then create a new thread //if the IOManager can read AND write at the same time then create a new thread
//thath will write to it while going on reading the next command //thath will write to it while going on reading the next command
//Thread::create( sigc::bind(&TextSimulation::parse_command, p), true); //Thread::create( sigc::bind(&TextSimulation::parse_command, p), true);
//else //else
//no read is possible: only write //no read is possible: only write
pun.first->parse_command(p); pun.first->parse_command(p);
} }
} }

View File

@ -38,7 +38,7 @@
namespace sgpem namespace sgpem
{ {
class TextSimulation; class TextSimulation;
/** /**
\brief Concrete \ref Simulation subclass with a text-based user interface. \brief Concrete \ref Simulation subclass with a text-based user interface.
@ -48,81 +48,81 @@ namespace sgpem
Any object returned after the call to Simulation will be returned to the output Any object returned after the call to Simulation will be returned to the output
devices(s) in a human-readable format. devices(s) in a human-readable format.
*/ */
class SG_DLLEXPORT TextSimulation : public Simulation, public sigc::trackable class SG_DLLEXPORT TextSimulation : public Simulation, public sigc::trackable
{ {
public: public:
~TextSimulation(); ~TextSimulation();
/** /**
\brief Executes a command read from an input device. \brief Executes a command read from an input device.
A list of supported commands follows: A list of supported commands follows:
\li help \<string\> <br> \li help \<string\> <br>
If \<string\> is a valid command, usage instructions are printed If \<string\> is a valid command, usage instructions are printed
for the command. for the command.
\li run <br> \li run <br>
Calls run() Calls run()
\li pause <br> \li pause <br>
Calls pause() Calls pause()
\li stop <br> \li stop <br>
Calls stop() Calls stop()
\li setmode \<bool\> <br> \li setmode \<bool\> <br>
Calls set_mode() Calls set_mode()
\li getmode <br> \li getmode <br>
Calls get_mode() Calls get_mode()
\li settimer \<int\> <br> \li settimer \<int\> <br>
Calls set_timer() Calls set_timer()
\li gettimer <br> \li gettimer <br>
Calls get_timer() Calls get_timer()
\li reset <br> \li reset <br>
Calls reset() Calls reset()
\li jumpto \<int\> <br> \li jumpto \<int\> <br>
Calls jump_to() Calls jump_to()
\li setpolicy \<string\> <br> \li setpolicy \<string\> <br>
Calls set_policy() Calls set_policy()
\li getpolicy <br> \li getpolicy <br>
Calls get_policy(), and prints the name and a description of Calls get_policy(), and prints the name and a description of
the returned policy the returned policy
\li getpolicies <br> \li getpolicies <br>
Calls get_avaiable_policies(), and prints a list of policy Calls get_avaiable_policies(), and prints a list of policy
descriptions in the same way as getpolicy does descriptions in the same way as getpolicy does
\li setpolicyattributes \<name\> = \<value\>; \<name\> = \<value\>; <br> \li setpolicyattributes \<name\> = \<value\>; \<name\> = \<value\>; <br>
Changes the value of the policy's attributes Changes the value of the policy's attributes
\li getpolicyattributes <br> \li getpolicyattributes <br>
Prints the name and the value of the policy's attributes Prints the name and the value of the policy's attributes
*/ */
static void parse_command(std::pair< std::pair<TextSimulation*, IOManager*>, const Glib::ustring >); static void parse_command(std::pair< std::pair<TextSimulation*, IOManager*>, const Glib::ustring >);
/** /**
Adds an available I/O device. Adds an available I/O device.
*/ */
void add_io_device(memory::smart_ptr<IOManager>); void add_io_device(memory::smart_ptr<IOManager>);
/** /**
Prints the actual state of the simulation, with emphasis on the current Prints the actual state of the simulation, with emphasis on the current
status of the scheduling process (ready queue and running process). status of the scheduling process (ready queue and running process).
*/ */
void update(); void update();
private: private:
std::vector<memory::smart_ptr<IOManager> > _devices; std::vector<memory::smart_ptr<IOManager> > _devices;
static void _io_loop(std::pair<TextSimulation*, int>); static void _io_loop(std::pair<TextSimulation*, int>);
}; };
} }