#ifndef PORTS_SYS_CLOCKTIMER_H
#define PORTS_SYS_CLOCKTIMER_H

#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

#define PORTS_Num_ClockTimer() 2

#define PORTS_ClockTimerTerm() PORTS_CLOCKTIMER_SUCCESS


/* -- Clock 0: gethrtime() -- */

typedef hrtime_t PORTS_Clock0_t;

struct PORTS_T0_t {
  int count;
  PORTS_Clock0_t sum;
  PORTS_Clock0_t clk;
};

typedef struct PORTS_T0_t *PORTS_Timer0_t;

#define PORTS_TimerStart0(t) (t)->clk = gethrtime()

#define PORTS_TimerStop0(t) (t)->count++, (t)->sum += (gethrtime() - (t)->clk)

#define PORTS_Clock0(c) c  = gethrtime()

#define PORTS_ClockToSeconds0(c) (c * 1.0e-9)

#define PORTS_TimerInit0(t) PORTS_TimerInitInternal0(&t)

#ifdef __cplusplus
extern "C" {
#endif

extern int PORTS_ClockTimerInit(int *argc, char **argv);

extern int PORTS_TimerInitInternal0(PORTS_Timer0_t *t);

extern int PORTS_TimerDestroy0(PORTS_Timer0_t t);

extern int PORTS_TimerReset0(PORTS_Timer0_t t);

extern double PORTS_TimerElapsed0(PORTS_Timer0_t t, int *c);

#ifdef __cplusplus
}
#endif


/* -- Clock 1: gettimeofday() -- */

typedef struct timeval PORTS_Clock1_t;

struct PORTS_T1_t {
  int count;
  PORTS_Clock1_t sum;
  PORTS_Clock1_t clk;
};

typedef struct PORTS_T1_t *PORTS_Timer1_t;

#define PORTS_TimerStart1(t) gettimeofday(&((t)->clk),0)

#define PORTS_TimerStop1(t) \
  do { \
    struct timeval x; \
    gettimeofday(&x,0); \
    (t)->count++; \
    (t)->sum.tv_sec += x.tv_sec - (t)->clk.tv_sec; \
    (t)->sum.tv_usec += x.tv_usec - (t)->clk.tv_usec; \
  } while (0)

#define PORTS_Clock1(c) gettimeofday(&c,0)

#define PORTS_ClockToSeconds1(c) (c.tv_sec + c.tv_usec * 1.0e-6)

#define PORTS_TimerInit1(t) PORTS_TimerInitInternal1(&t)

#ifdef __cplusplus
extern "C" {
#endif

extern int PORTS_TimerInitInternal1(PORTS_Timer1_t *t);

extern int PORTS_TimerDestroy1(PORTS_Timer1_t t);

extern int PORTS_TimerReset1(PORTS_Timer1_t t);

extern double PORTS_TimerElapsed1(PORTS_Timer1_t t, int *c);

#ifdef __cplusplus
}
#endif
#endif
