- Add unified Singleton support

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@643 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-06-21 09:09:50 +00:00
parent 8ca3a61730
commit 383889a203
17 changed files with 193 additions and 136 deletions

View File

@ -48,6 +48,7 @@ bin_PROGRAMS =
plugin_LTLIBRARIES =
noinst_HEADERS =
pkglib_LTLIBRARIES =
pkginclude_HEADERS =
EXTRA_DIST =
MAINTAINERCLEANFILES =
MOSTLYCLEANFILES =
@ -127,6 +128,7 @@ pkglib_LTLIBRARIES += src/backend/libbackend.la
src_backend_libbackend_la_CPPFLAGS = \
-I@top_srcdir@ \
-I@top_srcdir@/src/templates \
-DPOLDIR="\"$(policiesdir)\"" \
-DPLUGDIR="\"$(plugindir)\"" \
-DLOCALEDIR="\"$(localedir)\"" \
@ -163,7 +165,7 @@ src_backend_libbackend_la_SOURCES = \
src/backend/thread.cc \
src/backend/user_interrupt_exception.cc
pkginclude_HEADERS = \
pkginclude_HEADERS += \
config.h \
src/backend/dynamic_process.hh \
src/backend/dynamic_schedulable.hh \
@ -198,6 +200,7 @@ bin_PROGRAMS += sgpemv2
sgpemv2_CPPFLAGS = \
-I@top_srcdir@ \
-I@top_srcdir@/src/templates \
-DLOCALEDIR="\"$(localedir)\"" \
$(CAIRO_CFLAGS) \
$(GTKMM_CFLAGS) \
@ -242,10 +245,12 @@ noinst_HEADERS += \
#
# ############################################################
noinst_HEADERS += \
pkginclude_HEADERS += \
src/templates/parameter.tcc \
src/templates/smartp.tcc \
src/templates/smartp.hh
src/templates/singleton.hh \
src/templates/singleton.tcc \
src/templates/smartp.hh \
src/templates/smartp.tcc
# ############################################################
#
@ -266,6 +271,7 @@ noinst_PROGRAMS = \
src_testsuite_test_history_CPPFLAGS = \
-I@top_srcdir@/src \
-I@top_srcdir@/src/templates \
$(GLIBMM_CFLAGS)
src_testsuite_test_history_LDFLAGS = \
src/backend/libbackend.la \
@ -277,6 +283,7 @@ src_testsuite_test_history_SOURCES = \
#src_testsuite_test_parse_command_CPPFLAGS = \
# -I@top_srcdir@/src \
# -I@top_srcdir@/src/templates \
# $(GLIBMM_CFLAGS)
#src_testsuite_test_parse_command_LDFLAGS = \
# src/backend/libbackend.la \
@ -288,6 +295,7 @@ src_testsuite_test_history_SOURCES = \
# advice: get dummy_policy from the somewhere in the repository, and compile it in.
#src_testsuite_test_stepforward_CPPFLAGS = \
# -I@top_srcdir@/src \
# -I@top_srcdir@/src/templates \
# $(GLIBMM_CFLAGS)
#src_testsuite_test_stepforward_LDFLAGS = \
# src/backend/libbackend.la \

View File

@ -14,4 +14,4 @@ URL: http://www.math.unipd.it/
Requires: glibmm-2.4 >= 2.8 gthread-2.0 >= 2.8
Libs: -L${libdir}/src/backend -lbackend
Libs.private: -lglibmm-2.4 -lgthread-2.0
Cflags: -I${includedir}/backend
Cflags: -I${includedir}/backend -I${includedir}/templates

View File

