- 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 = plugin_LTLIBRARIES =
noinst_HEADERS = noinst_HEADERS =
pkglib_LTLIBRARIES = pkglib_LTLIBRARIES =
pkginclude_HEADERS =
EXTRA_DIST = EXTRA_DIST =
MAINTAINERCLEANFILES = MAINTAINERCLEANFILES =
MOSTLYCLEANFILES = MOSTLYCLEANFILES =
@ -127,6 +128,7 @@ pkglib_LTLIBRARIES += src/backend/libbackend.la
src_backend_libbackend_la_CPPFLAGS = \ src_backend_libbackend_la_CPPFLAGS = \
-I@top_srcdir@ \ -I@top_srcdir@ \
-I@top_srcdir@/src/templates \
-DPOLDIR="\"$(policiesdir)\"" \ -DPOLDIR="\"$(policiesdir)\"" \
-DPLUGDIR="\"$(plugindir)\"" \ -DPLUGDIR="\"$(plugindir)\"" \
-DLOCALEDIR="\"$(localedir)\"" \ -DLOCALEDIR="\"$(localedir)\"" \
@ -163,7 +165,7 @@ src_backend_libbackend_la_SOURCES = \
src/backend/thread.cc \ src/backend/thread.cc \
src/backend/user_interrupt_exception.cc src/backend/user_interrupt_exception.cc
pkginclude_HEADERS = \ pkginclude_HEADERS += \
config.h \ config.h \
src/backend/dynamic_process.hh \ src/backend/dynamic_process.hh \
src/backend/dynamic_schedulable.hh \ src/backend/dynamic_schedulable.hh \
@ -198,6 +200,7 @@ bin_PROGRAMS += sgpemv2
sgpemv2_CPPFLAGS = \ sgpemv2_CPPFLAGS = \
-I@top_srcdir@ \ -I@top_srcdir@ \
-I@top_srcdir@/src/templates \
-DLOCALEDIR="\"$(localedir)\"" \ -DLOCALEDIR="\"$(localedir)\"" \
$(CAIRO_CFLAGS) \ $(CAIRO_CFLAGS) \
$(GTKMM_CFLAGS) \ $(GTKMM_CFLAGS) \
@ -242,10 +245,12 @@ noinst_HEADERS += \
# #
# ############################################################ # ############################################################
noinst_HEADERS += \ pkginclude_HEADERS += \
src/templates/parameter.tcc \ src/templates/parameter.tcc \
src/templates/smartp.tcc \ src/templates/singleton.hh \
src/templates/smartp.hh src/templates/singleton.tcc \
src/templates/smartp.hh \
src/templates/smartp.tcc
# ############################################################ # ############################################################
# #
@ -266,6 +271,7 @@ noinst_PROGRAMS = \
src_testsuite_test_history_CPPFLAGS = \ src_testsuite_test_history_CPPFLAGS = \
-I@top_srcdir@/src \ -I@top_srcdir@/src \
-I@top_srcdir@/src/templates \
$(GLIBMM_CFLAGS) $(GLIBMM_CFLAGS)
src_testsuite_test_history_LDFLAGS = \ src_testsuite_test_history_LDFLAGS = \
src/backend/libbackend.la \ src/backend/libbackend.la \
@ -277,6 +283,7 @@ src_testsuite_test_history_SOURCES = \
#src_testsuite_test_parse_command_CPPFLAGS = \ #src_testsuite_test_parse_command_CPPFLAGS = \
# -I@top_srcdir@/src \ # -I@top_srcdir@/src \
# -I@top_srcdir@/src/templates \
# $(GLIBMM_CFLAGS) # $(GLIBMM_CFLAGS)
#src_testsuite_test_parse_command_LDFLAGS = \ #src_testsuite_test_parse_command_LDFLAGS = \
# src/backend/libbackend.la \ # 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. # advice: get dummy_policy from the somewhere in the repository, and compile it in.
#src_testsuite_test_stepforward_CPPFLAGS = \ #src_testsuite_test_stepforward_CPPFLAGS = \
# -I@top_srcdir@/src \ # -I@top_srcdir@/src \
# -I@top_srcdir@/src/templates \
# $(GLIBMM_CFLAGS) # $(GLIBMM_CFLAGS)
#src_testsuite_test_stepforward_LDFLAGS = \ #src_testsuite_test_stepforward_LDFLAGS = \
# src/backend/libbackend.la \ # 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 Requires: glibmm-2.4 >= 2.8 gthread-2.0 >= 2.8
Libs: -L${libdir}/src/backend -lbackend Libs: -L${libdir}/src/backend -lbackend
Libs.private: -lglibmm-2.4 -lgthread-2.0 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. // environment variables.
// FIXME: find better way to achieve this. // FIXME: find better way to achieve this.
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(GlobalPreferences::instance().policies_dir_begin(), for_each(prefs.policies_dir_begin(),
GlobalPreferences::instance().policies_dir_end(), prefs.policies_dir_end(),
pol_dirs_concat(importdirs)); pol_dirs_concat(importdirs));
importdirs += " '" SHAREDIR "' ]\n"; importdirs += " '" SHAREDIR "' ]\n";
@ -131,8 +132,9 @@ PythonPolicyManager::get_avail_policies()
void void
PythonPolicyManager::collect_policies() PythonPolicyManager::collect_policies()
{ {
GlobalPreferences::dir_iterator dir_it = GlobalPreferences::instance().policies_dir_begin(); GlobalPreferences& prefs = GlobalPreferences::get_instance();
GlobalPreferences::dir_iterator dir_end = GlobalPreferences::instance().policies_dir_end(); 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) for(; dir_it != dir_end; ++dir_it)
{ {

View File

@ -67,7 +67,7 @@ main(int argc, char** argv) {
} }
else else
// Add argv[1] as the directory to search for uninstalled policies // 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 // Self-register itself to Scheduler, however we don't care about it
TestPythonPolicyManager polman; TestPythonPolicyManager polman;

View File

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

View File

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

View File

@ -23,27 +23,15 @@ using namespace std;
using namespace sgpem; using namespace sgpem;
using namespace memory; 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 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. The parameter is discarded History::History() //private constructor.
:_total_time_elapsed(-1) :_total_time_elapsed(-1)
{} {}
History&
History::get_instance()
{
if(!_instance)
_instance = new History();
return *_instance;
}
/** /**
Returns a pointer to a copy of the DynamicSchedulable object relative to this instant. Returns a pointer to a copy of the DynamicSchedulable object relative to this instant.
It can be NULL if time is out of range or if there are no running entities in the associated It can be NULL if time is out of range or if there are no running entities in the associated

View File

@ -32,6 +32,8 @@
#include "dynamic_schedulable.hh" #include "dynamic_schedulable.hh"
#include "../templates/smartp.hh" #include "../templates/smartp.hh"
#include "singleton.hh"
namespace sgpem namespace sgpem
{ {
@ -47,8 +49,10 @@ namespace sgpem
*/ */
class History; class History;
class SG_DLLEXPORT History : public ObservedSubject class SG_DLLEXPORT History : public Singleton<History>, public ObservedSubject
{ {
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.
@ -83,15 +87,8 @@ namespace sgpem
virtual void truncate_at(int instant); virtual void truncate_at(int instant);
/**
Gets the only instance of History.
\return The Singleton instance of this object.
*/
static History& get_instance();
protected: protected:
History(); //private constructor. The parameter is discarded History(); //private constructor.
static History* _instance;
private: private:
int _total_time_elapsed; int _total_time_elapsed;

View File

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

View File

@ -34,6 +34,8 @@ namespace sgpem
#include <map> #include <map>
#include <stdexcept> #include <stdexcept>
#include "singleton.hh"
namespace sgpem namespace sgpem
{ {
class PoliciesGatekeeper; class PoliciesGatekeeper;
@ -43,15 +45,11 @@ namespace sgpem
*/ */
class SG_DLLEXPORT PoliciesGatekeeper class SG_DLLEXPORT PoliciesGatekeeper : public Singleton<PoliciesGatekeeper>
{ {
public: friend class Singleton<PoliciesGatekeeper>;
/** \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();
public:
std::vector<PolicyManager*> get_registered() const; std::vector<PolicyManager*> get_registered() const;
void register_manager(PolicyManager* manager); void register_manager(PolicyManager* manager);
@ -68,7 +66,6 @@ namespace sgpem
// 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);
static PoliciesGatekeeper* _instance;
std::vector<PolicyManager*> _registered; std::vector<PolicyManager*> _registered;
std::map<History*, Policy*> _active_policies; std::map<History*, Policy*> _active_policies;
}; };

View File

@ -29,9 +29,6 @@ using namespace std;
using namespace sgpem; using namespace sgpem;
using namespace memory; using namespace memory;
Scheduler*
Scheduler::_instance = 0;
//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())
@ -39,14 +36,6 @@ Scheduler::Scheduler()
_policy_manager.init(); _policy_manager.init();
} }
Scheduler&
Scheduler::get_instance()
{
if(!_instance)
_instance = new Scheduler();
return *_instance;
}
SchedulableQueue* SchedulableQueue*
Scheduler::get_ready_queue() Scheduler::get_ready_queue()
{ {

View File

@ -37,6 +37,8 @@ namespace sgpem
#include "schedulable_queue.hh" #include "schedulable_queue.hh"
#include "user_interrupt_exception.hh" #include "user_interrupt_exception.hh"
#include "singleton.hh"
namespace sgpem namespace sgpem
{ {
class Scheduler; class Scheduler;
@ -52,16 +54,10 @@ namespace sgpem
*/ */
class SG_DLLEXPORT Scheduler class SG_DLLEXPORT Scheduler : public Singleton<Scheduler>
{ {
friend class Singleton<Scheduler>;
public: 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 Returns a pointer to the queue containing all the ready
schedulable objects (for the policy to sort it). schedulable objects (for the policy to sort it).
@ -95,7 +91,6 @@ namespace sgpem
private: private:
Scheduler(); //private constructor. Scheduler(); //private constructor.
static Scheduler* _instance;
SchedulableQueue _ready_queue; SchedulableQueue _ready_queue;
PolicyManager& _policy_manager; PolicyManager& _policy_manager;
}; };
@ -103,8 +98,3 @@ namespace sgpem
}//~ namespace sgpem }//~ namespace sgpem
#endif //SCHEDULER_HH #endif //SCHEDULER_HH

View File

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

View File

@ -80,10 +80,10 @@ parse_options(int& argc, char**& argv)
// FIXME : to be written! // FIXME : to be written!
break; break;
case 'P': case 'P':
GlobalPreferences::instance().add_policies_dir(optarg); GlobalPreferences::get_instance().add_policies_dir(optarg);
break; break;
case 'M': case 'M':
GlobalPreferences::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"

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 // of Padova, dept. of Pure and Applied
// Mathematics // 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