blob: d98bcfcd13254b3ba13273183e41efbe5ae9a98e [file] [log] [blame]
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Timestamp.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A generic interface to a timestamp.
* This implementation uses the unix gettimeofday().
* -------------------------------------------------------------------
* headers
* uses
* <sys/types.h>
* <sys/time.h>
* <unistd.h>
* ------------------------------------------------------------------- */
#ifndef TIMESTAMP_H
#define TIMESTAMP_H
#include "headers.h"
/* ------------------------------------------------------------------- */
class Timestamp {
public:
/* -------------------------------------------------------------------
* Create a timestamp, with the current time in it.
* ------------------------------------------------------------------- */
Timestamp( void ) {
setnow();
}
/* -------------------------------------------------------------------
* Create a timestamp, with the given seconds/microseconds
* ------------------------------------------------------------------- */
Timestamp( long sec, long usec ) {
set( sec, usec );
}
/* -------------------------------------------------------------------
* Create a timestamp, with the given seconds
* ------------------------------------------------------------------- */
Timestamp( double sec ) {
set( sec );
}
/* -------------------------------------------------------------------
* Set timestamp to current time.
* ------------------------------------------------------------------- */
void setnow( void ) {
gettimeofday( &mTime, NULL );
}
/* -------------------------------------------------------------------
* Set timestamp to the given seconds/microseconds
* ------------------------------------------------------------------- */
void set( long sec, long usec ) {
assert( sec >= 0 );
assert( usec >= 0 && usec < kMillion );
mTime.tv_sec = sec;
mTime.tv_usec = usec;
}
/* -------------------------------------------------------------------
* Set timestamp to the given seconds
* ------------------------------------------------------------------- */
void set( double sec ) {
mTime.tv_sec = (long) sec;
mTime.tv_usec = (long) ((sec - mTime.tv_sec) * kMillion);
}
/* -------------------------------------------------------------------
* return seconds portion of timestamp
* ------------------------------------------------------------------- */
long getSecs( void ) {
return mTime.tv_sec;
}
/* -------------------------------------------------------------------
* return microseconds portion of timestamp
* ------------------------------------------------------------------- */
long getUsecs( void ) {
return mTime.tv_usec;
}
/* -------------------------------------------------------------------
* return timestamp as a floating point seconds
* ------------------------------------------------------------------- */
double get( void ) {
return mTime.tv_sec + mTime.tv_usec / ((double) kMillion);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in microseconds.
* ------------------------------------------------------------------- */
long subUsec( Timestamp right ) {
return(mTime.tv_sec - right.mTime.tv_sec) * kMillion +
(mTime.tv_usec - right.mTime.tv_usec);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in microseconds.
* ------------------------------------------------------------------- */
long subUsec( timeval right ) {
return(mTime.tv_sec - right.tv_sec) * kMillion +
(mTime.tv_usec - right.tv_usec);
}
/* -------------------------------------------------------------------
* Return the number of microseconds from now to last time of setting.
* ------------------------------------------------------------------- */
long delta_usec(void) {
struct timeval previous = mTime;
setnow();
return subUsec(previous);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in seconds as a floating point.
* ------------------------------------------------------------------- */
double subSec( Timestamp right ) {
return(mTime.tv_sec - right.mTime.tv_sec) +
(mTime.tv_usec - right.mTime.tv_usec) / ((double) kMillion);
}
/* -------------------------------------------------------------------
* add the right timestamp to my timestamp.
* ------------------------------------------------------------------- */
void add( Timestamp right ) {
mTime.tv_sec += right.mTime.tv_sec;
mTime.tv_usec += right.mTime.tv_usec;
// watch for under- and overflow
if ( mTime.tv_usec < 0 ) {
mTime.tv_usec += kMillion;
mTime.tv_sec--;
}
if ( mTime.tv_usec >= kMillion ) {
mTime.tv_usec -= kMillion;
mTime.tv_sec++;
}
assert( mTime.tv_usec >= 0 &&
mTime.tv_usec < kMillion );
}
/* -------------------------------------------------------------------
* add the seconds to my timestamp.
* TODO optimize?
* ------------------------------------------------------------------- */
void add( double sec ) {
mTime.tv_sec += (long) sec;
mTime.tv_usec += (long) ((sec - ((long) sec )) * kMillion);
// watch for overflow
if ( mTime.tv_usec >= kMillion ) {
mTime.tv_usec -= kMillion;
mTime.tv_sec++;
}
assert( mTime.tv_usec >= 0 &&
mTime.tv_usec < kMillion );
}
/* -------------------------------------------------------------------
* return true if my timestamp is before the right timestamp.
* ------------------------------------------------------------------- */
bool before( timeval right ) {
return mTime.tv_sec < right.tv_sec ||
(mTime.tv_sec == right.tv_sec &&
mTime.tv_usec < right.tv_usec);
}
bool before( Timestamp right ) { return before(right.mTime); }
/* -------------------------------------------------------------------
* return true if my timestamp is after the right timestamp.
* ------------------------------------------------------------------- */
bool after( timeval right ) {
return mTime.tv_sec > right.tv_sec ||
(mTime.tv_sec == right.tv_sec &&
mTime.tv_usec > right.tv_usec);
}
bool after( Timestamp right ) { return after(right.mTime); }
/**
* This function returns the fraction of time elapsed after the beginning
* till the end
*/
double fraction(Timestamp currentTime, Timestamp endTime) {
if ( (currentTime.after(*this)) && (endTime.after(currentTime)) ) {
return(((double)currentTime.subUsec(*this)) /
((double)endTime.subUsec(*this)));
} else {
return -1.0;
}
}
protected:
enum {
kMillion = 1000000
};
struct timeval mTime;
}; // end class Timestamp
#endif // TIMESTAMP_H