@ -107,10 +107,11 @@ PythonPolicyManager::init()
// environment variables.
// FIXME: find better way to achieve this.
GlobalPreferences& prefs = GlobalPreferences::get_instance();
Glib::ustring importdirs = "import sys\n"
"sys.path[:0] = [ ";
for_each(GlobalPreferences::instance().policies_dir_begin(),
GlobalPreferences::instance().policies_dir_end(),
for_each(prefs.policies_dir_begin(),
prefs.policies_dir_end(),
pol_dirs_concat(importdirs));
importdirs += " '" SHAREDIR "' ]\n";
@ -131,8 +132,9 @@ PythonPolicyManager::get_avail_policies()
void
PythonPolicyManager::collect_policies()
{
GlobalPreferences::dir_iterator dir_it = GlobalPreferences::instance().policies_dir_begin();
GlobalPreferences::dir_iterator dir_end = GlobalPreferences::instance().policies_dir_end();
GlobalPreferences& prefs = GlobalPreferences::get_instance();
GlobalPreferences::dir_iterator dir_it = prefs.policies_dir_begin();
GlobalPreferences::dir_iterator dir_end = prefs.policies_dir_end();
for(; dir_it != dir_end; ++dir_it)
{

View File

@ -67,7 +67,7 @@ main(int argc, char** argv) {
}
else
// Add argv[1] as the directory to search for uninstalled policies
sgpem::GlobalPreferences::instance().add_policies_dir(argv[1]);
sgpem::GlobalPreferences::get_instance().add_policies_dir(argv[1]);
// Self-register itself to Scheduler, however we don't care about it
TestPythonPolicyManager polman;

View File

@ -23,17 +23,6 @@
using namespace sgpem;
GlobalPreferences* GlobalPreferences::_instance = 0;
GlobalPreferences&
GlobalPreferences::instance()
{
if(!_instance)
_instance = new GlobalPreferences();
return *_instance;
}
GlobalPreferences::GlobalPreferences()
: _mod_dirs(1, PLUGDIR), _pol_dirs(1, POLDIR)
{}

View File

@ -26,6 +26,8 @@
#include <glibmm/ustring.h>
#include <vector>
#include "singleton.hh"
namespace sgpem {
class GlobalPreferences;
}
@ -33,12 +35,13 @@ namespace sgpem {
#include "config.h"
namespace sgpem {
class SG_DLLEXPORT GlobalPreferences {
public:
class SG_DLLEXPORT GlobalPreferences : public Singleton<GlobalPreferences>
{
friend class Singleton<GlobalPreferences>;
public:
typedef std::vector<Glib::ustring>::const_iterator dir_iterator;
static GlobalPreferences& instance();
dir_iterator modules_dir_begin() const;
dir_iterator modules_dir_end() const;
@ -53,7 +56,6 @@ namespace sgpem {
GlobalPreferences(const GlobalPreferences&);
GlobalPreferences& operator=(const GlobalPreferences&);
static GlobalPreferences* _instance;
std::vector<Glib::ustring> _mod_dirs;
std::vector<Glib::ustring> _pol_dirs;
};

View File

@ -23,25 +23,13 @@ using namespace std;
using namespace sgpem;
using namespace memory;
//History::instance; //static object
History* History::_instance = 0;
/**
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.
*/
History::History() //private constructor. The parameter is discarded
History::History() //private constructor.
:_total_time_elapsed(-1)
{}
History&
History::get_instance()
{
if(!_instance)
_instance = new History();
return *_instance;
}
/**

View File

@ -32,6 +32,8 @@
#include "dynamic_schedulable.hh"
#include "../templates/smartp.hh"
#include "singleton.hh"
namespace sgpem
{
@ -47,8 +49,10 @@ namespace sgpem
*/
class History;
class SG_DLLEXPORT History : public ObservedSubject
class SG_DLLEXPORT History : public Singleton<History>, public ObservedSubject
{
friend class Singleton<History>;
public:
/**
Gets the \ref Schedulable object running at the specified time.
@ -82,16 +86,9 @@ namespace sgpem
*/
virtual void truncate_at(int instant);
/**
Gets the only instance of History.
\return The Singleton instance of this object.
*/
static History& get_instance();
protected:
History(); //private constructor. The parameter is discarded
static History* _instance;
History(); //private constructor.
private:
int _total_time_elapsed;

View File

@ -34,16 +34,6 @@ using namespace sgpem;
typedef vector<PolicyManager*>::iterator ManagerIterator;
typedef map<History*, Policy*>::iterator ActiveIterator;
PoliciesGatekeeper* PoliciesGatekeeper::_instance = NULL;
PoliciesGatekeeper&
PoliciesGatekeeper::get_instance()
{
if(!_instance)
_instance = new PoliciesGatekeeper();
return *_instance;
}
vector<PolicyManager*>
PoliciesGatekeeper::get_registered() const
{

View File

@ -34,6 +34,8 @@ namespace sgpem
#include <map>
#include <stdexcept>
#include "singleton.hh"
namespace sgpem
{
class PoliciesGatekeeper;
@ -43,15 +45,11 @@ namespace sgpem
*/
class SG_DLLEXPORT PoliciesGatekeeper
class SG_DLLEXPORT PoliciesGatekeeper : public Singleton<PoliciesGatekeeper>
{
public:
/** \brief Returns the unique instance of this class, conforming to the Singleton pattern.
*
* \return the unique instance of this class, conforming to the Singleton pattern.
*/
static PoliciesGatekeeper& get_instance();
friend class Singleton<PoliciesGatekeeper>;
public:
std::vector<PolicyManager*> get_registered() const;
void register_manager(PolicyManager* manager);
@ -68,7 +66,6 @@ namespace sgpem
// Deactivates active policies managed by the specified manager.
void deactivate_policies(PolicyManager* manager);
static PoliciesGatekeeper* _instance;
std::vector<PolicyManager*> _registered;
std::map<History*, Policy*> _active_policies;
};

View File

@ -29,9 +29,6 @@ using namespace std;
using namespace sgpem;
using namespace memory;
Scheduler*
Scheduler::_instance = 0;
//private constructor. The parameter is discarded
Scheduler::Scheduler()
: _policy_manager(PolicyManager::get_registered_manager())
@ -39,14 +36,6 @@ Scheduler::Scheduler()
_policy_manager.init();
}
Scheduler&
Scheduler::get_instance()
{
if(!_instance)
_instance = new Scheduler();
return *_instance;
}
SchedulableQueue*
Scheduler::get_ready_queue()
{

View File

@ -37,11 +37,13 @@ namespace sgpem
#include "schedulable_queue.hh"
#include "user_interrupt_exception.hh"
#include "singleton.hh"
namespace sgpem
{
class Scheduler;
class Scheduler;
/** \brief Manages the DynamicSchedulable objects, implementing a given policy.
/** \brief Manages the DynamicSchedulable objects, implementing a given policy.
Class Scheduler manages the schedulable entities which are ready to run,
ordering them in a queue; it also checks that the current scheduling policy
@ -50,61 +52,49 @@ namespace sgpem
the DynamicSchedulable objects (for further details about this, check
class DynamicSchedulable).
*/
*/
class SG_DLLEXPORT Scheduler
{
public:
/** \brief Returns the unique instance of this class, conforming to the Singleton pattern.
*
* If Scheduler isn't initialized, creates it. Should be called at least once before
* starting the Simulation.
* \return the unique instance of this class, conforming to the Singleton pattern.
*/
static Scheduler& get_instance();
/**
Returns a pointer to the queue containing all the ready
schedulable objects (for the policy to sort it).
\return a pointer to the queue containing all the ready
schedulable objects (for the policy to sort it).
*/
SchedulableQueue* get_ready_queue();
/**
Resets the simulation to the initial state.
*/
void reset_status();
/**
Generates a new SchedulableQueue representing the status of the processes
at the simulation instant next to the current one, and extends the History by
one instant with it.
*/
void step_forward() throw(UserInterruptException);
/**
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.
*/
/* DISABLED until we don't have PolicyManager::set_policy()
void set_policy(Policy* policy);
*/
/**
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.
*/
Policy& get_policy();
class SG_DLLEXPORT Scheduler : public Singleton<Scheduler>
{
friend class Singleton<Scheduler>;
public:
/**
Returns a pointer to the queue containing all the ready
schedulable objects (for the policy to sort it).
\return a pointer to the queue containing all the ready
schedulable objects (for the policy to sort it).
*/
SchedulableQueue* get_ready_queue();
/**
Resets the simulation to the initial state.
*/
void reset_status();
/**
Generates a new SchedulableQueue representing the status of the processes
at the simulation instant next to the current one, and extends the History by
one instant with it.
*/
void step_forward() throw(UserInterruptException);
/**
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.
*/
/* DISABLED until we don't have PolicyManager::set_policy()
void set_policy(Policy* policy);
*/
/**
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.
*/
Policy& get_policy();
private:
Scheduler(); //private constructor.
static Scheduler* _instance;
SchedulableQueue _ready_queue;
PolicyManager& _policy_manager;
};
private:
Scheduler(); //private constructor.
SchedulableQueue _ready_queue;
PolicyManager& _policy_manager;
};
}//~ namespace sgpem
#endif //SCHEDULER_HH

View File

@ -63,8 +63,9 @@ static void load_pyloader_plugin() {
// Leaks willingly:
Module* pyloader = 0;
GlobalPreferences::dir_iterator it = GlobalPreferences::instance().modules_dir_begin();
while(it != GlobalPreferences::instance().modules_dir_end()) {
GlobalPreferences& prefs = GlobalPreferences::get_instance();
GlobalPreferences::dir_iterator it = prefs.modules_dir_begin();
while(it != prefs.modules_dir_end()) {
std::string pyloader_path = Module::build_path(*it, "pyloader");
pyloader = new Module(pyloader_path);
if(*pyloader) break;

View File

@ -80,10 +80,10 @@ parse_options(int& argc, char**& argv)
// FIXME : to be written!
break;
case 'P':
GlobalPreferences::instance().add_policies_dir(optarg);
GlobalPreferences::get_instance().add_policies_dir(optarg);
break;
case 'M':
GlobalPreferences::instance().add_modules_dir(optarg);
GlobalPreferences::get_instance().add_modules_dir(optarg);
break;
case ':':
printf(_("[EE] Wrong number of parameters. Please see \n"

View File

@ -1,4 +1,4 @@
// Src/templates/parameter.tcc - Copyright 2005, 2006, University
// src/templates/parameter.tcc - Copyright 2005, 2006, University
// of Padova, dept. of Pure and Applied
// Mathematics
//

View File

@ -0,0 +1,59 @@
// singleton.hh - Copyright 2005, 2006, University
// of Padova, dept. of Pure and Applied
// Mathematics
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef SINGLETON_HH
#define SINGLETON_HH 1
#include <glibmm/thread.h>
#include "config.h"
namespace sgpem
{
/** \brief An abstract implementation of the Singleton design pattern.
*
* Singleton implementers constuctor will have to declare friendliness
* to Singleton::get_instance(). This also attempts to achieve
* thread-safeness.
*/
template<typename Instantiated_class>
class SG_DLLEXPORT Singleton
{
public:
/** \brief Ensures thread safety is respected, and returns the instantiated object
*
* This is done by locking _instance via a mutex, before intantiating the
* Instantiated_class attribute (if not done before).
*
* \return The instantiated object
*/
static Instantiated_class& get_instance();
private:
static Instantiated_class* _instance;
static Glib::StaticMutex _mutex;
}; //~ class Singleton
} //~ namespace sgpem
#include "singleton.tcc"
#endif //~ SINGLETON_HH

View File

@ -0,0 +1,45 @@
// singleton.tcc - Copyright 2005, 2006, University
// of Padova, dept. of Pure and Applied
// Mathematics
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef SINGLETON_TCC
#define SINGLETON_TCC 1
#include "singleton.hh"
template<typename Instantiated_class>
Instantiated_class*
sgpem::Singleton<Instantiated_class>::_instance = NULL;
template<typename Instantiated_class>
Glib::StaticMutex
sgpem::Singleton<Instantiated_class>::_mutex = GLIBMM_STATIC_MUTEX_INIT;
template<typename Instantiated_class>
Instantiated_class&
sgpem::Singleton<Instantiated_class>::get_instance()
{
Glib::Mutex::Lock lock(_mutex);
if(_instance == NULL)
_instance = new Instantiated_class();
return *_instance;
}
#endif //~ SINGLETON_TCC