common/cputimer.c

///////////////////////////////////////////////////////////////////////////////
// Filename: cputimer.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: implementation of class "cputimer" which measures cpu time
//          (user+system, without children)
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/02/06 01:10:57 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////


// Feature test switches ///////////////////////////// Feature test switches //
    /* NONE */



// System headers /////////////////////////////////////////// System headers //

#include <stdlib.h>
#include <unistd.h>


// Local headers ///////////////////////////////////////////// Local headers //

#include "../common.h"
#include "cputimer.h"


// Macros /////////////////////////////////////////////////////////// Macros //
    /* NONE */



// 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 //
    /* NONE */



// Functions and class implementation /// Functions and class implementation //
    /* NONE */

/*
 * constructor: get the speed of the times() clock
 */

cputimer::cputimer(void):gottime(false),started(false)
{
    if( (ticks_per_sec=sysconf(_SC_CLK_TCK)) < 0)
        error.system("cputimer::cputimer(): sysconf(): can't get CLK_TCK");
}


/*
 * start the cpu timer
 */

bool 
cputimer::start(void)
{
    gottime = false;

    if(times(&tstart) == (clock_t)(-1))
    {
        cerr << "cputimer::start:times() error" << endl;
        return false;
    }

    started = true;
    return true;
}


/*
 * end the cpu timer and calculate result
 */

bool 
cputimer::end(void)
{
    tms tend;

    if(!started)
    {
        cerr << "cputimer::end(): called without calling"
             << " cputimer::start() first!" << endl;
        return false;
    }

    if(times(&tend) == (clock_t)(-1))
    {
        cerr << "cputimer::end(): times() error" << endl;
        return false;
    }

    tresult.tms_utime = tend.tms_utime - tstart.tms_utime;
    tresult.tms_stime = tend.tms_stime - tstart.tms_stime;
    tresult.tms_cutime = tend.tms_cutime - tstart.tms_cutime;
    tresult.tms_cstime = tend.tms_cstime - tstart.tms_cstime;

    gottime = true;
    started = false;

    return true;
}


/*
 * return number of measured seconds or -1 for an error
 */

long 
cputimer::secs(void)
{
    if(gottime)
        return (tresult.tms_utime + tresult.tms_stime)/ticks_per_sec;
    else
        return -1;
}


/*
 * return number of measured microseconds or -1 for an error
 */

long 
cputimer::usecs(void)
{
    if(gottime)
    {
        long ticks = tresult.tms_utime + tresult.tms_stime;
        long secs  = ticks/ticks_per_sec;
        long rest  = ticks - secs*ticks_per_sec;
        long multiplier = 1000000/ticks_per_sec;

        return rest * multiplier;
    }
    else
        return -1;
}


// Main /////////////////////////////////////////////////////////////// Main //
    /* NONE */