#ifndef INSTR_TIME_H
#define INSTR_TIME_H
#ifndef WIN32
#ifdef HAVE_CLOCK_GETTIME
#include <time.h>
#if defined(__darwin__) && defined(CLOCK_MONOTONIC_RAW)
#define PG_INSTR_CLOCK CLOCK_MONOTONIC_RAW
#elif defined(CLOCK_MONOTONIC)
#define PG_INSTR_CLOCK CLOCK_MONOTONIC
#else
#define PG_INSTR_CLOCK CLOCK_REALTIME
#endif
typedef struct timespec instr_time;
#define INSTR_TIME_IS_ZERO(t) ((t).tv_nsec == 0 && (t).tv_sec == 0)
#define INSTR_TIME_SET_ZERO(t) ((t).tv_sec = 0, (t).tv_nsec = 0)
#define INSTR_TIME_SET_CURRENT(t) ((void) clock_gettime(PG_INSTR_CLOCK, &(t)))
#define INSTR_TIME_ADD(x,y) \
do { \
(x).tv_sec += (y).tv_sec; \
(x).tv_nsec += (y).tv_nsec; \
\
while ((x).tv_nsec >= 1000000000) \
{ \
(x).tv_nsec -= 1000000000; \
(x).tv_sec++; \
} \
} while (0)
#define INSTR_TIME_SUBTRACT(x,y) \
do { \
(x).tv_sec -= (y).tv_sec; \
(x).tv_nsec -= (y).tv_nsec; \
\
while ((x).tv_nsec < 0) \
{ \
(x).tv_nsec += 1000000000; \
(x).tv_sec--; \
} \
} while (0)
#define INSTR_TIME_ACCUM_DIFF(x,y,z) \
do { \
(x).tv_sec += (y).tv_sec - (z).tv_sec; \
(x).tv_nsec += (y).tv_nsec - (z).tv_nsec; \
\
while ((x).tv_nsec < 0) \
{ \
(x).tv_nsec += 1000000000; \
(x).tv_sec--; \
} \
while ((x).tv_nsec >= 1000000000) \
{ \
(x).tv_nsec -= 1000000000; \
(x).tv_sec++; \
} \
} while (0)
#define INSTR_TIME_GET_DOUBLE(t) \
(((double) (t).tv_sec) + ((double) (t).tv_nsec) / 1000000000.0)
#define INSTR_TIME_GET_MILLISEC(t) \
(((double) (t).tv_sec * 1000.0) + ((double) (t).tv_nsec) / 1000000.0)
#define INSTR_TIME_GET_MICROSEC(t) \
(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) ((t).tv_nsec / 1000))
#else
#include <sys/time.h>
typedef struct timeval instr_time;
#define INSTR_TIME_IS_ZERO(t) ((t).tv_usec == 0 && (t).tv_sec == 0)
#define INSTR_TIME_SET_ZERO(t) ((t).tv_sec = 0, (t).tv_usec = 0)
#define INSTR_TIME_SET_CURRENT(t) gettimeofday(&(t), NULL)
#define INSTR_TIME_ADD(x,y) \
do { \
(x).tv_sec += (y).tv_sec; \
(x).tv_usec += (y).tv_usec; \
\
while ((x).tv_usec >= 1000000) \
{ \
(x).tv_usec -= 1000000; \
(x).tv_sec++; \
} \
} while (0)
#define INSTR_TIME_SUBTRACT(x,y) \
do { \
(x).tv_sec -= (y).tv_sec; \
(x).tv_usec -= (y).tv_usec; \
\
while ((x).tv_usec < 0) \
{ \
(x).tv_usec += 1000000; \
(x).tv_sec--; \
} \
} while (0)
#define INSTR_TIME_ACCUM_DIFF(x,y,z) \
do { \
(x).tv_sec += (y).tv_sec - (z).tv_sec; \
(x).tv_usec += (y).tv_usec - (z).tv_usec; \
\
while ((x).tv_usec < 0) \
{ \
(x).tv_usec += 1000000; \
(x).tv_sec--; \
} \
while ((x).tv_usec >= 1000000) \
{ \
(x).tv_usec -= 1000000; \
(x).tv_sec++; \
} \
} while (0)
#define INSTR_TIME_GET_DOUBLE(t) \
(((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
#define INSTR_TIME_GET_MILLISEC(t) \
(((double) (t).tv_sec * 1000.0) + ((double) (t).tv_usec) / 1000.0)
#define INSTR_TIME_GET_MICROSEC(t) \
(((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) (t).tv_usec)
#endif
#else
typedef LARGE_INTEGER instr_time;
#define INSTR_TIME_IS_ZERO(t) ((t).QuadPart == 0)
#define INSTR_TIME_SET_ZERO(t) ((t).QuadPart = 0)
#define INSTR_TIME_SET_CURRENT(t) QueryPerformanceCounter(&(t))
#define INSTR_TIME_ADD(x,y) \
((x).QuadPart += (y).QuadPart)
#define INSTR_TIME_SUBTRACT(x,y) \
((x).QuadPart -= (y).QuadPart)
#define INSTR_TIME_ACCUM_DIFF(x,y,z) \
((x).QuadPart += (y).QuadPart - (z).QuadPart)
#define INSTR_TIME_GET_DOUBLE(t) \
(((double) (t).QuadPart) / GetTimerFrequency())
#define INSTR_TIME_GET_MILLISEC(t) \
(((double) (t).QuadPart * 1000.0) / GetTimerFrequency())
#define INSTR_TIME_GET_MICROSEC(t) \
((uint64) (((double) (t).QuadPart * 1000000.0) / GetTimerFrequency()))
static inline double
GetTimerFrequency(void)
{
LARGE_INTEGER f;
QueryPerformanceFrequency(&f);
return (double) f.QuadPart;
}
#endif
#define INSTR_TIME_SET_CURRENT_LAZY(t) \
(INSTR_TIME_IS_ZERO(t) ? INSTR_TIME_SET_CURRENT(t), true : false)
#endif