]> granicus.if.org Git - postgresql/commitdiff
Portability and documentation fixes for threaded pgbench patch.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Aug 2009 18:30:55 +0000 (18:30 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Aug 2009 18:30:55 +0000 (18:30 +0000)
contrib/pgbench/Makefile
contrib/pgbench/pgbench.c
doc/src/sgml/pgbench.sgml

index d13cb7405a4243469c0a65253fe10323ceb62a9e..0570705dad5be04c867eb5642393aeb3ffc78403 100644 (file)
@@ -1,10 +1,10 @@
-# $PostgreSQL: pgsql/contrib/pgbench/Makefile,v 1.16 2007/11/10 23:59:51 momjian Exp $
+# $PostgreSQL: pgsql/contrib/pgbench/Makefile,v 1.17 2009/08/03 18:30:55 tgl Exp $
 
 PROGRAM = pgbench
 OBJS   = pgbench.o
 
 PG_CPPFLAGS = -I$(libpq_srcdir)
-PG_LIBS = $(libpq_pgport)
+PG_LIBS = $(libpq_pgport) $(PTHREAD_LIBS)
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
@@ -16,3 +16,7 @@ top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 include $(top_srcdir)/contrib/contrib-global.mk
 endif
+
+ifneq ($(PORTNAME), win32)
+override CFLAGS += $(PTHREAD_CFLAGS)
+endif
index 0c3704a2ff14dad5749ef2e96b8eafa7aec2c32a..aafc64e3ce899c14fd642b8ac4eb908744bb9df9 100644 (file)
@@ -4,7 +4,7 @@
  * A simple benchmark program for PostgreSQL
  * Originally written by Tatsuo Ishii and enhanced by many contributors.
  *
- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.89 2009/08/03 15:18:14 ishii Exp $
+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.90 2009/08/03 18:30:55 tgl Exp $
  * Copyright (c) 2000-2009, PostgreSQL Global Development Group
  * ALL RIGHTS RESERVED;
  *
 /* Use native win32 threads on Windows */
 typedef struct win32_pthread   *pthread_t;
 typedef int                                            pthread_attr_t;
+
 static int pthread_create(pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void *arg);
 static int pthread_join(pthread_t th, void **thread_return);
 
 #elif defined(ENABLE_THREAD_SAFETY)
-/* Use platform-dependent pthread */
+/* Use platform-dependent pthread capability */
 #include <pthread.h>
 
 #else
+/* Use emulation with fork. Rename pthread identifiers to avoid conflicts */
 
 #include <sys/wait.h>
-/* Use emulation with fork. Rename pthread idendifiers to avoid conflictions */
+
 #define pthread_t                              pg_pthread_t
 #define pthread_attr_t                 pg_pthread_attr_t
 #define pthread_create                 pg_pthread_create
 #define pthread_join                   pg_pthread_join
+
 typedef struct fork_pthread       *pthread_t;
 typedef int                                            pthread_attr_t;
+
 static int pthread_create(pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void *arg);
 static int pthread_join(pthread_t th, void **thread_return);
 
@@ -136,7 +140,7 @@ FILE           *LOGFILE = NULL;
 
 bool           use_log;                        /* log transaction latencies to a file */
 
-int                    is_connect;                     /* establish connection  for each transaction */
+int                    is_connect;                     /* establish connection for each transaction */
 
 char      *pghost = "";
 char      *pgport = "";
@@ -185,7 +189,7 @@ typedef struct
 {
        pthread_t               thread;         /* thread handle */
        CState             *state;              /* array of CState */
-       int                             nstate;         /* length of state */
+       int                             nstate;         /* length of state[] */
        instr_time              start_time;     /* thread start time */
 } TState;
 
@@ -647,20 +651,25 @@ top:
                 */
                if (use_log && commands[st->state + 1] == NULL)
                {
+                       instr_time      now;
                        instr_time      diff;
-                       double          sec;
-                       double          msec;
                        double          usec;
 
-                       INSTR_TIME_SET_CURRENT(diff);
+                       INSTR_TIME_SET_CURRENT(now);
+                       diff = now;
                        INSTR_TIME_SUBTRACT(diff, st->txn_begin);
-                       sec = INSTR_TIME_GET_DOUBLE(diff);
-                       msec = INSTR_TIME_GET_MILLISEC(diff);
                        usec = (double) INSTR_TIME_GET_MICROSEC(diff);
 
-                       fprintf(LOGFILE, "%d %d %.0f %d %.0f %.0f\n",
+#ifndef WIN32
+                       /* This is more than we really ought to know about instr_time */
+                       fprintf(LOGFILE, "%d %d %.0f %d %ld %ld\n",
                                        st->id, st->cnt, usec, st->use_file,
-                                       sec, usec - sec * 1000.0);
+                                       (long) now.tv_sec, (long) now.tv_usec);
+#else
+                       /* On Windows, instr_time doesn't provide a timestamp anyway */
+                       fprintf(LOGFILE, "%d %d %.0f %d 0 0\n",
+                                       st->id, st->cnt, usec, st->use_file);
+#endif
                }
 
                if (commands[st->state]->type == SQL_COMMAND)
@@ -1269,15 +1278,17 @@ process_commands(char *buf)
                        }
 
                        /*
-                        * Split argument into number and unit for "sleep 1ms" or so.
+                        * Split argument into number and unit to allow "sleep 1ms" etc.
                         * We don't have to terminate the number argument with null
-                        * because it will parsed with atoi, that ignores trailing
+                        * because it will be parsed with atoi, which ignores trailing
                         * non-digit characters.
                         */
                        if (my_commands->argv[1][0] != ':')
                        {
                                char    *c = my_commands->argv[1];
-                               while (isdigit(*c)) { c++; }
+
+                               while (isdigit((unsigned char) *c))
+                                       c++;
                                if (*c)
                                {
                                        my_commands->argv[2] = c;
@@ -1772,7 +1783,7 @@ main(int argc, char **argv)
 
        if (nclients % nthreads != 0)
        {
-               fprintf(stderr, "number of clients (%d) must be a multiple number of threads (%d)\n", nclients, nthreads);
+               fprintf(stderr, "number of clients (%d) must be a multiple of number of threads (%d)\n", nclients, nthreads);
                exit(1);
        }
 
index c34f7acbbb9c644a32cb1011b11b5478e8da21f0..0e6ae3f057e0d0968e4930d9acc988777cd1f758 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.9 2009/08/03 15:18:14 ishii Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.10 2009/08/03 18:30:55 tgl Exp $ -->
 
 <sect1 id="pgbench">
  <title>pgbench</title>
@@ -27,13 +27,14 @@ transaction type: TPC-B (sort of)
 scaling factor: 10
 query mode: simple
 number of clients: 10
+number of threads: 1
 number of transactions per client: 1000
 number of transactions actually processed: 10000/10000
 tps = 85.184871 (including connections establishing)
 tps = 85.296346 (excluding connections establishing)
  </programlisting>
 
-  The first five lines report some of the most important parameter
+  The first six lines report some of the most important parameter
   settings.  The next line reports the number of transactions completed
   and intended (the latter being just the product of number of clients
   and number of transactions per client); these will be equal unless the run
@@ -174,9 +175,11 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
      <row>
       <entry><literal>-j</literal> <replaceable>threads</></entry>
       <entry>
-       Number of worker threads. Clients are equally-divided into those
-       threads and executed in it. The number of clients must be a multiple
-       number of threads. Default is 1.
+       Number of worker threads within <application>pgbench</application>.
+       Using more than one thread can be helpful on multi-CPU machines.
+       The number of clients must be a multiple of the number of threads,
+       since each thread is given the same number of client sessions to manage.
+       Default is 1.
       </entry>
      </row>
      <row>
@@ -267,7 +270,7 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
       <entry><literal>-C</literal></entry>
       <entry>
        Establish a new connection for each transaction, rather than
-       doing it just once per client thread.
+       doing it just once per client session.
        This is useful to measure the connection overhead.
       </entry>
      </row>