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 restart()
00165       {
00166         INT << "RESTART MEASURE(" << _ident << ")" << endl;
00167         _start = _stop;
00168       }
00169       
00170       void elapsed() const
00171       {
00172         _stop.get();
00173         ++_seq;
00174         std::ostream & str( INT << "ELAPSED(" << _ident << ") " );
00175         dumpMeasure( str );
00176         _elapsed = _stop;
00177       }
00178 
00179     private:
00180       std::ostream & dumpMeasure( std::ostream & str_r ) const
00181       {
00182         str_r << ( _stop - _start );
00183         if ( _seq > 1 ) // diff to previous _elapsed
00184           {
00185             str_r << " [" << ( _stop - _elapsed ) << "]";
00186           }
00187         return str_r << endl;
00188       }
00189 
00190     private:
00191       std::string       _ident;
00192       Tm               _start;
00193       mutable unsigned _seq;
00194       mutable Tm       _elapsed;
00195       mutable Tm       _stop;
00196     };
00198 
00200     //
00201     //  CLASS NAME : Measure
00202     //
00204 
00206     //
00207     //  METHOD NAME : Measure::Measure
00208     //  METHOD TYPE : Ctor
00209     //
00210     Measure::Measure()
00211     {}
00212 
00214     //
00215     //  METHOD NAME : Measure::Measure
00216     //  METHOD TYPE : Ctor
00217     //
00218     Measure::Measure( const std::string & ident_r )
00219     : _pimpl( new Impl( ident_r ) )
00220     {}
00221 
00223     //
00224     //  METHOD NAME : Measure::~Measure
00225     //  METHOD TYPE : Dtor
00226     //
00227     Measure::~Measure()
00228     {}
00229 
00231     //
00232     //  METHOD NAME : Measure::start
00233     //  METHOD TYPE : void
00234     //
00235     void Measure::start( const std::string & ident_r )
00236     {
00237       stop();
00238       _pimpl.reset( new Impl( ident_r ) );
00239     }
00240 
00242     //
00243     //  METHOD NAME : Measure::start
00244     //  METHOD TYPE : void
00245     //
00246     void Measure::restart()
00247     {
00248       _pimpl->restart();
00249     }
00250     
00252     //
00253     //  METHOD NAME : Measure::
00254     //  METHOD TYPE : void
00255     //
00256     void Measure::elapsed() const
00257     {
00258       if ( _pimpl )
00259         _pimpl->elapsed();
00260     }
00261 
00263     //
00264     //  METHOD NAME : Measure::
00265     //  METHOD TYPE : void
00266     //
00267     void Measure::stop()
00268     {
00269       _pimpl.reset();
00270     }
00271 
00273   } // namespace debug
00276 } // namespace zypp

Generated on Tue Sep 25 19:22:58 2007 for libzypp by  doxygen 1.5.3