00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef STXXL_IOSTATS_HEADER
00015 #define STXXL_IOSTATS_HEADER
00016
00017 #ifndef STXXL_IO_STATS
00018 #define STXXL_IO_STATS 1
00019 #endif
00020
00021
00022 #include <iostream>
00023
00024 #include <stxxl/bits/namespace.h>
00025 #include <stxxl/bits/common/mutex.h>
00026 #include <stxxl/bits/common/types.h>
00027 #include <stxxl/bits/common/utils.h>
00028 #include <stxxl/bits/singleton.h>
00029
00030
00031 __STXXL_BEGIN_NAMESPACE
00032
00036
00039 class stats : public singleton<stats>
00040 {
00041 friend class singleton<stats>;
00042
00043 unsigned reads, writes;
00044 int64 volume_read, volume_written;
00045 double t_reads, t_writes;
00046 double p_reads, p_writes;
00047 double p_begin_read, p_begin_write;
00048 double p_ios;
00049 double p_begin_io;
00050 double t_waits, p_waits;
00051 double p_begin_wait;
00052 int acc_reads, acc_writes;
00053 int acc_ios;
00054 int acc_waits;
00055 double last_reset;
00056 mutex read_mutex, write_mutex, io_mutex, wait_mutex;
00057
00058 stats();
00059
00060 public:
00061 class scoped_write_timer
00062 {
00063 typedef unsigned_type size_type;
00064
00065 #if STXXL_IO_STATS
00066 bool running;
00067 #endif
00068
00069 public:
00070 scoped_write_timer(size_type size)
00071 #if STXXL_IO_STATS
00072 : running(false)
00073 #endif
00074 {
00075 start(size);
00076 }
00077
00078 ~scoped_write_timer()
00079 {
00080 stop();
00081 }
00082
00083 void start(size_type size)
00084 {
00085 #if STXXL_IO_STATS
00086 if (!running) {
00087 running = true;
00088 stats::get_instance()->write_started(size);
00089 }
00090 #else
00091 UNUSED(size);
00092 #endif
00093 }
00094
00095 void stop()
00096 {
00097 #if STXXL_IO_STATS
00098 if (running) {
00099 stats::get_instance()->write_finished();
00100 running = false;
00101 }
00102 #endif
00103 }
00104 };
00105
00106 class scoped_read_timer
00107 {
00108 typedef unsigned_type size_type;
00109
00110 #if STXXL_IO_STATS
00111 bool running;
00112 #endif
00113
00114 public:
00115 scoped_read_timer(size_type size)
00116 #if STXXL_IO_STATS
00117 : running(false)
00118 #endif
00119 {
00120 start(size);
00121 }
00122
00123 ~scoped_read_timer()
00124 {
00125 stop();
00126 }
00127
00128 void start(size_type size)
00129 {
00130 #if STXXL_IO_STATS
00131 if (!running) {
00132 running = true;
00133 stats::get_instance()->read_started(size);
00134 }
00135 #else
00136 UNUSED(size);
00137 #endif
00138 }
00139
00140 void stop()
00141 {
00142 #if STXXL_IO_STATS
00143 if (running) {
00144 stats::get_instance()->read_finished();
00145 running = false;
00146 }
00147 #endif
00148 }
00149 };
00150
00151 class scoped_wait_timer
00152 {
00153 #ifdef COUNT_WAIT_TIME
00154 bool running;
00155 #endif
00156
00157 public:
00158 scoped_wait_timer()
00159 #ifdef COUNT_WAIT_TIME
00160 : running(false)
00161 #endif
00162 {
00163 start();
00164 }
00165
00166 ~scoped_wait_timer()
00167 {
00168 stop();
00169 }
00170
00171 void start()
00172 {
00173 #ifdef COUNT_WAIT_TIME
00174 if (!running) {
00175 running = true;
00176 stats::get_instance()->wait_started();
00177 }
00178 #endif
00179 }
00180
00181 void stop()
00182 {
00183 #ifdef COUNT_WAIT_TIME
00184 if (running) {
00185 stats::get_instance()->wait_finished();
00186 running = false;
00187 }
00188 #endif
00189 }
00190 };
00191
00192 public:
00195 unsigned get_reads() const
00196 {
00197 return reads;
00198 }
00199
00202 unsigned get_writes() const
00203 {
00204 return writes;
00205 }
00206
00209 int64 get_read_volume() const
00210 {
00211 return volume_read;
00212 }
00213
00216 int64 get_written_volume() const
00217 {
00218 return volume_written;
00219 }
00220
00223 double get_read_time() const
00224 {
00225 return t_reads;
00226 }
00227
00230 double get_write_time() const
00231 {
00232 return t_writes;
00233 }
00234
00237 double get_pread_time() const
00238 {
00239 return p_reads;
00240 }
00241
00244 double get_pwrite_time() const
00245 {
00246 return p_writes;
00247 }
00248
00251 double get_pio_time() const
00252 {
00253 return p_ios;
00254 }
00255
00261 double get_io_wait_time() const
00262 {
00263 return t_waits;
00264 }
00265
00268 double get_last_reset_time() const
00269 {
00270 return last_reset;
00271 }
00272
00274 void reset();
00275
00277 __STXXL_DEPRECATED(void _reset_io_wait_time());
00278
00279
00280 void write_started(unsigned size_);
00281 void write_finished();
00282 void read_started(unsigned size_);
00283 void read_finished();
00284 void wait_started();
00285 void wait_finished();
00286 };
00287
00288 #if !STXXL_IO_STATS
00289 inline void stats::write_started(unsigned size_)
00290 {
00291 UNUSED(size_);
00292 }
00293 inline void stats::write_finished() { }
00294 inline void stats::read_started(unsigned size_)
00295 {
00296 UNUSED(size_);
00297 }
00298 inline void stats::read_finished() { }
00299 #endif
00300 #ifndef COUNT_WAIT_TIME
00301 inline void stats::wait_started() { }
00302 inline void stats::wait_finished() { }
00303 #endif
00304
00305
00306 class stats_data
00307 {
00308 unsigned reads, writes;
00309 int64 volume_read, volume_written;
00310 double t_reads, t_writes;
00311 double p_reads, p_writes;
00312 double p_ios;
00313 double t_wait;
00314 double elapsed;
00315
00316 public:
00317 stats_data() :
00318 reads(0),
00319 writes(0),
00320 volume_read(0),
00321 volume_written(0),
00322 t_reads(0.0),
00323 t_writes(0.0),
00324 p_reads(0.0),
00325 p_writes(0.0),
00326 p_ios(0.0),
00327 t_wait(0.0),
00328 elapsed(0.0)
00329 { }
00330
00331 stats_data(const stats & s) :
00332 reads(s.get_reads()),
00333 writes(s.get_writes()),
00334 volume_read(s.get_read_volume()),
00335 volume_written(s.get_written_volume()),
00336 t_reads(s.get_read_time()),
00337 t_writes(s.get_write_time()),
00338 p_reads(s.get_pread_time()),
00339 p_writes(s.get_pwrite_time()),
00340 p_ios(s.get_pio_time()),
00341 t_wait(s.get_io_wait_time()),
00342 elapsed(timestamp() - s.get_last_reset_time())
00343 { }
00344
00345 stats_data operator + (const stats_data & a) const
00346 {
00347 stats_data s;
00348 s.reads = reads + a.reads;
00349 s.writes = writes + a.writes;
00350 s.volume_read = volume_read + a.volume_read;
00351 s.volume_written = volume_written + a.volume_written;
00352 s.t_reads = t_reads + a.t_reads;
00353 s.t_writes = t_writes + a.t_writes;
00354 s.p_reads = p_reads + a.p_reads;
00355 s.p_writes = p_writes + a.p_writes;
00356 s.p_ios = p_ios + a.p_ios;
00357 s.t_wait = t_wait + a.t_wait;
00358 s.elapsed = elapsed + a.elapsed;
00359 return s;
00360 }
00361
00362 stats_data operator - (const stats_data & a) const
00363 {
00364 stats_data s;
00365 s.reads = reads - a.reads;
00366 s.writes = writes - a.writes;
00367 s.volume_read = volume_read - a.volume_read;
00368 s.volume_written = volume_written - a.volume_written;
00369 s.t_reads = t_reads - a.t_reads;
00370 s.t_writes = t_writes - a.t_writes;
00371 s.p_reads = p_reads - a.p_reads;
00372 s.p_writes = p_writes - a.p_writes;
00373 s.p_ios = p_ios - a.p_ios;
00374 s.t_wait = t_wait - a.t_wait;
00375 s.elapsed = elapsed - a.elapsed;
00376 return s;
00377 }
00378
00379 unsigned get_reads() const
00380 {
00381 return reads;
00382 }
00383
00384 unsigned get_writes() const
00385 {
00386 return writes;
00387 }
00388
00389 int64 get_read_volume() const
00390 {
00391 return volume_read;
00392 }
00393
00394 int64 get_written_volume() const
00395 {
00396 return volume_written;
00397 }
00398
00399 double get_read_time() const
00400 {
00401 return t_reads;
00402 }
00403
00404 double get_write_time() const
00405 {
00406 return t_writes;
00407 }
00408
00409 double get_pread_time() const
00410 {
00411 return p_reads;
00412 }
00413
00414 double get_pwrite_time() const
00415 {
00416 return p_writes;
00417 }
00418
00419 double get_pio_time() const
00420 {
00421 return p_ios;
00422 }
00423
00424 double get_elapsed_time() const
00425 {
00426 return elapsed;
00427 }
00428
00429 double get_io_wait_time() const
00430 {
00431 return t_wait;
00432 }
00433 };
00434
00435 std::ostream & operator << (std::ostream & o, const stats_data & s);
00436
00437 inline std::ostream & operator << (std::ostream & o, const stats & s)
00438 {
00439 o << stxxl::stats_data(s);
00440 return o;
00441 }
00442
00444
00445 __STXXL_END_NAMESPACE
00446
00447 #endif // !STXXL_IOSTATS_HEADER
00448