libzypp  10.5.0
Measure.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 extern "C"
00013 {
00014 #include <sys/times.h>
00015 #include <unistd.h>
00016 }
00017 #include <iostream>
00018 
00019 #include "zypp/base/Logger.h"
00020 #include "zypp/base/Measure.h"
00021 #include "zypp/base/String.h"
00022 
00023 using std::endl;
00024 
00025 #undef ZYPP_BASE_LOGGER_LOGGROUP
00026 #define ZYPP_BASE_LOGGER_LOGGROUP "Measure"
00027 
00029 namespace zypp
00030 { 
00031 
00032   namespace debug
00033   { 
00034 
00036       struct Tm
00037       {
00038         Tm()
00039         : _real( 0 )
00040         , _proc( tmsEmpty )
00041         {}
00042 
00043         void get()
00044         {
00045           _real = ::time(NULL);
00046           ::times( &_proc );
00047         }
00048 
00049         Tm operator-( const Tm & rhs ) const
00050         {
00051           Tm ret( *this );
00052           ret._real -= rhs._real;
00053           ret._proc.tms_utime -= rhs._proc.tms_utime;
00054           ret._proc.tms_stime -= rhs._proc.tms_stime;
00055           ret._proc.tms_cutime -= rhs._proc.tms_cutime;
00056           ret._proc.tms_cstime -= rhs._proc.tms_cstime;
00057           return ret;
00058         }
00059 
00060         std::string asString() const
00061         {
00062           std::string ret( timeStr( _real ) );
00063           ret += " (u ";
00064           ret += timeStr( asSec( _proc.tms_utime ) );
00065           ret += " s ";
00066           ret += timeStr( asSec( _proc.tms_stime ) );
00067           ret += " c ";
00068           ret += timeStr( asSec( _proc.tms_cutime + _proc.tms_cstime ) );
00069           ret += ")";
00070           return ret;
00071         }
00072 
00073         std::string stringIf( clock_t ticks_r, const std::string & tag_r ) const
00074         {
00075           std::string ret;
00076           if ( ticks_r )
00077             {
00078               ret += tag_r;
00079               ret += timeStr( asSec( ticks_r ) );
00080             }
00081           return ret;
00082         }
00083 
00084         double asSec( clock_t ticks_r ) const
00085         { return double(ticks_r) / ticks; }
00086 
00087         std::string timeStr( time_t sec_r ) const
00088         {
00089           time_t h = sec_r/3600;
00090           sec_r -= h*3600;
00091           time_t m = sec_r/60;
00092           sec_r -= m*60;
00093           if ( h )
00094             return str::form( "%lu:%02lu:%02lu", h, m, sec_r );
00095           if ( m )
00096             return str::form( "%lu:%02lu", m, sec_r );
00097           return str::form( "%lu", sec_r );
00098         }
00099 
00100         std::string timeStr( double sec_r ) const
00101         {
00102           time_t h = time_t(sec_r)/3600;
00103           sec_r -= h*3600;
00104           time_t m = time_t(sec_r)/60;
00105           sec_r -= m*60;
00106           if ( h )
00107             return str::form( "%lu:%02lu:%05.2lf", h, m, sec_r );
00108           if ( m )
00109             return str::form( "%lu:%05.2lf", m, sec_r );
00110           return str::form( "%.2lf", sec_r );
00111         }
00112 
00114         static const long ticks;
00116         static const struct tms tmsEmpty;
00118         time_t      _real;
00120         struct tms  _proc;
00121       };
00122 
00123       const struct tms Tm::tmsEmpty = { 0, 0, 0, 0 };
00124       const long Tm::ticks = sysconf(_SC_CLK_TCK);
00125 
00127       std::ostream & operator<<( std::ostream & str, const Tm & obj )
00128       {
00129         return str << obj.asString();
00130       }
00131 
00132       
00134     //
00135     //  CLASS NAME : Measure::Impl
00136     //
00138     class Measure::Impl
00139     {
00140     public:
00141       Impl( const std::string & ident_r )
00142       : _ident  ( ident_r )
00143       , _seq    ( 0 )
00144       {
00145         INT << "START MEASURE(" << _ident << ")" << endl;
00146         _start.get();
00147       }
00148 
00149       ~Impl()
00150       {
00151         _stop.get();
00152         ++_seq;
00153         std::ostream & str( INT << "MEASURE(" << _ident << ") " );
00154         dumpMeasure( str );
00155       }
00156 
00157       void restart()
00158       {
00159         INT << "RESTART MEASURE(" << _ident << ")" << endl;
00160         _start = _stop;
00161       }
00162       
00163       void elapsed() const
00164       {
00165         _stop.get();
00166         ++_seq;
00167         std::ostream & str( INT << "ELAPSED(" << _ident << ") " );
00168         dumpMeasure( str );
00169         _elapsed = _stop;
00170       }
00171 
00172     private:
00173       std::ostream & dumpMeasure( std::ostream & str_r ) const
00174       {
00175         str_r << ( _stop - _start );
00176         if ( _seq > 1 ) // diff to previous _elapsed
00177           {
00178             str_r << " [" << ( _stop - _elapsed ) << "]";
00179           }
00180         return str_r << endl;
00181       }
00182 
00183     private:
00184       std::string       _ident;
00185       Tm               _start;
00186       mutable unsigned _seq;
00187       mutable Tm       _elapsed;
00188       mutable Tm       _stop;
00189     };
00191 
00193     //
00194     //  CLASS NAME : Measure
00195     //
00197 
00199     //
00200     //  METHOD NAME : Measure::Measure
00201     //  METHOD TYPE : Ctor
00202     //
00203     Measure::Measure()
00204     {}
00205 
00207     //
00208     //  METHOD NAME : Measure::Measure
00209     //  METHOD TYPE : Ctor
00210     //
00211     Measure::Measure( const std::string & ident_r )
00212     : _pimpl( new Impl( ident_r ) )
00213     {}
00214 
00216     //
00217     //  METHOD NAME : Measure::~Measure
00218     //  METHOD TYPE : Dtor
00219     //
00220     Measure::~Measure()
00221     {}
00222 
00224     //
00225     //  METHOD NAME : Measure::start
00226     //  METHOD TYPE : void
00227     //
00228     void Measure::start( const std::string & ident_r )
00229     {
00230       stop();
00231       _pimpl.reset( new Impl( ident_r ) );
00232     }
00233 
00235     //
00236     //  METHOD NAME : Measure::start
00237     //  METHOD TYPE : void
00238     //
00239     void Measure::restart()
00240     {
00241       _pimpl->restart();
00242     }
00243     
00245     //
00246     //  METHOD NAME : Measure::
00247     //  METHOD TYPE : void
00248     //
00249     void Measure::elapsed() const
00250     {
00251       if ( _pimpl )
00252         _pimpl->elapsed();
00253     }
00254 
00256     //
00257     //  METHOD NAME : Measure::
00258     //  METHOD TYPE : void
00259     //
00260     void Measure::stop()
00261     {
00262       _pimpl.reset();
00263     }
00264 
00266   } // namespace debug
00269 } // namespace zypp