123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /*-------------------------------------------------------------------------
- *
- * instr_time.h
- * portable high-precision interval timing
- *
- * This file provides an abstraction layer to hide portability issues in
- * interval timing. On Unix we use gettimeofday(), but on Windows that
- * gives a low-precision result so we must use QueryPerformanceCounter()
- * instead. These macros also give some breathing room to use other
- * high-precision-timing APIs on yet other platforms.
- *
- * The basic data type is instr_time, which all callers should treat as an
- * opaque typedef. instr_time can store either an absolute time (of
- * unspecified reference time) or an interval. The operations provided
- * for it are:
- *
- * INSTR_TIME_IS_ZERO(t) is t equal to zero?
- *
- * INSTR_TIME_SET_ZERO(t) set t to zero (memset is acceptable too)
- *
- * INSTR_TIME_SET_CURRENT(t) set t to current time
- *
- * INSTR_TIME_ADD(x, y) x += y
- *
- * INSTR_TIME_SUBTRACT(x, y) x -= y
- *
- * INSTR_TIME_ACCUM_DIFF(x, y, z) x += (y - z)
- *
- * INSTR_TIME_GET_DOUBLE(t) convert t to double (in seconds)
- *
- * INSTR_TIME_GET_MILLISEC(t) convert t to double (in milliseconds)
- *
- * INSTR_TIME_GET_MICROSEC(t) convert t to uint64 (in microseconds)
- *
- * Note that INSTR_TIME_SUBTRACT and INSTR_TIME_ACCUM_DIFF convert
- * absolute times to intervals. The INSTR_TIME_GET_xxx operations are
- * only useful on intervals.
- *
- * When summing multiple measurements, it's recommended to leave the
- * running sum in instr_time form (ie, use INSTR_TIME_ADD or
- * INSTR_TIME_ACCUM_DIFF) and convert to a result format only at the end.
- *
- * Beware of multiple evaluations of the macro arguments.
- *
- *
- * Copyright (c) 2001-2016, PostgreSQL Global Development Group
- *
- * src/include/portability/instr_time.h
- *
- *-------------------------------------------------------------------------
- */
- #ifndef INSTR_TIME_H
- #define INSTR_TIME_H
- #ifndef WIN32
- #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; \
- /* Normalize */ \
- 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; \
- /* Normalize */ \
- 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; \
- /* Normalize after each add to avoid overflow/underflow of 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)
- #else /* WIN32 */
- 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 /* WIN32 */
- #endif /* INSTR_TIME_H */
|