Fix obsolete comment regarding FSM truncation.
[PostgreSQL.git] / src / include / portability / instr_time.h
blob1b7fc7c13e414859234d54864f1774f4c441dc47
1 /*-------------------------------------------------------------------------
3 * instr_time.h
4 * portable high-precision interval timing
6 * This file provides an abstraction layer to hide portability issues in
7 * interval timing. On Unix we use gettimeofday(), but on Windows that
8 * gives a low-precision result so we must use QueryPerformanceCounter()
9 * instead. These macros also give some breathing room to use other
10 * high-precision-timing APIs on yet other platforms.
12 * The basic data type is instr_time, which all callers should treat as an
13 * opaque typedef. instr_time can store either an absolute time (of
14 * unspecified reference time) or an interval. The operations provided
15 * for it are:
17 * INSTR_TIME_IS_ZERO(t) is t equal to zero?
19 * INSTR_TIME_SET_ZERO(t) set t to zero (memset is acceptable too)
21 * INSTR_TIME_SET_CURRENT(t) set t to current time
23 * INSTR_TIME_ADD(x, y) x += y
25 * INSTR_TIME_SUBTRACT(x, y) x -= y
27 * INSTR_TIME_ACCUM_DIFF(x, y, z) x += (y - z)
29 * INSTR_TIME_GET_DOUBLE(t) convert t to double (in seconds)
31 * INSTR_TIME_GET_MILLISEC(t) convert t to double (in milliseconds)
33 * INSTR_TIME_GET_MICROSEC(t) convert t to uint64 (in microseconds)
35 * Note that INSTR_TIME_SUBTRACT and INSTR_TIME_ACCUM_DIFF convert
36 * absolute times to intervals. The INSTR_TIME_GET_xxx operations are
37 * only useful on intervals.
39 * When summing multiple measurements, it's recommended to leave the
40 * running sum in instr_time form (ie, use INSTR_TIME_ADD or
41 * INSTR_TIME_ACCUM_DIFF) and convert to a result format only at the end.
43 * Beware of multiple evaluations of the macro arguments.
46 * Copyright (c) 2001-2008, PostgreSQL Global Development Group
48 * $PostgreSQL$
50 *-------------------------------------------------------------------------
52 #ifndef INSTR_TIME_H
53 #define INSTR_TIME_H
55 #ifndef WIN32
57 #include <sys/time.h>
59 typedef struct timeval instr_time;
61 #define INSTR_TIME_IS_ZERO(t) ((t).tv_usec == 0 && (t).tv_sec == 0)
63 #define INSTR_TIME_SET_ZERO(t) ((t).tv_sec = 0, (t).tv_usec = 0)
65 #define INSTR_TIME_SET_CURRENT(t) gettimeofday(&(t), NULL)
67 #define INSTR_TIME_ADD(x,y) \
68 do { \
69 (x).tv_sec += (y).tv_sec; \
70 (x).tv_usec += (y).tv_usec; \
71 /* Normalize */ \
72 while ((x).tv_usec >= 1000000) \
73 { \
74 (x).tv_usec -= 1000000; \
75 (x).tv_sec++; \
76 } \
77 } while (0)
79 #define INSTR_TIME_SUBTRACT(x,y) \
80 do { \
81 (x).tv_sec -= (y).tv_sec; \
82 (x).tv_usec -= (y).tv_usec; \
83 /* Normalize */ \
84 while ((x).tv_usec < 0) \
85 { \
86 (x).tv_usec += 1000000; \
87 (x).tv_sec--; \
88 } \
89 } while (0)
91 #define INSTR_TIME_ACCUM_DIFF(x,y,z) \
92 do { \
93 (x).tv_sec += (y).tv_sec - (z).tv_sec; \
94 (x).tv_usec += (y).tv_usec - (z).tv_usec; \
95 /* Normalize after each add to avoid overflow/underflow of tv_usec */ \
96 while ((x).tv_usec < 0) \
97 { \
98 (x).tv_usec += 1000000; \
99 (x).tv_sec--; \
101 while ((x).tv_usec >= 1000000) \
103 (x).tv_usec -= 1000000; \
104 (x).tv_sec++; \
106 } while (0)
108 #define INSTR_TIME_GET_DOUBLE(t) \
109 (((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
111 #define INSTR_TIME_GET_MILLISEC(t) \
112 (((double) (t).tv_sec * 1000.0) + ((double) (t).tv_usec) / 1000.0)
114 #define INSTR_TIME_GET_MICROSEC(t) \
115 (((uint64) (t).tv_sec * (uint64) 1000000) + (uint64) (t).tv_usec)
117 #else /* WIN32 */
119 typedef LARGE_INTEGER instr_time;
121 #define INSTR_TIME_IS_ZERO(t) ((t).QuadPart == 0)
123 #define INSTR_TIME_SET_ZERO(t) ((t).QuadPart = 0)
125 #define INSTR_TIME_SET_CURRENT(t) QueryPerformanceCounter(&(t))
127 #define INSTR_TIME_ADD(x,y) \
128 ((x).QuadPart += (y).QuadPart)
130 #define INSTR_TIME_SUBTRACT(x,y) \
131 ((x).QuadPart -= (y).QuadPart)
133 #define INSTR_TIME_ACCUM_DIFF(x,y,z) \
134 ((x).QuadPart += (y).QuadPart - (z).QuadPart)
136 #define INSTR_TIME_GET_DOUBLE(t) \
137 (((double) (t).QuadPart) / GetTimerFrequency())
139 #define INSTR_TIME_GET_MILLISEC(t) \
140 (((double) (t).QuadPart * 1000.0) / GetTimerFrequency())
142 #define INSTR_TIME_GET_MICROSEC(t) \
143 ((uint64) (((double) (t).QuadPart * 1000000.0) / GetTimerFrequency()))
145 static __inline__ double
146 GetTimerFrequency(void)
148 LARGE_INTEGER f;
150 QueryPerformanceFrequency(&f);
151 return (double) f.QuadPart;
154 #endif /* WIN32 */
156 #endif /* INSTR_TIME_H */