]> granicus.if.org Git - postgresql/commitdiff
Move the "instr_time" typedef and associated macros into a new header
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 14 May 2008 19:10:29 +0000 (19:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 14 May 2008 19:10:29 +0000 (19:10 +0000)
file portability/instr_time.h, and add a couple more macros to eliminate
some abstraction leakage we formerly had.  Also update psql to use this
header instead of its own copy of nearly the same code.

This commit in itself is just code cleanup and shouldn't change anything.
It lays some groundwork for the upcoming function-stats patch, though.

src/backend/commands/explain.c
src/backend/executor/instrument.c
src/bin/psql/command.c
src/bin/psql/common.c
src/bin/psql/common.h
src/include/Makefile
src/include/executor/instrument.h
src/include/portability/instr_time.h [new file with mode: 0644]

index 6fbdabd1d2baa5ab439f6dedeaa3c8d7a615ae53..0892cdbe3eb29f58de7fb91d18a32babd16c595d 100644 (file)
@@ -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);
 }
 
index fa0a7f7b507de15242846418de116d6e168c62d0..b83d6f5d32c021a9ea199a11e556a0021dff6081 100644 (file)
@@ -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);
 
index f74ce95140970eaeab11cbcf934bc1ab86b57f75..b86d67e92814189ecc8f9b3ca71f7b9617936749 100644 (file)
@@ -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);
index 72aad262f5af02c974b83d9e1073e61c423e5697..ab1f03f310980dc614dcd1a66f27772e5796e6ff 100644 (file)
@@ -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;
index c8cefe1843f2a29418e315a9775042df39ba0705..7977eb5493c0c39f8ce68b0287d417a299fb2f42 100644 (file)
@@ -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 */
index 01a046f4fccc30d1a10b3e1aa123424ce9bbbd43..a37414b69914de71142aa142193674a2ff82cae5 100644 (file)
@@ -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
index 6889e9c0eb4b771cd370a68fbf3df72317af5d4b..080e264629bb126c55edaf81f44f55667778126a 100644 (file)
@@ -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 (file)
index 0000000..666d495
--- /dev/null
@@ -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 */