/**************************************************
 * time checking routines
 */

#include LATDEF


/*************************************************
 * resource clocks
 */

static double time_last;


#ifdef MPI

static double time_start;

void inittime()
{
  time_start = time_last = MPI_Wtime();
}

void resettime()
{
  time_last = MPI_Wtime();
}

double cputime() 
{
  return ( MPI_Wtime() - time_start );
}

double added_cpu_time()
{
  double t,t2;

  t = (t2 = MPI_Wtime()) - time_last;
  time_last = t2;
  return(t);
}

#else

double cputime()
{
  struct rusage resource;
  extern int getrusage();

  getrusage(RUSAGE_SELF,&resource);
  return(resource.ru_utime.tv_sec + 1e-6*resource.ru_utime.tv_usec +
	 resource.ru_stime.tv_sec + 1e-6*resource.ru_stime.tv_usec);

}

void inittime()
{
  time_last = cputime();
}

void resettime()
{
  time_last = cputime();
}

double added_cpu_time()
{
  double t,t2;

  t = (t2 = cputime()) - time_last;
  time_last = t2;
  return(t);
}

#endif

/**************************************************
 * Timing check routines 
 */

static int interval=0,starttime;
static time_t timelimit;


void timecheck(int iteration, int maxiter, int status)
{
  int temp,ttime=0;

  if (this_node == 0) {
    ttime = time(NULL);
    if (interval <= 0.0) {
      interval = ttime - starttime;
      printf(" -- approx %d seconds between time checks\n",interval);
      fflush(stdout);
      interval += 1200;  /* leave good time (20 min) for the save etc. */
    }
    if (iteration < maxiter && timelimit - ttime - interval < 0) temp = 1;
    else temp = 0;
  } else temp = 0;

  broadcast_field(&temp,sizeof(int));
  
  if (temp == 1) {
    dumpall(status,&maxiter);
    /* normal exit here */
    if (this_node == 0) 
      printf("\n **** cpu time exit, remaining time %d seconds\n",
	     (int)(timelimit - ttime));
    finishrun();
  }
}

void inittimecheck() 
{
  starttime = time(NULL);
  interval = 0;
  if (this_node == 0) {
    printf(" -- Available wallclock time %d seconds\n",(int)(timelimit-starttime));
    fflush(stdout);
  }
}


int setup_timelimit(time_t t,int argc,char *argv)
{
  int tmp,istimelimit;

  if (this_node == 0) {
    if (argc > 0) {
      if (sscanf(argv,"%d",&tmp) != 1) 
	halt("Error reading in time limit");
      timelimit = tmp;                   /* use tmp to guarantee int */
      if (this_node == 0) 
	printf(" +++++ wallclock time limit %d seconds\n",(int)timelimit);
      istimelimit = 1;
      timelimit += t;   /* this is the time at the end ... */
    } else istimelimit = 0;
  }
  
  broadcast_int( &istimelimit );

  return(istimelimit);
}
