InitSequencer.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 #ifndef __INITSEQUENCER_H__
00018 #define __INITSEQUENCER_H__
00019 
00020 #include <vector>
00021 #include <map>
00022 #include <string>
00023 
00024 #include "../util/Singleton.h"
00025 #include "../debug/Logger.h"
00026 
00027 namespace oasys {
00028 
00029 // predecl
00030 class InitStep;
00031 class InitExtraDependency;
00032 
00077 class InitSequencer : public Logger {
00078     friend class InitExtraDependency;
00079 
00080 public:
00081     typedef std::map<std::string, InitStep*> StepMap;
00082     typedef std::vector<std::string>         Plan;
00083 
00084     InitSequencer();
00085 
00093     int start(std::string step, Plan* plan = 0);
00094 
00098     void add_step(InitStep* step);
00099 
00103     InitStep* get_step(const std::string& name);
00104 
00110     void reset();
00111 
00115     void print_dot();
00116 
00117 private:
00118     typedef std::vector<std::string>              ReverseDepList;
00119     typedef std::map<std::string, ReverseDepList> ReverseDepEdges;
00120     
00121     StepMap steps_;
00122     int     dfs_time_;
00123 
00124     std::vector<InitExtraDependency*> extra_dependencies_;
00125 
00127     int run_steps();
00128 
00130     int topo_sort();
00131 
00132     // helper function to dfs
00133     void dfs(InitStep* step, ReverseDepEdges& edges);
00134     
00136     void mark_dep(const std::string& target);
00137 
00139     void add_extra_dep(InitExtraDependency* extra_dep);
00140 
00142     void add_extra_deps();
00143 };
00144 
00148 class InitStep {
00149     friend class InitSequencer;
00150 
00151 public:
00152     typedef std::vector<std::string> DepList;
00153 
00157     InitStep(const std::string& the_namespace, const std::string& name);
00158     InitStep(const std::string& the_namespace, 
00159              const std::string& name, int depsize, ...);
00160     InitStep(const std::string& the_namespace, 
00161              const std::string& name, const DepList& deps);
00162 
00163     virtual ~InitStep() {}
00164     
00168     virtual int run();
00169 
00173     bool dep_are_satisfied();
00174     
00175     const DepList& dependencies() { return dependencies_; }
00176     std::string name() { return name_; }
00177     bool        done() { return done_; }
00178     int         time() { return time_; }
00179 
00180 protected:
00181     bool        done_;
00182 
00184     virtual int run_component() = 0;
00185 
00186 private:
00187     std::string name_;
00188     DepList     dependencies_;
00189 
00190     bool mark_;                 // mark for dep checking
00191     int  time_;                 // finishing time for topo-sort
00192 
00193     void add_dep(const std::string& dep) { dependencies_.push_back(dep); }
00194 };
00195 
00201 class InitConfigStep : public InitStep {
00202 public:
00203     InitConfigStep(const std::string& the_namespace,
00204                    const std::string& name) 
00205         : InitStep(the_namespace, name) {}
00206 
00207     int  run()                { return 0; } 
00208     void configuration_done() { done_ = true; }
00209 
00210 protected:
00211     int  run_component()      { NOTREACHED; }
00212 };
00213 
00219 struct InitExtraDependency {
00220     InitExtraDependency(const std::string& new_dep,
00221                         const std::string& depender) 
00222         : new_dep_(new_dep), depender_(depender)
00223     {
00224         Singleton<InitSequencer>::instance()->add_extra_dep(this);
00225     }
00226     
00227     std::string new_dep_;
00228     std::string depender_;
00229 };
00230 
00231 
00233 
00237 #define OASYS_DECLARE_INIT_MODULE_0(_namespace, _name)                  \
00238 class InitModule##_namespace##_name : public ::oasys::InitStep {        \
00239 public:                                                                 \
00240     InitModule##_namespace##_name() : InitStep(#_namespace, #_name) {}  \
00241 protected:                                                              \
00242     int run_component();                                                \
00243 };                                                                      \
00244 InitModule##_namespace##_name *                                         \
00245     ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0;   \
00246 InitModule##_namespace##_name * init_module_##_name =                   \
00247     ::oasys::Singleton<InitModule##_namespace##_name>::instance();      \
00248 int InitModule##_namespace##_name::run_component()
00249 
00250 #define OASYS_DECLARE_INIT_MODULE_1(_namespace, _name, _dep1) \
00251     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 1, _dep1)                 
00252 #define OASYS_DECLARE_INIT_MODULE_2(_namespace, _name, _dep1, _dep2) \
00253     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 2, _dep1, _dep2)
00254 #define OASYS_DECLARE_INIT_MODULE_3(_namespace, _name, _dep1, _dep2, _dep3) \
00255     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 3, _dep1, _dep2, _dep3)
00256 #define OASYS_DECLARE_INIT_MODULE_4(_namespace, _name, _dep1, _dep2, _dep3, _dep4) \
00257     OASYS_DECLARE_INIT_MODULE(_namespace, _name, 4, _dep1, _dep2, _dep3, _dep4)
00259 
00260 
00264 #define OASYS_DECLARE_INIT_MODULE(_namespace, _name, _num_dep, _args...)        \
00265 class InitModule##_namespace##_name : public ::oasys::InitStep {                \
00266 public:                                                                         \
00267     InitModule##_namespace##_name()                                             \
00268         : InitStep(#_namespace, #_name, _num_dep, _args) {}                     \
00269 protected:                                                                      \
00270     int run_component();                                                        \
00271 };                                                                              \
00272 InitModule##_namespace##_name *                                                 \
00273     ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0;           \
00274 InitModule##_namespace##_name * init_module_##_name =                           \
00275     ::oasys::Singleton<InitModule##_namespace##_name>::instance();              \
00276 int InitModule##_namespace##_name::run_component()
00277 
00281 #define OASYS_DECLARE_INIT_CONFIG(_namespace, _name)                    \
00282 class InitModule##_namespace##_name : public InitConfigStep {           \
00283 public:                                                                 \
00284     InitModule##_namespace##_name()                                     \
00285         : InitConfigStep(#_namespace, #_name) {}                        \
00286 };                                                                      \
00287 InitModule##_namespace##_name *                                         \
00288     ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0;   \
00289 InitModule##_namespace##_name * init_module_##_name =                   \
00290     ::oasys::Singleton<InitModule##_namespace##_name>::instance()
00291 
00295 #define OASYS_INIT_CONFIG_DONE(_namespace, _name)                       \
00296 do {                                                                    \
00297     ::oasys::Singleton<InitModule##_namespace##_name>::instance()       \
00298          ->configuration_done();                                        \
00299 } while (0)
00300 
00304 #define OASYS_INIT_ADD_DEP(_new_dep, _depender) \
00305 ::oasys::InitExtraDependency init_extra_dep_##__LINE__(_new_dep, _depender)
00306 
00307 } // namespace oasys
00308 
00309 #endif /* __INITSEQUENCER_H__ */

Generated on Sat Sep 8 08:43:28 2007 for DTN Reference Implementation by  doxygen 1.5.3