#ifndef IOSTATS_HEADER #define IOSTATS_HEADER /*************************************************************************** * iostats.h * * Sat Aug 24 23:54:50 2002 * Copyright 2002 Roman Dementiev * dementiev@mpi-sb.mpg.de ****************************************************************************/ #include "../common/mutex.h" #include "../common/utils.h" #include __STXXL_BEGIN_NAMESPACE //! \addtogroup iolayer //! //! \{ #ifdef COUNT_WAIT_TIME extern double stxxl::wait_time_counter; #endif class disk_queue; //! \brief Collects varoius I/O statistics //! \remarks is a singleton class stats { friend class disk_queue; unsigned reads, writes; // number of operations double t_reads, t_writes; // seconds spent in operations double p_reads, p_writes; // seconds spent in parallel operations double p_begin_read, p_begin_write; // start time of parallel operation double p_ios; // seconds spent in all parallel I/O operations (read and write) double p_begin_io; int acc_ios; int acc_reads, acc_writes; // number of requests, participating in parallel operation mutex read_mutex, write_mutex, io_mutex; static stats *instance; stats ():reads (0), writes (0), t_reads (0.0), t_writes (0.0), p_reads (0.0), p_writes (0.0), p_begin_read (0.0), p_begin_write (0.0), p_ios (0.0), p_begin_io (0), acc_ios (0), acc_reads (0), acc_writes (0) { }; public: //! \brief Call this function in order to access an instance of stats //! \return pointer to an instance of stats static stats *get_instance () { if (!instance) instance = new stats (); return instance; }; //! \brief Returns total number of reads //! \return total number of reads unsigned get_reads () { return reads; }; //! \brief Returns total number of writes //! \return total number of writes unsigned get_writes () { return writes; }; //! \brief Returns time spent in serving all read requests //! \remarks If there are \c n read requests that are served simultaneously //! \remarks in 1 second then the counter corresponding to the function increments by \c n seconds //! \return seconds spent in reading double get_read_time () { return t_reads; }; //! \brief Returns total time spent in serving all write requests //! \remarks If there are \c n write requests that are served simultaneously //! \remarks in 1 second then the counter corresponding to the function increments by \c n seconds //! \return seconds spent in writing double get_write_time () { return t_writes; }; //! \brief Returns time spent in reading (parallel read time) //! \remarks If there are \c n read requests that are served simultaneously //! \remarks in 1 second then the counter corresponding to the function increments by 1 second //! \return seconds spent in reading double get_pread_time() { return p_reads; }; //! \brief Returns time spent in writing (parallel write time) //! \remarks If there are \c n write requests that are served simultaneously //! \remarks in 1 second then the counter corresponding to the function increments by 1 second //! \return seconds spent in writing double get_pwrite_time() { return p_writes; }; //! \brief Returns time spent in I/O (parallel I/O time) //! \remarks If there are \c n \b any requests that are served simultaneously //! \remarks in 1 second then the counter corresponding to the function increments by 1 second //! \return seconds spent in I/O double get_pio_time() { return p_ios; }; //! \brief Resets I/O time counters void reset() { read_mutex.lock (); // assert(acc_reads == 0); if (acc_reads) std::cerr << "Warning: " << acc_reads << " read(s) not yet finished" << std:: endl; reads = 0; t_reads = 0; p_reads = 0.0; read_mutex.unlock (); write_mutex.lock (); // assert(acc_writes == 0); if (acc_writes) std::cerr << "Warning: " << acc_writes << " write(s) not yet finished" << std:: endl; writes = 0; t_writes = 0.0; p_writes = 0.0; write_mutex.unlock (); io_mutex.lock (); // assert(acc_ios == 0); if (acc_ios) std::cerr << "Warning: " << acc_ios << " io(s) not yet finished" << std:: endl; p_ios = 0.0; io_mutex.unlock (); }; #ifdef COUNT_WAIT_TIME //! \brief Resets I/O wait time counter void _reset_io_wait_time() { stxxl::wait_time_counter = 0.0; } //! \brief Returns I/O wait time counter //! \return number of seconds spent in I/O waiting functions //! \link request::wait request::wait \endlink, //! \c wait_any and //! \c wait_all double get_io_wait_time() { return (stxxl::wait_time_counter); } //! \brief Increments I/O wait time counter //! \param val increment value in seconds //! \return new value of I/O wait time counter in seconds double increment_io_wait_time(double val) { return stxxl::wait_time_counter+= val; } #else //! \brief Resets I/O wait time counter void _reset_io_wait_time() {} //! \brief Returns I/O wait time counter //! \return number of seconds spent in I/O waiting functions //! \link request::wait request::wait \endlink, //! \c wait_any and //! \c wait_all //! \return number of seconds double get_io_wait_time() { return -1.0; } //! \brief Increments I/O wait time counter //! \param val increment value in seconds //! \return new value of I/O wait time counter in seconds double increment_io_wait_time(double val) { return -1.0; } #endif protected: void write_started () { write_mutex.lock (); double now = stxxl_timestamp (); writes++; double diff = now - p_begin_write; t_writes += double (acc_writes) * diff; p_begin_write = now; p_writes += (acc_writes++) ? diff : 0.0; write_mutex.unlock (); io_mutex.lock (); diff = now - p_begin_io; p_ios += (acc_ios++) ? diff : 0.0; p_begin_io = now; io_mutex.unlock (); } void write_finished () { write_mutex.lock (); double now = stxxl_timestamp (); double diff = now - p_begin_write; t_writes += double (acc_writes) * diff; p_begin_write = now; p_writes += (acc_writes--) ? diff : 0.0; write_mutex.unlock (); io_mutex.lock (); diff = now - p_begin_io; p_ios += (acc_ios--) ? diff : 0.0; p_begin_io = now; io_mutex.unlock (); } void read_started () { read_mutex.lock (); double now = stxxl_timestamp (); reads++; double diff = now - p_begin_read; t_reads += double (acc_reads) * diff; p_begin_read = now; p_reads += (acc_reads++) ? diff : 0.0; read_mutex.unlock (); io_mutex.lock (); diff = now - p_begin_io; p_ios += (acc_ios++) ? diff : 0.0; p_begin_io = now; io_mutex.unlock (); } void read_finished () { read_mutex.lock (); double now = stxxl_timestamp (); double diff = now - p_begin_read; t_reads += double (acc_reads) * diff; p_begin_read = now; p_reads += (acc_reads--) ? diff : 0.0; read_mutex.unlock (); io_mutex.lock (); diff = now - p_begin_io; p_ios += (acc_ios--) ? diff : 0.0; p_begin_io = now; io_mutex.unlock (); } }; //! \} __STXXL_END_NAMESPACE #endif