/**********************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: LBTimestamp.h,v 1.2 2007/04/06 00:20:08 jkubasta Exp $
 *
 * Contributors:
 * IBM - Initial API and implementation
 **********************************************************************/

#ifndef LBTIMESTAMP_H
#define LBTIMESTAMP_H

#ifdef WIN32
#include <time.h>
typedef clock_t LBCLOCK_t;

static void getClock(LBCLOCK_t *pclock) {
  *pclock = clock();
}
static unsigned int clockDiffInMilliseconds(const LBCLOCK_t *start) {
  LBCLOCK_t end;
  getClock(&end);
  return (unsigned int)(1000*((double)(end-*start))/CLOCKS_PER_SEC);
}
static double clockDiffInFractionalMilliseconds(const LBCLOCK_t *start) {
  LBCLOCK_t end;
  getClock(&end);
  return (1000000.0*((double)(end-*start))/CLOCKS_PER_SEC);
}
static unsigned int clockDiffInMicroseconds(const LBCLOCK_t *start) {
  LBCLOCK_t end;
  getClock(&end);
  return (unsigned int)(1000000*((double)(end-*start))/CLOCKS_PER_SEC);
}

#else
#include <sys/time.h>
typedef struct timeval LBCLOCK_t;

# define timersub(a, b, result)						      \
  do {									      \
    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;			      \
    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;			      \
    if ((result)->tv_usec < 0) {					      \
      --(result)->tv_sec;						      \
      (result)->tv_usec += 1000000;					      \
    }									      \
  } while (0)

static void getClock(LBCLOCK_t *pclock) {
  gettimeofday(pclock, NULL);
}
static double clockDiffInFractionalMilliseconds(const LBCLOCK_t *start) {
  LBCLOCK_t end, interval;
  getClock(&end);
  timersub(&end, start, &interval);
  return interval.tv_sec*1e3 + interval.tv_usec/1e3;
}
static unsigned int clockDiffInMilliseconds(const LBCLOCK_t *start) {
  return (unsigned int) clockDiffInFractionalMilliseconds(start);
}
static unsigned int clockDiffInMicroseconds(const LBCLOCK_t *start) {
  LBCLOCK_t end, interval;
  getClock(&end);
  timersub(&end, start, &interval);
  return (unsigned int) (interval.tv_sec/1e6 + interval.tv_usec);
}

#endif

#endif /* LBTIMESTAMP_H */
