All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
Profiler.h
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 OMPL_UTIL_PROFILER_
00039 #define OMPL_UTIL_PROFILER_
00040 
00041 #define ENABLE_PROFILING 1
00042 
00043 #ifndef ENABLE_PROFILING
00044 
00048 #  ifdef NDEBUG
00049 #    define ENABLE_PROFILING 0
00050 #  else
00051 #    define ENABLE_PROFILING 1
00052 #  endif
00053 
00054 #endif
00055 
00056 #if ENABLE_PROFILING
00057 
00058 #include <map>
00059 #include <string>
00060 #include <iostream>
00061 #include <boost/thread.hpp>
00062 #include <boost/noncopyable.hpp>
00063 
00064 #include "ompl/util/Time.h"
00065 
00066 namespace ompl
00067 {
00068 
00075     class Profiler : private boost::noncopyable
00076     {
00077     public:
00078 
00080         class BeginBlock
00081         {
00082         public:
00083 
00084             BeginBlock(const std::string &name, Profiler &prof = Profiler::Instance()) : name_(name), prof_(prof)
00085             {
00086                 prof_.begin(name);
00087             }
00088 
00089             ~BeginBlock(void)
00090             {
00091                 prof_.end(name_);
00092             }
00093 
00094         private:
00095 
00096             std::string  name_;
00097             Profiler    &prof_;
00098         };
00099 
00101         static Profiler& Instance(void);
00102 
00105         Profiler(bool printOnDestroy = false, bool autoStart = false) : running_(false), printOnDestroy_(printOnDestroy)
00106         {
00107             if (autoStart)
00108                 start();
00109         }
00110 
00112         ~Profiler(void)
00113         {
00114             if (printOnDestroy_ && !data_.empty())
00115                 console();
00116         }
00117 
00119         static void Start(void)
00120         {
00121             Instance().start();
00122         }
00123 
00125         static void Stop(void)
00126         {
00127             Instance().stop();
00128         }
00129 
00131         static void Clear(void)
00132         {
00133             Instance().clear();
00134         }
00135 
00137         void start(void);
00138 
00140         void stop(void);
00141 
00143         void clear(void);
00144 
00146         static void Event(const std::string& name, const unsigned int times = 1)
00147         {
00148             Instance().event(name, times);
00149         }
00150 
00152         void event(const std::string &name, const unsigned int times = 1);
00153 
00155         static void Begin(const std::string &name)
00156         {
00157             Instance().begin(name);
00158         }
00159 
00161         static void End(const std::string &name)
00162         {
00163             Instance().end(name);
00164         }
00165 
00167         void begin(const std::string &name);
00168 
00170         void end(const std::string &name);
00171 
00175         static void Status(std::ostream &out = std::cout, bool merge = true)
00176         {
00177             Instance().status(out, merge);
00178         }
00179 
00183         void status(std::ostream &out = std::cout, bool merge = true);
00184 
00187         static void Console(void)
00188         {
00189             Instance().console();
00190         }
00191 
00194         void console(void);
00195 
00196     private:
00197 
00199         struct TimeInfo
00200         {
00201             TimeInfo(void) : total(0, 0, 0, 0), shortest(boost::posix_time::pos_infin), longest(boost::posix_time::neg_infin), parts(0)
00202             {
00203             }
00204 
00206             time::duration    total;
00207 
00209             time::duration    shortest;
00210 
00212             time::duration    longest;
00213 
00215             unsigned long int parts;
00216 
00218             time::point       start;
00219 
00221             void set(void)
00222             {
00223                 start = time::now();
00224             }
00225 
00227             void update(void)
00228             {
00229                 const time::duration &dt = time::now() - start;
00230                 if (dt > longest)
00231                     longest = dt;
00232                 if (dt < shortest)
00233                     shortest = dt;
00234                 total = total + dt;
00235                 ++parts;
00236             }
00237         };
00238 
00240         struct PerThread
00241         {
00243             std::map<std::string, unsigned long int> events;
00244 
00246             std::map<std::string, TimeInfo>          time;
00247         };
00248 
00249         void printThreadInfo(std::ostream &out, const PerThread &data);
00250 
00251         boost::mutex                           lock_;
00252         std::map<boost::thread::id, PerThread> data_;
00253         TimeInfo                               tinfo_;
00254         bool                                   running_;
00255         bool                                   printOnDestroy_;
00256 
00257     };
00258 }
00259 
00260 #else
00261 
00262 #include <string>
00263 #include <iostream>
00264 
00265 /* If profiling is disabled, provide empty implementations for the
00266    public functions */
00267 namespace ompl
00268 {
00269 
00270     class Profiler
00271     {
00272     public:
00273 
00274         class BeginBlock
00275         {
00276         public:
00277 
00278             BeginBlock(const std::string &, Profiler & = Profiler::Instance())
00279             {
00280             }
00281 
00282             ~BeginBlock(void)
00283             {
00284             }
00285         };
00286 
00287         static Profiler& Instance(void);
00288 
00289         Profiler(bool = true, bool = true)
00290         {
00291         }
00292 
00293         ~Profiler(void)
00294         {
00295         }
00296 
00297         static void Start(void)
00298         {
00299         }
00300 
00301         static void Stop(void)
00302         {
00303         }
00304 
00305         static void Clear(void)
00306         {
00307         }
00308 
00309         void start(void)
00310         {
00311         }
00312 
00313         void stop(void)
00314         {
00315         }
00316 
00317         void clear(void)
00318         {
00319         }
00320 
00321         static void Event(const std::string&, const unsigned int = 1)
00322         {
00323         }
00324 
00325         void event(const std::string &, const unsigned int = 1)
00326         {
00327         }
00328 
00329         static void Begin(const std::string &)
00330         {
00331         }
00332 
00333         static void End(const std::string &)
00334         {
00335         }
00336 
00337         void begin(const std::string &)
00338         {
00339         }
00340 
00341         void end(const std::string &)
00342         {
00343         }
00344 
00345         static void Status(std::ostream & = std::cout, bool = true)
00346         {
00347         }
00348 
00349         void status(std::ostream & = std::cout, bool = true)
00350         {
00351         }
00352 
00353         static void Console(void)
00354         {
00355         }
00356 
00357         void console(void)
00358         {
00359         }
00360 
00361     };
00362 }
00363 
00364 #endif
00365 
00366 
00367 #endif