diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/explain.c | 16 | ||||
-rw-r--r-- | src/backend/executor/instrument.c | 22 | ||||
-rw-r--r-- | src/bin/psql/command.c | 16 | ||||
-rw-r--r-- | src/bin/psql/common.c | 36 | ||||
-rw-r--r-- | src/bin/psql/common.h | 34 | ||||
-rw-r--r-- | src/include/Makefile | 5 | ||||
-rw-r--r-- | src/include/executor/instrument.h | 41 | ||||
-rw-r--r-- | src/include/portability/instr_time.h | 139 |
8 files changed, 178 insertions, 131 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 6fbdabd1d2b..0892cdbe3eb 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -7,7 +7,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -390,19 +390,7 @@ elapsed_time(instr_time *starttime) 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); } diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c index fa0a7f7b507..b83d6f5d32c 100644 --- a/src/backend/executor/instrument.c +++ b/src/backend/executor/instrument.c @@ -7,7 +7,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -55,25 +55,7 @@ InstrStopNode(Instrumentation *instr, double nTuples) } 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); diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index f74ce951409..b86d67e9281 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * 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" @@ -30,6 +30,8 @@ #include <sys/stat.h> /* for stat() */ #endif +#include "portability/instr_time.h" + #include "libpq-fe.h" #include "pqexpbuffer.h" #include "dumputils.h" @@ -282,24 +284,22 @@ exec_command(const char *cmd, 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); diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 72aad262f5a..ab1f03f3109 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -3,7 +3,7 @@ * * 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" @@ -17,6 +17,8 @@ #include <win32.h> #endif +#include "portability/instr_time.h" + #include "pqsignal.h" #include "settings.h" @@ -844,11 +846,11 @@ SendQuery(const char *query) 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); @@ -858,8 +860,9 @@ SendQuery(const char *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: */ @@ -961,7 +964,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) bool did_pager = false; int ntuples; char fetch_cmd[64]; - TimevalStruct before, + instr_time before, after; *elapsed_msec = 0; @@ -972,7 +975,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) 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) @@ -1001,8 +1004,9 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) 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), @@ -1028,15 +1032,16 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) 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) @@ -1112,7 +1117,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) 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 @@ -1137,8 +1142,9 @@ cleanup: 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; diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index c8cefe1843f..7977eb5493c 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -3,7 +3,7 @@ * * 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 @@ -63,36 +63,4 @@ extern const char *session_username(void); 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 */ diff --git a/src/include/Makefile b/src/include/Makefile index 01a046f4fcc..a37414b6991 100644 --- a/src/include/Makefile +++ b/src/include/Makefile @@ -4,7 +4,7 @@ # # '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 $ # #------------------------------------------------------------------------- @@ -21,7 +21,8 @@ SUBDIRS = access bootstrap catalog commands executor lib libpq mb \ 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 diff --git a/src/include/executor/instrument.h b/src/include/executor/instrument.h index 6889e9c0eb4..080e264629b 100644 --- a/src/include/executor/instrument.h +++ b/src/include/executor/instrument.h @@ -6,51 +6,14 @@ * * 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 diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h new file mode 100644 index 00000000000..666d495f203 --- /dev/null +++ b/src/include/portability/instr_time.h @@ -0,0 +1,139 @@ +/*------------------------------------------------------------------------- + * + * 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 */ |