profiler.h
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2008, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 
00036 /* Author Ioan Sucan */
00037 
00038 #ifndef MOVEIT_PROFILER_
00039 #define MOVEIT_PROFILER_
00040 
00041 #define MOVEIT_ENABLE_PROFILING 1
00042 
00043 #ifndef MOVEIT_ENABLE_PROFILING
00044 
00048 #  ifdef NDEBUG
00049 #    define MOVEIT_ENABLE_PROFILING 0
00050 #  else
00051 #    define MOVEIT_ENABLE_PROFILING 1
00052 #  endif
00053 
00054 #endif
00055 
00056 #if MOVEIT_ENABLE_PROFILING
00057 
00058 #include <map>
00059 #include <string>
00060 #include <iostream>
00061 #include <boost/thread.hpp>
00062 #include <boost/noncopyable.hpp>
00063 #include <boost/date_time/posix_time/posix_time.hpp>
00064 
00065 namespace moveit
00066 {
00067 
00073 class Profiler : private boost::noncopyable
00074 {
00075 public:
00076 
00078   class ScopedBlock
00079   {
00080   public:
00082     ScopedBlock(const std::string &name, Profiler &prof = Profiler::Instance()) : name_(name), prof_(prof)
00083     {
00084       prof_.begin(name);
00085     }
00086 
00087     ~ScopedBlock(void)
00088     {
00089       prof_.end(name_);
00090     }
00091 
00092   private:
00093 
00094     std::string  name_;
00095     Profiler    &prof_;
00096   };
00097 
00100   class ScopedStart
00101   {
00102   public:
00103 
00105     ScopedStart(Profiler &prof = Profiler::Instance()) : prof_(prof), wasRunning_(prof_.running())
00106     {
00107       if (!wasRunning_)
00108         prof_.start();
00109     }
00110 
00111     ~ScopedStart(void)
00112     {
00113       if (!wasRunning_)
00114         prof_.stop();
00115     }
00116 
00117   private:
00118 
00119     Profiler &prof_;
00120     bool      wasRunning_;
00121   };
00122 
00124   static Profiler& Instance(void);
00125 
00128   Profiler(bool printOnDestroy = false, bool autoStart = false) : running_(false), printOnDestroy_(printOnDestroy)
00129   {
00130     if (autoStart)
00131       start();
00132   }
00133 
00135   ~Profiler(void)
00136   {
00137     if (printOnDestroy_ && !data_.empty())
00138       status();
00139   }
00140 
00142   static void Start(void)
00143   {
00144     Instance().start();
00145   }
00146 
00148   static void Stop(void)
00149   {
00150     Instance().stop();
00151   }
00152 
00154   static void Clear(void)
00155   {
00156     Instance().clear();
00157   }
00158 
00160   void start(void);
00161 
00163   void stop(void);
00164 
00166   void clear(void);
00167 
00169   static void Event(const std::string& name, const unsigned int times = 1)
00170   {
00171     Instance().event(name, times);
00172   }
00173 
00175   void event(const std::string &name, const unsigned int times = 1);
00176 
00178   static void Average(const std::string& name, const double value)
00179   {
00180     Instance().average(name, value);
00181   }
00182 
00184   void average(const std::string &name, const double value);
00185 
00187   static void Begin(const std::string &name)
00188   {
00189     Instance().begin(name);
00190   }
00191 
00193   static void End(const std::string &name)
00194   {
00195     Instance().end(name);
00196   }
00197 
00199   void begin(const std::string &name);
00200 
00202   void end(const std::string &name);
00203 
00207   static void Status(std::ostream &out = std::cout, bool merge = true)
00208   {
00209     Instance().status(out, merge);
00210   }
00211 
00215   void status(std::ostream &out = std::cout, bool merge = true);
00216 
00219   static void Console(void)
00220   {
00221     Instance().console();
00222   }
00223 
00226   void console(void);
00227 
00229   bool running(void) const
00230   {
00231     return running_;
00232   }
00233 
00235   static bool Running(void)
00236   {
00237     return Instance().running();
00238   }
00239 
00240 private:
00241 
00243   struct TimeInfo
00244   {
00245     TimeInfo(void) : total(0, 0, 0, 0), shortest(boost::posix_time::pos_infin), longest(boost::posix_time::neg_infin), parts(0)
00246     {
00247     }
00248 
00250     boost::posix_time::time_duration total;
00251 
00253     boost::posix_time::time_duration shortest;
00254 
00256     boost::posix_time::time_duration longest;
00257 
00259     unsigned long int parts;
00260 
00262     boost::posix_time::ptime start;
00263 
00265     void set(void)
00266     {
00267       start = boost::posix_time::microsec_clock::universal_time();
00268     }
00269 
00271     void update(void)
00272     {
00273       const boost::posix_time::time_duration &dt = boost::posix_time::microsec_clock::universal_time() - start;
00274       if (dt > longest)
00275         longest = dt;
00276       if (dt < shortest)
00277         shortest = dt;
00278       total = total + dt;
00279       ++parts;
00280     }
00281   };
00282 
00284   struct AvgInfo
00285   {
00287     double            total;
00288 
00290     double            totalSqr;
00291 
00293     unsigned long int parts;
00294   };
00295 
00297   struct PerThread
00298   {
00300     std::map<std::string, unsigned long int> events;
00301 
00303     std::map<std::string, AvgInfo>           avg;
00304 
00306     std::map<std::string, TimeInfo>          time;
00307   };
00308 
00309   void printThreadInfo(std::ostream &out, const PerThread &data);
00310 
00311   boost::mutex                           lock_;
00312   std::map<boost::thread::id, PerThread> data_;
00313   TimeInfo                               tinfo_;
00314   bool                                   running_;
00315   bool                                   printOnDestroy_;
00316 
00317 };
00318 }
00319 
00320 #else
00321 
00322 #include <string>
00323 #include <iostream>
00324 
00325 /* If profiling is disabled, provide empty implementations for the
00326    public functions */
00327 namespace moveit
00328 {
00329 
00330 class Profiler
00331 {
00332 public:
00333 
00334   class ScopedBlock
00335   {
00336   public:
00337 
00338     ScopedBlock(const std::string &, Profiler & = Profiler::Instance())
00339     {
00340     }
00341 
00342     ~ScopedBlock(void)
00343     {
00344     }
00345   };
00346 
00347   class ScopedStart
00348   {
00349   public:
00350 
00351     ScopedStart(Profiler & = Profiler::Instance())
00352     {
00353     }
00354 
00355     ~ScopedStart(void)
00356     {
00357     }
00358   };
00359 
00360   static Profiler& Instance(void);
00361 
00362   Profiler(bool = true, bool = true)
00363   {
00364   }
00365 
00366   ~Profiler(void)
00367   {
00368   }
00369 
00370   static void Start(void)
00371   {
00372   }
00373 
00374   static void Stop(void)
00375   {
00376   }
00377 
00378   static void Clear(void)
00379   {
00380   }
00381 
00382   void start(void)
00383   {
00384   }
00385 
00386   void stop(void)
00387   {
00388   }
00389 
00390   void clear(void)
00391   {
00392   }
00393 
00394   static void Event(const std::string&, const unsigned int = 1)
00395   {
00396   }
00397 
00398   void event(const std::string &, const unsigned int = 1)
00399   {
00400   }
00401 
00402   static void Average(const std::string&, const double)
00403   {
00404   }
00405 
00406   void average(const std::string &, const double)
00407   {
00408   }
00409 
00410   static void Begin(const std::string &)
00411   {
00412   }
00413 
00414   static void End(const std::string &)
00415   {
00416   }
00417 
00418   void begin(const std::string &)
00419   {
00420   }
00421 
00422   void end(const std::string &)
00423   {
00424   }
00425 
00426   static void Status(std::ostream & = std::cout, bool = true)
00427   {
00428   }
00429 
00430   void status(std::ostream & = std::cout, bool = true)
00431   {
00432   }
00433 
00434   static void Console(void)
00435   {
00436   }
00437 
00438   void console(void)
00439   {
00440   }
00441 
00442   bool running(void) const
00443   {
00444     return false;
00445   }
00446 
00447   static bool Running(void)
00448   {
00449     return false;
00450   }
00451 };
00452 
00453 }
00454 
00455 #endif
00456 
00457 #endif


moveit_core
Author(s): Ioan Sucan , Sachin Chitta , Acorn Pooley
autogenerated on Mon Oct 6 2014 02:24:47