InitSequencer.h

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 #ifndef __INITSEQUENCER_H__
00039 #define __INITSEQUENCER_H__
00040 
00041 #include <vector>
00042 #include <map>
00043 #include <string>
00044 
00045 #include "../util/Singleton.h"
00046 #include "../debug/Logger.h"
00047 
00048 namespace oasys {
00049 
00050 // predecl
00051 class InitStep;
00052 class InitExtraDependency;
00053 
00098 class InitSequencer : public Logger {
00099     friend class InitExtraDependency;
00100 
00101 public:
00102     typedef std::map<std::string, InitStep*> StepMap;
00103     typedef std::vector<std::string>         Plan;
00104 
00105     InitSequencer();
00106 
00114     int start(std::string step, Plan* plan = 0);
00115 
00119     void add_step(InitStep* step);
00120 
00124     InitStep* get_step(const std::string& name);
00125 
00131     void reset();
00132 
00136     void print_dot();
00137 
00138 private:
00139     typedef std::vector<std::string>              ReverseDepList;
00140     typedef std::map<std::string, ReverseDepList> ReverseDepEdges;
00141     
00142     StepMap steps_;
00143     int     dfs_time_;
00144 
00145     std::vector<InitExtraDependency*> extra_dependencies_;
00146 
00148     int run_steps();
00149 
00151     int topo_sort();
00152 
00153     // helper function to dfs
00154     void dfs(InitStep* step, ReverseDepEdges& edges);
00155     
00157     void mark_dep(const std::string& target);
00158 
00160     void add_extra_dep(InitExtraDependency* extra_dep);
00161 
00163     void add_extra_deps();
00164 };
00165 
00169 class InitStep {
00170     friend class InitSequencer;
00171 
00172 public:
00173     typedef std::vector<std::string> DepList;
00174 
00178     InitStep(const std::string& the_namespace, const std::string& name);
00179     InitStep(const std::string& the_namespace, 
00180              const std::string& name, int depsize, ...);
00181     InitStep(const std::string& the_namespace, 
00182              const std::string& name, const DepList& deps);
00183 
00184     virtual ~InitStep() {}
00185     
00189     virtual int run();
00190 
00194     bool dep_are_satisfied();
00195     
00196     const DepList& dependencies() { return dependencies_; }
00197     std::string name() { return name_; }
00198     bool        done() { return done_; }
00199     int         time() { return time_; }
00200 
00201 protected:
00202     bool        done_;
00203 
00205     virtual int run_component() = 0;
00206 
00207 private:
00208     std::string name_;
00209     DepList     dependencies_;
00210 
00211     bool mark_;                 // mark for dep checking
00212     int  time_;                 // finishing time for topo-sort
00213 
00214     void add_dep(const std::string& dep) { dependencies_.push_back(dep); }
00215 };
00216 
00222 class InitConfigStep : public InitStep {
00223 public:
00224     InitConfigStep(const std::string& the_namespace,
00225                    const std::string& name) 
00226         : InitStep(the_namespace, name) {}
00227 
00228     int  run()                { return 0; } 
00229     void configuration_done() { done_ = true; }
00230 
00231 protected:
00232     int  run_component()      { NOTREACHED; }
00233 };
00234 
00240 struct InitExtraDependency {
00241     InitExtraDependency(const std::string& new_dep,
00242                         const std::string& depender) 
00243         : new_dep_(new_dep), depender_(depender)
00244     {
00245         Singleton<InitSequencer>::instance()->add_extra_dep(this);
00246     }
00247     
00248     std::string new_dep_;
00249     std::string depender_;
00250 };
00251 
00252 
00254 
00258 #define OASYS_DECLARE_INIT_MODULE_0(_namespace, _name)                  \
00259 class InitModule##_namespace##_name : public ::oasys::InitStep {        \
00260 public:                                                                 \
00261     InitModule##_namespace##_name() : InitStep(#_namespace, #_name) {}  \
00262 protected:                                                              \
00263     int run_component();                                                \
00264 };                                                                      \
00265 InitModule##_namespace##_name *                                         \
00266     ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0;   \
00267 InitModule##_namespace##_name * init_module_##_name =                   \
00268     ::oasys::Singleton<InitModule##_namespace##_name>::instance();      \
00269 int InitModule##_namespace##_name::run_component()
00270 
00271 #define OASYS_DECLARE_INIT_MODULE_1(_namespace, _name, _dep1) \
00272     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 1, _dep1)                 
00273 #define OASYS_DECLARE_INIT_MODULE_2(_namespace, _name, _dep1, _dep2) \
00274     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 2, _dep1, _dep2)
00275 #define OASYS_DECLARE_INIT_MODULE_3(_namespace, _name, _dep1, _dep2, _dep3) \
00276     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 3, _dep1, _dep2, _dep3)
00277 #define OASYS_DECLARE_INIT_MODULE_4(_namespace, _name, _dep1, _dep2, _dep3, _dep4) \
00278     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 4, _dep1, _dep2, _dep3, _dep4)
00280 
00281 
00285 #define OASYS_DECLARE_INIT_MODULE(_namespace, _name, _num_dep, _args...)        \
00286 class InitModule##_namespace##_name : public ::oasys::InitStep {                \
00287 public:                                                                         \
00288     InitModule##_namespace##_name()                                             \
00289         : InitStep(#_namespace, #_name, _num_dep, _args) {}                     \
00290 protected:                                                                      \
00291     int run_component();                                                        \
00292 };                                                                              \
00293 InitModule##_namespace##_name *                                                 \
00294     ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0;           \
00295 InitModule##_namespace##_name * init_module_##_name =                           \
00296     ::oasys::Singleton<InitModule##_namespace##_name>::instance();              \
00297 int InitModule##_namespace##_name::run_component()
00298 
00302 #define OASYS_DECLARE_INIT_CONFIG(_namespace, _name)                    \
00303 class InitModule##_namespace##_name : public InitConfigStep {           \
00304 public:                                                                 \
00305     InitModule##_namespace##_name()                                     \
00306         : InitConfigStep(#_namespace, #_name) {}                        \
00307 };                                                                      \
00308 InitModule##_namespace##_name *                                         \
00309     ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0;   \
00310 InitModule##_namespace##_name * init_module_##_name =                   \
00311     ::oasys::Singleton<InitModule##_namespace##_name>::instance()
00312 
00316 #define OASYS_INIT_CONFIG_DONE(_namespace, _name)                       \
00317 do {                                                                    \
00318     ::oasys::Singleton<InitModule##_namespace##_name>::instance()       \
00319          ->configuration_done();                                        \
00320 } while (0)
00321 
00325 #define OASYS_INIT_ADD_DEP(_new_dep, _depender) \
00326 ::oasys::InitExtraDependency init_extra_dep_##__LINE__(_new_dep, _depender)
00327 
00328 } // namespace oasys
00329 
00330 #endif /* __INITSEQUENCER_H__ */

Generated on Fri Dec 22 14:47:59 2006 for DTN Reference Implementation by  doxygen 1.5.1