* Portions Copyright (c) 1994-5, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.174 2008/05/12 20:01:59 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.175 2008/05/14 19:10:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
instr_time endtime;
INSTR_TIME_SET_CURRENT(endtime);
-
-#ifndef WIN32
- endtime.tv_sec -= starttime->tv_sec;
- endtime.tv_usec -= starttime->tv_usec;
- while (endtime.tv_usec < 0)
- {
- endtime.tv_usec += 1000000;
- endtime.tv_sec--;
- }
-#else /* WIN32 */
- endtime.QuadPart -= starttime->QuadPart;
-#endif
-
+ INSTR_TIME_SUBTRACT(endtime, *starttime);
return INSTR_TIME_GET_DOUBLE(endtime);
}
* Copyright (c) 2001-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.20 2008/01/01 19:45:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.21 2008/05/14 19:10:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
}
INSTR_TIME_SET_CURRENT(endtime);
-
-#ifndef WIN32
- instr->counter.tv_sec += endtime.tv_sec - instr->starttime.tv_sec;
- instr->counter.tv_usec += endtime.tv_usec - instr->starttime.tv_usec;
-
- /* Normalize after each add to avoid overflow/underflow of tv_usec */
- while (instr->counter.tv_usec < 0)
- {
- instr->counter.tv_usec += 1000000;
- instr->counter.tv_sec--;
- }
- while (instr->counter.tv_usec >= 1000000)
- {
- instr->counter.tv_usec -= 1000000;
- instr->counter.tv_sec++;
- }
-#else /* WIN32 */
- instr->counter.QuadPart += (endtime.QuadPart - instr->starttime.QuadPart);
-#endif
+ INSTR_TIME_ACCUM_DIFF(instr->counter, endtime, instr->starttime);
INSTR_TIME_SET_ZERO(instr->starttime);
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.188 2008/05/08 17:04:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.189 2008/05/14 19:10:29 tgl Exp $
*/
#include "postgres_fe.h"
#include "command.h"
#include <sys/stat.h> /* for stat() */
#endif
+#include "portability/instr_time.h"
+
#include "libpq-fe.h"
#include "pqexpbuffer.h"
#include "dumputils.h"
else if (pg_strcasecmp(cmd, "copy") == 0)
{
/* Default fetch-it-all-and-print mode */
- TimevalStruct before,
+ instr_time before,
after;
- double elapsed_msec = 0;
char *opt = psql_scan_slash_option(scan_state,
OT_WHOLE_LINE, NULL, false);
if (pset.timing)
- GETTIMEOFDAY(&before);
+ INSTR_TIME_SET_CURRENT(before);
success = do_copy(opt);
if (pset.timing && success)
{
- GETTIMEOFDAY(&after);
- elapsed_msec = DIFF_MSEC(&after, &before);
- printf(_("Time: %.3f ms\n"), elapsed_msec);
-
+ INSTR_TIME_SET_CURRENT(after);
+ INSTR_TIME_SUBTRACT(after, before);
+ printf(_("Time: %.3f ms\n"), INSTR_TIME_GET_MILLISEC(after));
}
free(opt);
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.138 2008/01/01 19:45:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.139 2008/05/14 19:10:29 tgl Exp $
*/
#include "postgres_fe.h"
#include "common.h"
#include <win32.h>
#endif
+#include "portability/instr_time.h"
+
#include "pqsignal.h"
#include "settings.h"
if (pset.fetch_count <= 0 || !is_select_command(query))
{
/* Default fetch-it-all-and-print mode */
- TimevalStruct before,
+ instr_time before,
after;
if (pset.timing)
- GETTIMEOFDAY(&before);
+ INSTR_TIME_SET_CURRENT(before);
results = PQexec(pset.db, query);
if (pset.timing)
{
- GETTIMEOFDAY(&after);
- elapsed_msec = DIFF_MSEC(&after, &before);
+ INSTR_TIME_SET_CURRENT(after);
+ INSTR_TIME_SUBTRACT(after, before);
+ elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
}
/* but printing results isn't: */
bool did_pager = false;
int ntuples;
char fetch_cmd[64];
- TimevalStruct before,
+ instr_time before,
after;
*elapsed_msec = 0;
my_popt.topt.prior_records = 0;
if (pset.timing)
- GETTIMEOFDAY(&before);
+ INSTR_TIME_SET_CURRENT(before);
/* if we're not in a transaction, start one */
if (PQtransactionStatus(pset.db) == PQTRANS_IDLE)
if (pset.timing)
{
- GETTIMEOFDAY(&after);
- *elapsed_msec += DIFF_MSEC(&after, &before);
+ INSTR_TIME_SET_CURRENT(after);
+ INSTR_TIME_SUBTRACT(after, before);
+ *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
}
snprintf(fetch_cmd, sizeof(fetch_cmd),
for (;;)
{
if (pset.timing)
- GETTIMEOFDAY(&before);
+ INSTR_TIME_SET_CURRENT(before);
/* get FETCH_COUNT tuples at a time */
results = PQexec(pset.db, fetch_cmd);
if (pset.timing)
{
- GETTIMEOFDAY(&after);
- *elapsed_msec += DIFF_MSEC(&after, &before);
+ INSTR_TIME_SET_CURRENT(after);
+ INSTR_TIME_SUBTRACT(after, before);
+ *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
}
if (PQresultStatus(results) != PGRES_TUPLES_OK)
cleanup:
if (pset.timing)
- GETTIMEOFDAY(&before);
+ INSTR_TIME_SET_CURRENT(before);
/*
* We try to close the cursor on either success or failure, but on failure
if (pset.timing)
{
- GETTIMEOFDAY(&after);
- *elapsed_msec += DIFF_MSEC(&after, &before);
+ INSTR_TIME_SET_CURRENT(after);
+ INSTR_TIME_SUBTRACT(after, before);
+ *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
}
return OK;
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/common.h,v 1.56 2008/01/01 19:45:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/common.h,v 1.57 2008/05/14 19:10:29 tgl Exp $
*/
#ifndef COMMON_H
#define COMMON_H
extern char *expand_tilde(char **filename);
-#ifndef WIN32
-
-#include <sys/time.h>
-
-typedef struct timeval TimevalStruct;
-
-#define GETTIMEOFDAY(T) gettimeofday(T, NULL)
-#define DIFF_MSEC(T, U) \
- ((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \
- ((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0)
-#else
-/*
- * To get good resolution (better than ~15ms) on Windows, use
- * the high resolution performance counters. They can't be used
- * to get absolute times, but are good for measuring differences.
- */
-static __inline__ double
-GetTimerFrequency(void)
-{
- LARGE_INTEGER f;
-
- QueryPerformanceFrequency(&f);
- return (double) f.QuadPart;
-}
-
-typedef LARGE_INTEGER TimevalStruct;
-
-#define GETTIMEOFDAY(T) QueryPerformanceCounter((T))
-#define DIFF_MSEC(T, U) \
- (((T)->QuadPart - (U)->QuadPart) * 1000.0 / GetTimerFrequency())
-#endif /* WIN32 */
-
#endif /* COMMON_H */
#
# 'make install' installs whole contents of src/include.
#
-# $PostgreSQL: pgsql/src/include/Makefile,v 1.24 2008/03/17 19:44:41 petere Exp $
+# $PostgreSQL: pgsql/src/include/Makefile,v 1.25 2008/05/14 19:10:29 tgl Exp $
#
#-------------------------------------------------------------------------
nodes optimizer parser postmaster regex rewrite storage tcop \
snowball snowball/libstemmer tsearch tsearch/dicts utils \
port port/win32 port/win32_msvc port/win32_msvc/sys \
- port/win32/arpa port/win32/netinet port/win32/sys
+ port/win32/arpa port/win32/netinet port/win32/sys \
+ portability
# Install all headers
install: all installdirs
*
* Copyright (c) 2001-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/executor/instrument.h,v 1.18 2008/01/01 19:45:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/executor/instrument.h,v 1.19 2008/05/14 19:10:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef INSTRUMENT_H
#define INSTRUMENT_H
-#include <sys/time.h>
-
-
-/*
- * gettimeofday() does not have sufficient resolution on Windows,
- * 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 macro-ization is not complete, however;
- * see subtraction code in instrument.c and explain.c.)
- */
-#ifndef WIN32
-
-typedef struct timeval instr_time;
-
-#define INSTR_TIME_IS_ZERO(t) ((t).tv_sec == 0 && (t).tv_usec == 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_GET_DOUBLE(t) \
- (((double) (t).tv_sec) + ((double) (t).tv_usec) / 1000000.0)
-#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_GET_DOUBLE(t) \
- (((double) (t).QuadPart) / GetTimerFrequency())
-
-static __inline__ double
-GetTimerFrequency(void)
-{
- LARGE_INTEGER f;
-
- QueryPerformanceFrequency(&f);
- return (double) f.QuadPart;
-}
-#endif /* WIN32 */
+#include "portability/instr_time.h"
typedef struct Instrumentation
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * 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_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_ACCUM_DIFF) and
+ * convert to a result format only at the end.
+ *
+ * Beware of multiple evaluations of the macro arguments.
+ *
+ *
+ * Copyright (c) 2001-2008, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/portability/instr_time.h,v 1.1 2008/05/14 19:10:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#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_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_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 */