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?
};