//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
// Created: BMK 07/14/89 -- Initial design and implementation
// Updated: LGO 09/23/89 -- Conform to COOL coding style
// Updated: AFM 12/31/89 -- OS/2 port
//
// The Timer class provides timing code  for performance evaluation.  This code
// was originally written by Joe Rahmeh at UT Austin.
//
//  User time:
//    time cpu spends in user mode on behalf of the program.
//  System time:
//    time cpu spends in system mode on behalf of the program.
//  Real time:
//    what you get from a stop watch timer.

#include <cool/Timer.h>

/******************************************************************************/
/* The TIMER Class Implementation */

void
Timer::mark()
{
#if defined (DOS) || defined (MSDOS)
 usage0 = clock();
#else
 getrusage(0, &usage0);
#endif

 ftime(&real0);
}

long
Timer::real()
{long s, ms;
 timeb  real;        // current elapsed real time

 ftime(&real);
 s  = real.time    - real0.time;
 ms = real.millitm - real0.millitm;
 if(ms < 0)
   {ms += 1000;
    s--;
   }
 return 1000*s + ms;
}

long
Timer::user()
{
#if defined (DOS) || defined (MSDOS)
 register clock_t  usage1;
 
 if ((usage1 = clock()) != (clock_t) -1)
    return (usage1 - usage0);
 else   /* error: Processor time not available */
    return (0L);
 
#else
 register long dsec, dusec;
 rusage usage;       // current rusage structure

 getrusage(0, &usage);
 dsec  = usage.ru_utime.tv_sec  - usage0.ru_utime.tv_sec;
 dusec = usage.ru_utime.tv_usec - usage0.ru_utime.tv_usec;
 if(dusec < 0)
   {dusec += 1000000;
    dsec--;
   }
 return(dsec*1000 + dusec/1000);

#endif
}

long
Timer::system()
{
#if defined (DOS) || defined (MSDOS)
 return(0L);

#else
 register long dsec, dusec;
 rusage usage;       // current rusage structure

 getrusage(0, &usage);
 dsec  = usage.ru_stime.tv_sec  - usage0.ru_stime.tv_sec;
 dusec = usage.ru_stime.tv_usec - usage0.ru_stime.tv_usec;
 if(dusec < 0)
   {dusec += 1000000;
    dsec--;
   }
 return(dsec*1000 + dusec/1000);

#endif
}

long
Timer::all()
{
#if defined (DOS) || defined (MSDOS)
 register clock_t  usage1;
 
 if ((usage1 = clock()) != (clock_t) -1)
    return (usage1 - usage0);
 else   /* error: Processor time not available */
    return (0L);
 
#else
 register long dsec, dusec;
 rusage usage;       // current rusage structure

 getrusage(0, &usage);
 dsec  = usage.ru_utime.tv_sec   + usage.ru_stime.tv_sec
       - usage0.ru_utime.tv_sec  - usage0.ru_stime.tv_sec;
 dusec = usage.ru_utime.tv_usec  + usage.ru_stime.tv_usec
       - usage0.ru_utime.tv_usec - usage0.ru_stime.tv_usec;
 if(dusec < 0)
   {dusec += 1000000;
    dsec--;
   }
 return(dsec*1000 + dusec/1000);

#endif
}

long
Timer::user_usec()
{
#if defined (DOS) || defined (MSDOS)
register clock_t  usage1;
 
 if ((usage1 = clock()) != (clock_t) -1)
    return (usage1 - usage0);
 else   /* error: Processor time not available */
    return (0L);
 
#else
register long dsec, dusec;
 rusage usage;       // current rusage structure

 getrusage(0, &usage);
 dsec  = usage.ru_utime.tv_sec  - usage0.ru_utime.tv_sec;
 dusec = usage.ru_utime.tv_usec - usage0.ru_utime.tv_usec;
 if(dusec < 0)
   {dusec += 1000000;
    dsec--;
   }
 return(dsec*1000000 + dusec);

#endif
}

long
Timer::system_usec()
{
#if defined (DOS) || defined (MSDOS)
 return(0L);

#else
 register long dsec, dusec;
 rusage usage;       // current rusage structure

 getrusage(0, &usage);
 dsec  = usage.ru_stime.tv_sec  - usage0.ru_stime.tv_sec;
 dusec = usage.ru_stime.tv_usec - usage0.ru_stime.tv_usec;
 if(dusec < 0)
   {dusec += 1000000;
    dsec--;
   }
 return(dsec*1000000 + dusec);

#endif
}

long
Timer::all_usec()
{
#if defined (DOS) || defined (MSDOS)
 register clock_t  usage1;
 
 if ((usage1 = clock()) != (clock_t) -1)
    return (usage1 - usage0);
 else   /* error: Processor time not available */
    return (0L);
 
#else
 register long dsec, dusec;
 rusage usage;       // current rusage structure
 
 getrusage(0, &usage);
 dsec  = usage.ru_utime.tv_sec   + usage.ru_stime.tv_sec
       - usage0.ru_utime.tv_sec  - usage0.ru_stime.tv_sec;
 dusec = usage.ru_utime.tv_usec  + usage.ru_stime.tv_usec
       - usage0.ru_utime.tv_usec - usage0.ru_stime.tv_usec;
 if(dusec < 0)
   {dusec += 1000000;
    dsec--;
   }
 return(dsec*1000000 + dusec);

#endif
}
