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 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 )
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
00196
00198
00200
00201
00202
00203
00204 Measure::Measure()
00205 {}
00206
00208
00209
00210
00211
00212 Measure::Measure( const std::string & ident_r )
00213 : _pimpl( new Impl( ident_r ) )
00214 {}
00215
00217
00218
00219
00220
00221 Measure::~Measure()
00222 {}
00223
00225
00226
00227
00228
00229 void Measure::start( const std::string & ident_r )
00230 {
00231 stop();
00232 _pimpl.reset( new Impl( ident_r ) );
00233 }
00234
00236
00237
00238
00239
00240 void Measure::elapsed() const
00241 {
00242 if ( _pimpl )
00243 _pimpl->elapsed();
00244 }
00245
00247
00248
00249
00250
00251 void Measure::stop()
00252 {
00253 _pimpl.reset();
00254 }
00255
00257 }
00260 }