Skip to content

Commit 9e0dd84

Browse files
committed
On Windows, use QueryPerformanceCounter instead of gettimeofday for
EXPLAIN ANALYZE instrumentation. Magnus Hagander
1 parent 354049c commit 9e0dd84

File tree

3 files changed

+72
-30
lines changed

3 files changed

+72
-30
lines changed

src/backend/commands/explain.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994-5, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.129 2004/12/31 21:59:41 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.130 2005/03/20 22:27:51 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -46,7 +46,7 @@ typedef struct ExplainState
4646

4747
static void ExplainOneQuery(Query *query, ExplainStmt *stmt,
4848
TupOutputState *tstate);
49-
static double elapsed_time(struct timeval * starttime);
49+
static double elapsed_time(instr_time * starttime);
5050
static void explain_outNode(StringInfo str,
5151
Plan *plan, PlanState *planstate,
5252
Plan *outer_plan,
@@ -212,12 +212,12 @@ void
212212
ExplainOnePlan(QueryDesc *queryDesc, ExplainStmt *stmt,
213213
TupOutputState *tstate)
214214
{
215-
struct timeval starttime;
215+
instr_time starttime;
216216
double totaltime = 0;
217217
ExplainState *es;
218218
StringInfo str;
219219

220-
gettimeofday(&starttime, NULL);
220+
INSTR_TIME_SET_CURRENT(starttime);
221221

222222
/* If analyzing, we need to cope with queued triggers */
223223
if (stmt->analyze)
@@ -275,7 +275,7 @@ ExplainOnePlan(QueryDesc *queryDesc, ExplainStmt *stmt,
275275
* Close down the query and free resources; also run any queued
276276
* AFTER triggers. Include time for this in the total runtime.
277277
*/
278-
gettimeofday(&starttime, NULL);
278+
INSTR_TIME_SET_CURRENT(starttime);
279279

280280
ExecutorEnd(queryDesc);
281281

@@ -303,23 +303,27 @@ ExplainOnePlan(QueryDesc *queryDesc, ExplainStmt *stmt,
303303
pfree(es);
304304
}
305305

306-
/* Compute elapsed time in seconds since given gettimeofday() timestamp */
306+
/* Compute elapsed time in seconds since given timestamp */
307307
static double
308-
elapsed_time(struct timeval * starttime)
308+
elapsed_time(instr_time * starttime)
309309
{
310-
struct timeval endtime;
310+
instr_time endtime;
311311

312-
gettimeofday(&endtime, NULL);
312+
INSTR_TIME_SET_CURRENT(endtime);
313313

314+
#ifndef WIN32
314315
endtime.tv_sec -= starttime->tv_sec;
315316
endtime.tv_usec -= starttime->tv_usec;
316317
while (endtime.tv_usec < 0)
317318
{
318319
endtime.tv_usec += 1000000;
319320
endtime.tv_sec--;
320321
}
321-
return (double) endtime.tv_sec +
322-
(double) endtime.tv_usec / 1000000.0;
322+
#else /* WIN32 */
323+
endtime.QuadPart -= starttime->QuadPart;
324+
#endif
325+
326+
return INSTR_TIME_GET_DOUBLE(endtime);
323327
}
324328

325329
/*

src/backend/executor/instrument.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.9 2005/01/01 05:43:06 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.10 2005/03/20 22:27:51 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -36,29 +36,30 @@ InstrStartNode(Instrumentation *instr)
3636
if (!instr)
3737
return;
3838

39-
if (instr->starttime.tv_sec != 0 || instr->starttime.tv_usec != 0)
39+
if (!INSTR_TIME_IS_ZERO(instr->starttime))
4040
elog(DEBUG2, "InstrStartNode called twice in a row");
4141
else
42-
gettimeofday(&instr->starttime, NULL);
42+
INSTR_TIME_SET_CURRENT(instr->starttime);
4343
}
4444

4545
/* Exit from a plan node */
4646
void
4747
InstrStopNode(Instrumentation *instr, bool returnedTuple)
4848
{
49-
struct timeval endtime;
49+
instr_time endtime;
5050

5151
if (!instr)
5252
return;
5353

54-
if (instr->starttime.tv_sec == 0 && instr->starttime.tv_usec == 0)
54+
if (INSTR_TIME_IS_ZERO(instr->starttime))
5555
{
5656
elog(DEBUG2, "InstrStopNode without start");
5757
return;
5858
}
5959

60-
gettimeofday(&endtime, NULL);
60+
INSTR_TIME_SET_CURRENT(endtime);
6161

62+
#ifndef WIN32
6263
instr->counter.tv_sec += endtime.tv_sec - instr->starttime.tv_sec;
6364
instr->counter.tv_usec += endtime.tv_usec - instr->starttime.tv_usec;
6465

@@ -73,16 +74,17 @@ InstrStopNode(Instrumentation *instr, bool returnedTuple)
7374
instr->counter.tv_usec -= 1000000;
7475
instr->counter.tv_sec++;
7576
}
77+
#else /* WIN32 */
78+
instr->counter.QuadPart += (endtime.QuadPart - instr->starttime.QuadPart);
79+
#endif
7680

77-
instr->starttime.tv_sec = 0;
78-
instr->starttime.tv_usec = 0;
81+
INSTR_TIME_SET_ZERO(instr->starttime);
7982

8083
/* Is this the first tuple of this cycle? */
8184
if (!instr->running)
8285
{
8386
instr->running = true;
84-
instr->firsttuple = (double) instr->counter.tv_sec +
85-
(double) instr->counter.tv_usec / 1000000.0;
87+
instr->firsttuple = INSTR_TIME_GET_DOUBLE(instr->counter);
8688
}
8789

8890
if (returnedTuple)
@@ -103,8 +105,7 @@ InstrEndLoop(Instrumentation *instr)
103105
return;
104106

105107
/* Accumulate statistics */
106-
totaltime = (double) instr->counter.tv_sec +
107-
(double) instr->counter.tv_usec / 1000000.0;
108+
totaltime = INSTR_TIME_GET_DOUBLE(instr->counter);
108109

109110
instr->startup += instr->firsttuple;
110111
instr->total += totaltime;
@@ -113,10 +114,8 @@ InstrEndLoop(Instrumentation *instr)
113114

114115
/* Reset for next cycle (if any) */
115116
instr->running = false;
116-
instr->starttime.tv_sec = 0;
117-
instr->starttime.tv_usec = 0;
118-
instr->counter.tv_sec = 0;
119-
instr->counter.tv_usec = 0;
117+
INSTR_TIME_SET_ZERO(instr->starttime);
118+
INSTR_TIME_SET_ZERO(instr->counter);
120119
instr->firsttuple = 0;
121120
instr->tuplecount = 0;
122121
}

src/include/executor/instrument.h

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
88
*
9-
* $PostgreSQL: pgsql/src/include/executor/instrument.h,v 1.8 2005/01/01 05:43:09 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/executor/instrument.h,v 1.9 2005/03/20 22:27:52 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -16,12 +16,51 @@
1616
#include <sys/time.h>
1717

1818

19+
/*
20+
* gettimeofday() does not have sufficient resolution on Windows,
21+
* so we must use QueryPerformanceCounter() instead. These macros
22+
* also give some breathing room to use other high-precision-timing APIs
23+
* on yet other platforms. (The macro-ization is not complete, however;
24+
* see subtraction code in instrument.c and explain.c.)
25+
*/
26+
#ifndef WIN32
27+
28+
typedef struct timeval instr_time;
29+
30+
#define INSTR_TIME_IS_ZERO(t) ((t).tv_sec == 0 && (t).tv_usec == 0)
31+
#define INSTR_TIME_SET_ZERO(t) ((t).tv_sec = 0, (t).tv_usec = 0)
32+
#define INSTR_TIME_SET_CURRENT(t) gettimeofday(&(t), NULL)
33+
#define INSTR_TIME_GET_DOUBLE(t) \
34+
(((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
35+
36+
#else /* WIN32 */
37+
38+
typedef LARGE_INTEGER instr_time;
39+
40+
#define INSTR_TIME_IS_ZERO(t) ((t).QuadPart == 0)
41+
#define INSTR_TIME_SET_ZERO(t) ((t).QuadPart = 0)
42+
#define INSTR_TIME_SET_CURRENT(t) QueryPerformanceCounter(&(t))
43+
#define INSTR_TIME_GET_DOUBLE(t) \
44+
(((double) (t).QuadPart) / GetTimerFrequency())
45+
46+
static __inline__ double
47+
GetTimerFrequency(void)
48+
{
49+
LARGE_INTEGER f;
50+
51+
QueryPerformanceFrequency(&f);
52+
return (double) f.QuadPart;
53+
}
54+
55+
#endif /* WIN32 */
56+
57+
1958
typedef struct Instrumentation
2059
{
2160
/* Info about current plan cycle: */
2261
bool running; /* TRUE if we've completed first tuple */
23-
struct timeval starttime; /* Start time of current iteration of node */
24-
struct timeval counter; /* Accumulates runtime for this node */
62+
instr_time starttime; /* Start time of current iteration of node */
63+
instr_time counter; /* Accumulates runtime for this node */
2564
double firsttuple; /* Time for first tuple of this cycle */
2665
double tuplecount; /* Tuples so far this cycle */
2766
/* Accumulated statistics across all completed cycles: */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy