00001
00002
00003
00004
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 }
00139
00141
00142
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 )
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
00202
00204
00206
00207
00208
00209
00210 Measure::Measure()
00211 {}
00212
00214
00215
00216
00217
00218 Measure::Measure( const std::string & ident_r )
00219 : _pimpl( new Impl( ident_r ) )
00220 {}
00221
00223
00224
00225
00226
00227 Measure::~Measure()
00228 {}
00229
00231
00232
00233
00234
00235 void Measure::start( const std::string & ident_r )
00236 {
00237 stop();
00238 _pimpl.reset( new Impl( ident_r ) );
00239 }
00240
00242
00243
00244
00245
00246 void Measure::restart()
00247 {
00248 _pimpl->restart();
00249 }
00250
00252
00253
00254
00255
00256 void Measure::elapsed() const
00257 {
00258 if ( _pimpl )
00259 _pimpl->elapsed();
00260 }
00261
00263
00264
00265
00266
00267 void Measure::stop()
00268 {
00269 _pimpl.reset();
00270 }
00271
00273 }
00276 }