common/measurement.h
///////////////////////////////////////////////////////////////////////////////
// Filename: measurement.h
///////////////////////////////////////////////////////////////////////////////
// Purpose: defines a class "measurement" that makes it easier to measure
//          performances
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/02/28 22:49:38 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////
#ifndef __MEASUREMENT_H__
#define __MEASUREMENT_H__
// Feature test switches ///////////////////////////// Feature test switches //
    /* NONE */
// System headers /////////////////////////////////////////// System headers //
#include <stdlib.h>
// Local headers ///////////////////////////////////////////// Local headers //
#include "../common.h"
// Macros /////////////////////////////////////////////////////////// Macros //
// extensions for filenames of measurements
#define LOGFILE_EXTENSION ".log"
#define COMPLOGFILE_EXTENSION ".data"
// File scope objects /////////////////////////////////// File scope objects //
    /* NONE */
// External variables, functions, and classes ///////////// External objects //
    /* NONE */
// Signal catching functions ///////////////////// Signal catching functions //
    /* NONE */
// Structures, unions, and class definitions /////////////////// Definitions //
// this structure holds information about one measurement
struct measurement_data
{
    int buffersize;     // number of bytes read or written in each turn
    int how_often;      // how often buffersize is written
    long cpu_secs;      // how long this took in cpu seconds
    long cpu_usecs;     // and microseconds
    long clock_secs;    // how long this took in time seconds
    long clock_usecs;   // and microseconds
    char *comment;      // string to comment this result
};
class measurement
{
public:
    // define measurement environment, use name as base filename to write
    // data to, and define max. numbers of measurements
    measurement(char *name, char *ext, int max_number_of_measurements);
    ~measurement(void);
    // start measurement
    // buffersize: size of used buffer (needed to calculate the
    //             throughput
    // how_often:  the number how often the measurement is done with the
    //             given buffersize
    // comment:    a comment for a measurement.
    void start(int buffersize=-1, int how_often=0, char *comment=NULL);
    // end measurement
    void end(void);
    // reset measurement
    void reset(void);
    // these functions are for applications with kb/s and op/s
    // if use_cout is true, uses cout to display data instead of
    // creating a file
    void writeout_logfile(bool write_kb_per_sec  = true,
                          bool write_ops_per_sec = true,
                          bool use_cout = false);
    // generates data for gnuplot, therefore always creates a file
    void writeout_plain_logfile(bool write_kb_per_sec  = true, 
                                bool write_ops_per_sec = false);
    // these two functions are for measurements where only the taken
    // time matters (therefore no kb/s)
    void writeout_histogram(bool use_cout = false);
    void writeout_plain_histogram(void);
    
private:
    void write_logfile(char *extension, bool verbal, bool write_kb_per_secs,
                        bool write_ops_per_sec, bool use_cout);
    void write_histogram(bool verbal, bool use_cout);
    struct measurement_data *data;
    int max_number;         // class can handle up to this measurements
    char *logbasename;
    char *logbasenameext;
    cputimer cput;          // measures used cpu time
    clocktimer clockt;      // measures clock time
    int actual;             // which measurement comes next?
};