subsystem_mgr.cxx

00001 
00002 #include <simgear/debug/logstream.hxx>
00003 #include <simgear/timing/timestamp.hxx>
00004 
00005 #include "exception.hxx"
00006 #include "subsystem_mgr.hxx"
00007 
00008 
00009 
00011 // Implementation of SGSubsystem
00013 
00014 
00015 SGSubsystem::SGSubsystem ()
00016   : _suspended(false)
00017 {
00018 }
00019 
00020 SGSubsystem::~SGSubsystem ()
00021 {
00022 }
00023 
00024 void
00025 SGSubsystem::init ()
00026 {
00027 }
00028 
00029 void
00030 SGSubsystem::postinit ()
00031 {
00032 }
00033 
00034 void
00035 SGSubsystem::reinit ()
00036 {
00037 }
00038 
00039 void
00040 SGSubsystem::bind ()
00041 {
00042 }
00043 
00044 void
00045 SGSubsystem::unbind ()
00046 {
00047 }
00048 
00049 void
00050 SGSubsystem::suspend ()
00051 {
00052   _suspended = true;
00053 }
00054 
00055 void
00056 SGSubsystem::suspend (bool suspended)
00057 {
00058   _suspended = suspended;
00059 }
00060 
00061 void
00062 SGSubsystem::resume ()
00063 {
00064   _suspended = false;
00065 }
00066 
00067 bool
00068 SGSubsystem::is_suspended () const
00069 {
00070   return _suspended;
00071 }
00072 
00073 
00074 void
00075 SGSubsystem::printTimingInformation ()
00076 {
00077   SGTimeStamp startTime, endTime;
00078    long duration;
00079    for ( eventTimeVecIterator i = timingInfo.begin();
00080           i != timingInfo.end();
00081           i++) {
00082        if (i == timingInfo.begin()) {
00083            startTime = i->getTime();
00084        } else {
00085            endTime = i->getTime();
00086            duration = (endTime - startTime);
00087            startTime = endTime;
00088            SG_LOG(SG_GENERAL, SG_ALERT, "- Getting to timestamp :   " << i->getName() << " takes " << duration << " usec.");
00089        }
00090    }
00091 }
00092 
00093 
00094 
00095 void SGSubsystem::stamp(string name)
00096 {
00097     SGTimeStamp now;
00098     now.stamp();
00099     timingInfo.push_back(TimingInfo(name, now));
00100 }
00101 
00102 
00104 // Implementation of SGSubsystemGroup.
00106 
00107 SGSubsystemGroup::SGSubsystemGroup ()
00108 {
00109 }
00110 
00111 SGSubsystemGroup::~SGSubsystemGroup ()
00112 {
00113     for (unsigned int i = 0; i < _members.size(); i++)
00114     {
00115         _members[i]->printTimingStatistics();
00116         delete _members[i];
00117     }
00118 }
00119 
00120 void
00121 SGSubsystemGroup::init ()
00122 {
00123     for (unsigned int i = 0; i < _members.size(); i++)
00124         _members[i]->subsystem->init();
00125 }
00126 
00127 void
00128 SGSubsystemGroup::postinit ()
00129 {
00130     for (unsigned int i = 0; i < _members.size(); i++)
00131         _members[i]->subsystem->postinit();
00132 }
00133 
00134 void
00135 SGSubsystemGroup::reinit ()
00136 {
00137     for (unsigned int i = 0; i < _members.size(); i++)
00138         _members[i]->subsystem->reinit();
00139 }
00140 
00141 void
00142 SGSubsystemGroup::bind ()
00143 {
00144     for (unsigned int i = 0; i < _members.size(); i++)
00145         _members[i]->subsystem->bind();
00146 }
00147 
00148 void
00149 SGSubsystemGroup::unbind ()
00150 {
00151     for (unsigned int i = 0; i < _members.size(); i++)
00152         _members[i]->subsystem->unbind();
00153 }
00154 
00155 void
00156 SGSubsystemGroup::update (double delta_time_sec)
00157 {
00158     for (unsigned int i = 0; i < _members.size(); i++)
00159     {
00160          SGTimeStamp start, now;
00161          start.stamp();
00162          _members[i]->update(delta_time_sec); // indirect call
00163          now.stamp();
00164          long b = ( now - start );
00165          _members[i]->updateExecutionTime(b);
00166          double threshold = _members[i]->getTimeWarningThreshold();
00167          if (( b > threshold ) && (b > 10000)) {
00168              _members[i]->printTimingInformation(b);
00169          }
00170     }
00171 }
00172 
00173 void 
00174 SGSubsystemGroup::collectDebugTiming(bool collect)
00175 {
00176     for (unsigned int i = 0; i < _members.size(); i++)
00177     {
00178         _members[i]->collectDebugTiming(collect);
00179     }
00180 }
00181 
00182 void
00183 SGSubsystemGroup::suspend ()
00184 {
00185     for (unsigned int i = 0; i < _members.size(); i++)
00186         _members[i]->subsystem->suspend();
00187 }
00188 
00189 void
00190 SGSubsystemGroup::resume ()
00191 {
00192     for (unsigned int i = 0; i < _members.size(); i++)
00193         _members[i]->subsystem->resume();
00194 }
00195 
00196 bool
00197 SGSubsystemGroup::is_suspended () const
00198 {
00199     return false;
00200 }
00201 
00202 void
00203 SGSubsystemGroup::set_subsystem (const string &name, SGSubsystem * subsystem,
00204                                  double min_step_sec)
00205 {
00206     Member * member = get_member(name, true);
00207     if (member->subsystem != 0)
00208         delete member->subsystem;
00209     member->name = name;
00210     member->subsystem = subsystem;
00211     member->min_step_sec = min_step_sec;
00212 }
00213 
00214 SGSubsystem *
00215 SGSubsystemGroup::get_subsystem (const string &name)
00216 {
00217     Member * member = get_member(name);
00218     if (member != 0)
00219         return member->subsystem;
00220     else
00221         return 0;
00222 }
00223 
00224 void
00225 SGSubsystemGroup::remove_subsystem (const string &name)
00226 {
00227     for (unsigned int i = 0; i < _members.size(); i++) {
00228         if (name == _members[i]->name) {
00229             _members.erase(_members.begin() + i);
00230             return;
00231         }
00232     }
00233 }
00234 
00235 void
00236 SGSubsystemGroup::Member::printTimingStatistics ()
00237 {
00238     if (collectTimeStats) {
00239         double minTime = timeStat.min()   / 1000;
00240         double maxTime = timeStat.max()   / 1000;
00241         double meanTime = timeStat.mean() / 1000;
00242         double stddev   = timeStat.stdDev()   / 1000;
00243 
00244         char buffer[256];
00245         snprintf(buffer, 256, "Timing summary for %20s.\n"
00246                               "-  mean time: %04.2f ms.\n"
00247                               "-  min time : %04.2f ms.\n"
00248                               "-  max time : %04.2f ms.\n"
00249                               "- stddev    : %04.2f ms.\n", name.c_str(), meanTime, minTime, maxTime, stddev);
00250         SG_LOG(SG_GENERAL, SG_ALERT, buffer);
00251     }
00252 }
00253 
00254 
00255 bool
00256 SGSubsystemGroup::has_subsystem (const string &name) const
00257 {
00258     return (((SGSubsystemGroup *)this)->get_member(name) != 0);
00259 }
00260 
00261 SGSubsystemGroup::Member *
00262 SGSubsystemGroup::get_member (const string &name, bool create)
00263 {
00264     for (unsigned int i = 0; i < _members.size(); i++) {
00265         if (_members[i]->name == name)
00266             return _members[i];
00267     }
00268     if (create) {
00269         Member * member = new Member;
00270         _members.push_back(member);
00271         return member;
00272     } else {
00273         return 0;
00274     }
00275 }
00276 
00277 
00278 
00280 // Implementation of SGSubsystemGroup::Member
00282 
00283 
00284 SGSubsystemGroup::Member::Member ()
00285     : name(""),
00286       subsystem(0),
00287       min_step_sec(0),
00288       elapsed_sec(0),
00289       collectTimeStats(false)
00290 {
00291 }
00292 
00293 SGSubsystemGroup::Member::Member (const Member &)
00294 {
00295     Member();
00296 }
00297 
00298 SGSubsystemGroup::Member::~Member ()
00299 {
00300     delete subsystem;
00301 }
00302 
00303 void
00304 SGSubsystemGroup::Member::update (double delta_time_sec)
00305 {
00306     elapsed_sec += delta_time_sec;
00307     if (elapsed_sec >= min_step_sec) {
00308         if (!subsystem->is_suspended()) {
00309             subsystem->update(elapsed_sec);
00310             elapsed_sec = 0;
00311         }
00312     }
00313 }
00314 
00315 
00316 void 
00317 SGSubsystemGroup::Member::printTimingInformation(double time)
00318 {
00319      if (collectTimeStats) {
00320          SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem Timing Alert : " << time << " " << name);
00321          subsystem->printTimingInformation();
00322      }
00323 }
00324 
00325 double SGSubsystemGroup::Member::getTimeWarningThreshold()
00326 {
00327     return (timeStat.mean() + 3 * timeStat.stdDev());
00328 }
00329 
00330 void SGSubsystemGroup::Member::updateExecutionTime(double time)
00331 {
00332     if (collectTimeStats) {
00333         timeStat += time;
00334     }
00335 }
00336 
00337 
00338 
00339 
00340 
00342 // Implementation of SGSubsystemMgr.
00344 
00345 
00346 SGSubsystemMgr::SGSubsystemMgr ()
00347 {
00348 }
00349 
00350 SGSubsystemMgr::~SGSubsystemMgr ()
00351 {
00352 }
00353 
00354 void
00355 SGSubsystemMgr::init ()
00356 {
00357     for (int i = 0; i < MAX_GROUPS; i++)
00358             _groups[i].init();
00359 }
00360 
00361 void
00362 SGSubsystemMgr::postinit ()
00363 {
00364     for (int i = 0; i < MAX_GROUPS; i++)
00365             _groups[i].postinit();
00366 }
00367 
00368 void
00369 SGSubsystemMgr::reinit ()
00370 {
00371     for (int i = 0; i < MAX_GROUPS; i++)
00372             _groups[i].reinit();
00373 }
00374 
00375 void
00376 SGSubsystemMgr::bind ()
00377 {
00378     for (int i = 0; i < MAX_GROUPS; i++)
00379         _groups[i].bind();
00380 }
00381 
00382 void
00383 SGSubsystemMgr::unbind ()
00384 {
00385     for (int i = 0; i < MAX_GROUPS; i++)
00386         _groups[i].unbind();
00387 }
00388 
00389 void
00390 SGSubsystemMgr::update (double delta_time_sec)
00391 {
00392     for (int i = 0; i < MAX_GROUPS; i++) {
00393         _groups[i].update(delta_time_sec);
00394     }
00395 }
00396 
00397 void 
00398 SGSubsystemMgr::collectDebugTiming(bool collect)
00399 {
00400     for (int i = 0; i < MAX_GROUPS; i++) {
00401         _groups[i].collectDebugTiming(collect);
00402     }
00403 }
00404 
00405 void
00406 SGSubsystemMgr::suspend ()
00407 {
00408     for (int i = 0; i < MAX_GROUPS; i++)
00409         _groups[i].suspend();
00410 }
00411 
00412 void
00413 SGSubsystemMgr::resume ()
00414 {
00415     for (int i = 0; i < MAX_GROUPS; i++)
00416         _groups[i].resume();
00417 }
00418 
00419 bool
00420 SGSubsystemMgr::is_suspended () const
00421 {
00422     return false;
00423 }
00424 
00425 void
00426 SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem,
00427                      GroupType group, double min_time_sec)
00428 {
00429     SG_LOG(SG_GENERAL, SG_INFO, "Adding subsystem " << name);
00430     get_group(group)->set_subsystem(name, subsystem, min_time_sec);
00431 
00432     if (_subsystem_map.find(name) != _subsystem_map.end()) {
00433         SG_LOG(SG_GENERAL, SG_ALERT, "Adding duplicate subsystem " << name);
00434         throw sg_exception("duplicate subsystem");
00435     }
00436     _subsystem_map[name] = subsystem;
00437 }
00438 
00439 SGSubsystemGroup *
00440 SGSubsystemMgr::get_group (GroupType group)
00441 {
00442     return &(_groups[group]);
00443 }
00444 
00445 SGSubsystem *
00446 SGSubsystemMgr::get_subsystem (const string &name)
00447 {
00448     map<string,SGSubsystem *>::iterator s =_subsystem_map.find(name);
00449 
00450     if (s == _subsystem_map.end())
00451         return 0;
00452     else
00453         return s->second;
00454 }
00455 
00456 // end of fgfs.cxx

Generated on Mon Dec 17 09:30:56 2007 for SimGear by  doxygen 1.5.1