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     namespace
00037     { 
00038 
00040       struct Tm
00041       {
00042         Tm()
00043         : _real( 0 )
00044         , _proc( tmsEmpty )
00045         {}
00046 
00047         void get()
00048         {
00049           _real = ::time(NULL);
00050           ::times( &_proc );
00051         }
00052 
00053         Tm operator-( const Tm & rhs ) const
00054         {
00055           Tm ret( *this );
00056           ret._real -= rhs._real;
00057           ret._proc.tms_utime -= rhs._proc.tms_utime;
00058           ret._proc.tms_stime -= rhs._proc.tms_stime;
00059           ret._proc.tms_cutime -= rhs._proc.tms_cutime;
00060           ret._proc.tms_cstime -= rhs._proc.tms_cstime;
00061           return ret;
00062         }
00063 
00064         std::string asString() const
00065         {
00066           std::string ret( timeStr( _real ) );
00067           ret += " (u ";
00068           ret += timeStr( asSec( _proc.tms_utime ) );
00069           ret += " s ";
00070           ret += timeStr( asSec( _proc.tms_stime ) );
00071           ret += " c ";
00072           ret += timeStr( asSec( _proc.tms_cutime + _proc.tms_cstime ) );
00073           ret += ")";
00074           return ret;
00075         }
00076 
00077         std::string stringIf( clock_t ticks_r, const std::string & tag_r ) const
00078         {
00079           std::string ret;
00080           if ( ticks_r )
00081             {
00082               ret += tag_r;
00083               ret += timeStr( asSec( ticks_r ) );
00084             }
00085           return ret;
00086         }
00087 
00088         double asSec( clock_t ticks_r ) const
00089         { return double(ticks_r) / ticks; }
00090 
00091         std::string timeStr( time_t sec_r ) const
00092         {
00093           time_t h = sec_r/3600;
00094           sec_r -= h*3600;
00095           time_t m = sec_r/60;
00096           sec_r -= m*60;
00097           if ( h )
00098             return str::form( "%lu:%02lu:%02lu", h, m, sec_r );
00099           if ( m )
00100             return str::form( "%lu:%02lu", m, sec_r );
00101           return str::form( "%lu", sec_r );
00102         }
00103 
00104         std::string timeStr( double sec_r ) const
00105         {
00106           time_t h = time_t(sec_r)/3600;
00107           sec_r -= h*3600;
00108           time_t m = time_t(sec_r)/60;
00109           sec_r -= m*60;
00110           if ( h )
00111             return str::form( "%lu:%02lu:%05.2lf", h, m, sec_r );
00112           if ( m )
00113             return str::form( "%lu:%05.2lf", m, sec_r );
00114           return str::form( "%.2lf", sec_r );
00115         }
00116 
00118         static const long ticks;
00120         static const struct tms tmsEmpty;
00122         time_t      _real;
00124         struct tms  _proc;
00125       };
00126 
00127       const struct tms Tm::tmsEmpty = { 0, 0, 0, 0 };
00128       const long Tm::ticks = sysconf(_SC_CLK_TCK);
00129 
00131       std::ostream & operator<<( std::ostream & str, const Tm & obj )
00132       {
00133         return str << obj.asString();
00134       }
00135 
00137     } // namespace
00139 
00141     //
00142     //  CLASS NAME : Measure::Impl
00143     //
00145     class Measure::Impl
00146     {
00147     public:
00148       Impl( const std::string & ident_r )
00149       : _ident  ( ident_r )
00150       , _seq    ( 0 )
00151       {
00152         INT << "START MEASURE(" << _ident << ")" << endl;
00153         _start.get();
00154       }
00155 
00156       ~Impl()
00157       {
00158         _stop.get();
00159         ++_seq;
00160         std::ostream & str( INT << "MEASURE(" << _ident << ") " );
00161         dumpMeasure( str );
00162       }
00163 
00164       void elapsed() const
00165       {
00166         _stop.get();
00167         ++_seq;
00168         std::ostream & str( INT << "ELAPSED(" << _ident << ") " );
00169         dumpMeasure( str );
00170         _elapsed = _stop;
00171       }
00172 
00173     private:
00174       std::ostream & dumpMeasure( std::ostream & str_r ) const
00175       {
00176         str_r << ( _stop - _start );
00177         if ( _seq > 1 ) // diff to previous _elapsed
00178           {
00179             str_r << " [" << ( _stop - _elapsed ) << "]";
00180           }
00181         return str_r << endl;
00182       }
00183 
00184     private:
00185       std::string       _ident;
00186       Tm               _start;
00187       mutable unsigned _seq;
00188       mutable Tm       _elapsed;
00189       mutable Tm       _stop;
00190     };
00192 
00194     //
00195     //  CLASS NAME : Measure
00196     //
00198 
00200     //
00201     //  METHOD NAME : Measure::Measure
00202     //  METHOD TYPE : Ctor
00203     //
00204     Measure::Measure()
00205     {}
00206 
00208     //
00209     //  METHOD NAME : Measure::Measure
00210     //  METHOD TYPE : Ctor
00211     //
00212     Measure::Measure( const std::string & ident_r )
00213     : _pimpl( new Impl( ident_r ) )
00214     {}
00215 
00217     //
00218     //  METHOD NAME : Measure::~Measure
00219     //  METHOD TYPE : Dtor
00220     //
00221     Measure::~Measure()
00222     {}
00223 
00225     //
00226     //  METHOD NAME : Measure::start
00227     //  METHOD TYPE : void
00228     //
00229     void Measure::start( const std::string & ident_r )
00230     {
00231       stop();
00232       _pimpl.reset( new Impl( ident_r ) );
00233     }
00234 
00236     //
00237     //  METHOD NAME : Measure::
00238     //  METHOD TYPE : void
00239     //
00240     void Measure::elapsed() const
00241     {
00242       if ( _pimpl )
00243         _pimpl->elapsed();
00244     }
00245 
00247     //
00248     //  METHOD NAME : Measure::
00249     //  METHOD TYPE : void
00250     //
00251     void Measure::stop()
00252     {
00253       _pimpl.reset();
00254     }
00255 
00257   } // namespace debug
00260 } // namespace zypp

Generated on Tue Nov 28 16:49:28 2006 for zypp by  doxygen 1.5.0