/*
- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.66 2007/05/24 18:54:10 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.67 2007/07/06 13:36:55 wieck Exp $
*
* pgbench: a simple benchmark program for PostgreSQL
* written by Tatsuo Ishii
int ecnt; /* error count */
int listen; /* 0 indicates that an async query has been
* sent */
+ int sleeping; /* 1 indicates that the client is napping */
+ struct timeval until; /* napping until */
Variable *variables; /* array of variable definitions */
int nvariables;
struct timeval txn_begin; /* used for measuring latencies */
top:
commands = sql_files[st->use_file];
+ if (st->sleeping)
+ { /* are we sleeping? */
+ int usec;
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ usec = (st->until.tv_sec - now.tv_sec) * 1000000 +
+ st->until.tv_usec - now.tv_usec;
+ if (usec <= 0)
+ st->sleeping = 0; /* Done sleeping, go ahead with next command */
+ else
+ return; /* Still sleeping, nothing to do here */
+ }
+
if (st->listen)
{ /* are we receiver? */
if (commands[st->state]->type == SQL_COMMAND)
st->listen = 1;
}
+ else if (pg_strcasecmp(argv[0], "usleep") == 0)
+ {
+ char *var;
+ int usec;
+ struct timeval now;
+
+ if (*argv[1] == ':')
+ {
+ if ((var = getVariable(st, argv[1] + 1)) == NULL)
+ {
+ fprintf(stderr, "%s: undefined variable %s\n", argv[0], argv[1]);
+ st->ecnt++;
+ return;
+ }
+ usec = atoi(var);
+ }
+ else
+ usec = atoi(argv[1]);
+
+ gettimeofday(&now, NULL);
+ st->until.tv_sec = now.tv_sec + (now.tv_usec + usec) / 1000000;
+ st->until.tv_usec = (now.tv_usec + usec) % 1000000;
+ st->sleeping = 1;
+
+ st->listen = 1;
+ }
goto top;
}
fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
my_commands->argv[0], my_commands->argv[j]);
}
+ else if (pg_strcasecmp(my_commands->argv[0], "usleep") == 0)
+ {
+ if (my_commands->argc < 2)
+ {
+ fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
+ return NULL;
+ }
+
+ for (j = 2; j < my_commands->argc; j++)
+ fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
+ my_commands->argv[0], my_commands->argv[j]);
+ }
else
{
- fprintf(stderr, "invalid command %s\n", my_commands->argv[0]);
+ fprintf(stderr, "Invalid command %s\n", my_commands->argv[0]);
return NULL;
}
}
fd_set input_mask;
int nsocks; /* return from select(2) */
int maxsock; /* max socket number to be waited */
+ struct timeval now;
+ struct timeval timeout;
+ int min_usec;
#ifdef HAVE_GETRLIMIT
struct rlimit rlim;
FD_ZERO(&input_mask);
maxsock = -1;
+ min_usec = -1;
for (i = 0; i < nclients; i++)
{
Command **commands = sql_files[state[i].use_file];
- if (state[i].con && commands[state[i].state]->type != META_COMMAND)
+ if (state[i].sleeping)
+ {
+ int this_usec;
+ int sock = PQsocket(state[i].con);
+
+ if (min_usec < 0)
+ {
+ gettimeofday(&now, NULL);
+ min_usec = 0;
+ }
+
+ this_usec = (state[i].until.tv_sec - now.tv_sec) * 1000000 +
+ state[i].until.tv_usec - now.tv_usec;
+
+ if (this_usec > 0 && (min_usec == 0 || this_usec < min_usec))
+ min_usec = this_usec;
+
+ FD_SET(sock, &input_mask);
+ if (maxsock < sock)
+ maxsock = sock;
+ }
+ else if (state[i].con && commands[state[i].state]->type != META_COMMAND)
{
int sock = PQsocket(state[i].con);
if (maxsock != -1)
{
- if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
- (fd_set *) NULL, (struct timeval *) NULL)) < 0)
+ if (min_usec >= 0)
+ {
+ timeout.tv_sec = min_usec / 1000000;
+ timeout.tv_usec = min_usec % 1000000;
+
+ nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
+ (fd_set *) NULL, &timeout);
+ }
+ else
+ nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
+ (fd_set *) NULL, (struct timeval *) NULL);
+ if (nsocks < 0)
{
if (errno == EINTR)
continue;
fprintf(stderr, "select failed: %s\n", strerror(errno));
exit(1);
}
+#ifdef NOT_USED
else if (nsocks == 0)
{ /* timeout */
fprintf(stderr, "select timeout\n");
}
exit(0);
}
+#endif
}
/* ok, backend returns reply */