//
// $Id: ctimer.cc,v 1.6 2004-09-10 09:54:57 cmv Exp $
//

#include "sopnamsp.h"
#include "machdefs.h"
#include "ctimer.h"

//++
// Class	Timer
// Lib  	SysTools
// include	ctimer.h
//
//	Chronométrage de programmes. Le constructeur mémorise l'heure et
//      le temps CPU, ainsi qu'un message éventuel.
//
//	Split affiche le temps partiel.
//
//	Le destructeur affiche le temps total (CPU, et écoulé).
//    
//      Des macros permettent une utilisation simplifiée :
//      * TIMEF   crée un objet de type Timer, avec le nom de la function 
//	courante comme message. Le temps écoulé sera affiché à la sortie 
//	de la function.
//      * SPLITTIME affiche le temps partiel du compteur crée par TIMEF
//      * TIMEN(nom) permet de donner un autre nom que le nom de la fonction.
//--


//++
// Titre	Constructeurs
//--

//++
// Timer::Timer(const char* name)
//	Crée un objet qui mémorise l'heure et le temps CPU du process courant.
//	Le destructeur affiche les temps écoulé et CPU utilisé.
//--

/*!
  \class SOPHYA::Timer
  \ingroup SysTools
  \brief Simple chronometer for CPU and elapsed time measurements.
  This class implements a simple chronometer which can be used for
  measuring the CPU and elapsed time in functions. The constructor
  keeps the start time (and CPU time) and an optional message. 
  The \b Split method displays the partial time, and destructor 
  displays the total CPU and elapsed time since timer creation.
  The macro \b  TIMEF create a timer object with the function name.
  The macro \b  SPLITTIME calls the split methode for the timer created
  by TIMEF. A named timer can be created using the macro \b TIMEN(nom)
*/

/*! Constructor with the specification of a optional name or message */
Timer::Timer(const char* name)
: timerName(name)
{
  cpu0 = cpuSplit = clock();
  elapse0 = elapseSplit = time(0);
}

//++
// Titre	Méthodes
//--

//++
// Timer::Split(const char* comm)
//	Affiche le temps partiel.
//--

/*! Method which displays the partial CPU and elapsed time
    An optional message can be passed to be used instead of the
    timer name
*/
void Timer::Split(const char* comm)
{
  time_t elapse = time(0);
  clock_t cpu   = clock();

  float cpuSecT = ((float)cpu - (float)cpu0) / (float)(CLOCKS_PER_SEC);
  float cpuSecP = ((float)cpu - (float)cpuSplit) / (float)(CLOCKS_PER_SEC);
  
  int etm  = elapse - elapseSplit;
  int etmt = elapse - elapse0;

  cout << "***Timing " << (comm ? comm : timerName.c_str()) << endl;

// Pour des formats comme ca, la syntaxe printf est plus agreable.
// Pour ne pas melanger stdio/iostream (pb de desynchronisation sur
// autres C++ que GNU), on fait un cout << chaine.

  char out[200];
  sprintf(out,"CPU     Time: Total= %g (Partial= %g) Sec.",
	  cpuSecT, cpuSecP);
  cout << out << endl;

  sprintf(out,"Elapsed Time: Total= %02d:%02d:%02d (Partial=%02d:%02d:%02d)",
	  etmt/3600, (etmt%3600)/60, etmt%60, 
	  etm/3600,  (etm%3600)/60,  etm%60);

  cout << out << endl;

  elapseSplit = elapse;
  cpuSplit    = cpu;
}

Timer::~Timer()
{
  Split();
}
