Commit 7ffb14f9 authored by Tom Lane's avatar Tom Lane

Portability and documentation fixes for threaded pgbench patch.

parent 3da0dfb4
# $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 PROGRAM = pgbench
OBJS = pgbench.o OBJS = pgbench.o
PG_CPPFLAGS = -I$(libpq_srcdir) PG_CPPFLAGS = -I$(libpq_srcdir)
PG_LIBS = $(libpq_pgport) PG_LIBS = $(libpq_pgport) $(PTHREAD_LIBS)
ifdef USE_PGXS ifdef USE_PGXS
PG_CONFIG = pg_config PG_CONFIG = pg_config
...@@ -16,3 +16,7 @@ top_builddir = ../.. ...@@ -16,3 +16,7 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk include $(top_srcdir)/contrib/contrib-global.mk
endif endif
ifneq ($(PORTNAME), win32)
override CFLAGS += $(PTHREAD_CFLAGS)
endif
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* A simple benchmark program for PostgreSQL * A simple benchmark program for PostgreSQL
* Originally written by Tatsuo Ishii and enhanced by many contributors. * 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 * Copyright (c) 2000-2009, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED; * ALL RIGHTS RESERVED;
* *
...@@ -71,23 +71,27 @@ ...@@ -71,23 +71,27 @@
/* Use native win32 threads on Windows */ /* Use native win32 threads on Windows */
typedef struct win32_pthread *pthread_t; typedef struct win32_pthread *pthread_t;
typedef int pthread_attr_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_create(pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void *arg);
static int pthread_join(pthread_t th, void **thread_return); static int pthread_join(pthread_t th, void **thread_return);
#elif defined(ENABLE_THREAD_SAFETY) #elif defined(ENABLE_THREAD_SAFETY)
/* Use platform-dependent pthread */ /* Use platform-dependent pthread capability */
#include <pthread.h> #include <pthread.h>
#else #else
/* Use emulation with fork. Rename pthread identifiers to avoid conflicts */
#include <sys/wait.h> #include <sys/wait.h>
/* Use emulation with fork. Rename pthread idendifiers to avoid conflictions */
#define pthread_t pg_pthread_t #define pthread_t pg_pthread_t
#define pthread_attr_t pg_pthread_attr_t #define pthread_attr_t pg_pthread_attr_t
#define pthread_create pg_pthread_create #define pthread_create pg_pthread_create
#define pthread_join pg_pthread_join #define pthread_join pg_pthread_join
typedef struct fork_pthread *pthread_t; typedef struct fork_pthread *pthread_t;
typedef int pthread_attr_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_create(pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void *arg);
static int pthread_join(pthread_t th, void **thread_return); static int pthread_join(pthread_t th, void **thread_return);
...@@ -185,7 +189,7 @@ typedef struct ...@@ -185,7 +189,7 @@ typedef struct
{ {
pthread_t thread; /* thread handle */ pthread_t thread; /* thread handle */
CState *state; /* array of CState */ CState *state; /* array of CState */
int nstate; /* length of state */ int nstate; /* length of state[] */
instr_time start_time; /* thread start time */ instr_time start_time; /* thread start time */
} TState; } TState;
...@@ -647,20 +651,25 @@ top: ...@@ -647,20 +651,25 @@ top:
*/ */
if (use_log && commands[st->state + 1] == NULL) if (use_log && commands[st->state + 1] == NULL)
{ {
instr_time now;
instr_time diff; instr_time diff;
double sec;
double msec;
double usec; double usec;
INSTR_TIME_SET_CURRENT(diff); INSTR_TIME_SET_CURRENT(now);
diff = now;
INSTR_TIME_SUBTRACT(diff, st->txn_begin); 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); 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, 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) if (commands[st->state]->type == SQL_COMMAND)
...@@ -1269,15 +1278,17 @@ process_commands(char *buf) ...@@ -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 * 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. * non-digit characters.
*/ */
if (my_commands->argv[1][0] != ':') if (my_commands->argv[1][0] != ':')
{ {
char *c = my_commands->argv[1]; char *c = my_commands->argv[1];
while (isdigit(*c)) { c++; }
while (isdigit((unsigned char) *c))
c++;
if (*c) if (*c)
{ {
my_commands->argv[2] = c; my_commands->argv[2] = c;
...@@ -1772,7 +1783,7 @@ main(int argc, char **argv) ...@@ -1772,7 +1783,7 @@ main(int argc, char **argv)
if (nclients % nthreads != 0) 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); exit(1);
} }
......
<!-- $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"> <sect1 id="pgbench">
<title>pgbench</title> <title>pgbench</title>
...@@ -27,13 +27,14 @@ transaction type: TPC-B (sort of) ...@@ -27,13 +27,14 @@ transaction type: TPC-B (sort of)
scaling factor: 10 scaling factor: 10
query mode: simple query mode: simple
number of clients: 10 number of clients: 10
number of threads: 1
number of transactions per client: 1000 number of transactions per client: 1000
number of transactions actually processed: 10000/10000 number of transactions actually processed: 10000/10000
tps = 85.184871 (including connections establishing) tps = 85.184871 (including connections establishing)
tps = 85.296346 (excluding connections establishing) tps = 85.296346 (excluding connections establishing)
</programlisting> </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 settings. The next line reports the number of transactions completed
and intended (the latter being just the product of number of clients 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 and number of transactions per client); these will be equal unless the run
...@@ -174,9 +175,11 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</> ...@@ -174,9 +175,11 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
<row> <row>
<entry><literal>-j</literal> <replaceable>threads</></entry> <entry><literal>-j</literal> <replaceable>threads</></entry>
<entry> <entry>
Number of worker threads. Clients are equally-divided into those Number of worker threads within <application>pgbench</application>.
threads and executed in it. The number of clients must be a multiple Using more than one thread can be helpful on multi-CPU machines.
number of threads. Default is 1. 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> </entry>
</row> </row>
<row> <row>
...@@ -267,7 +270,7 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</> ...@@ -267,7 +270,7 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
<entry><literal>-C</literal></entry> <entry><literal>-C</literal></entry>
<entry> <entry>
Establish a new connection for each transaction, rather than 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. This is useful to measure the connection overhead.
</entry> </entry>
</row> </row>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment