* A simple benchmark program for PostgreSQL
* Originally written by Tatsuo Ishii and enhanced by many contributors.
*
- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.100 2010/08/12 20:39:39 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.101 2010/08/12 21:10:59 tgl Exp $
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED;
*
static void setalarm(int seconds);
static void *threadRun(void *arg);
+
+/*
+ * routines to check mem allocations and fail noisily.
+ */
+static void *
+xmalloc(size_t size)
+{
+ void *result;
+
+ result = malloc(size);
+ if (!result)
+ {
+ fprintf(stderr, "out of memory\n");
+ exit(1);
+ }
+ return result;
+}
+
+static void *
+xrealloc(void *ptr, size_t size)
+{
+ void *result;
+
+ result = realloc(ptr, size);
+ if (!result)
+ {
+ fprintf(stderr, "out of memory\n");
+ exit(1);
+ }
+ return result;
+}
+
+static char *
+xstrdup(const char *s)
+{
+ char *result;
+
+ result = strdup(s);
+ if (!result)
+ {
+ fprintf(stderr, "out of memory\n");
+ exit(1);
+ }
+ return result;
+}
+
+
static void
usage(const char *progname)
{
}
if (st->variables)
- newvars = (Variable *) realloc(st->variables,
+ newvars = (Variable *) xrealloc(st->variables,
(st->nvariables + 1) * sizeof(Variable));
else
- newvars = (Variable *) malloc(sizeof(Variable));
-
- if (newvars == NULL)
- goto out_of_memory;
+ newvars = (Variable *) xmalloc(sizeof(Variable));
st->variables = newvars;
var = &newvars[st->nvariables];
- var->name = NULL;
- var->value = NULL;
-
- if ((var->name = strdup(name)) == NULL ||
- (var->value = strdup(value)) == NULL)
- {
- free(var->name);
- free(var->value);
- return false;
- }
+ var->name = xstrdup(name);
+ var->value = xstrdup(value);
st->nvariables++;
{
char *val;
- if ((val = strdup(value)) == NULL)
- return false;
+ /* dup then free, in case value is pointing at this variable */
+ val = xstrdup(value);
free(var->value);
var->value = val;
}
return true;
-
-out_of_memory:
- fprintf(stderr, "%s: out of memory for variable '%s'\n", context, name);
- return false;
}
static char *
if (i == 1)
return NULL;
- name = malloc(i);
- if (name == NULL)
- return NULL;
+ name = xmalloc(i);
memcpy(name, &sql[1], i - 1);
name[i - 1] = '\0';
if (valueln > len)
{
- char *tmp;
size_t offset = param - *sql;
- tmp = realloc(*sql, strlen(*sql) - len + valueln + 1);
- if (tmp == NULL)
- {
- free(*sql);
- return NULL;
- }
- *sql = tmp;
+ *sql = xrealloc(*sql, strlen(*sql) - len + valueln + 1);
param = *sql + offset;
}
continue;
}
- if ((p = replaceVariable(&sql, p, eaten, val)) == NULL)
- return NULL;
+ p = replaceVariable(&sql, p, eaten, val);
}
return sql;
{
char *sql;
- if ((sql = strdup(command->argv[0])) == NULL
- || (sql = assignVariables(st, sql)) == NULL)
- {
- fprintf(stderr, "out of memory\n");
- st->ecnt++;
- return true;
- }
+ sql = xstrdup(command->argv[0]);
+ sql = assignVariables(st, sql);
if (debug)
fprintf(stderr, "client %d sending %s\n", st->id, sql);
char *sql,
*p;
- sql = strdup(raw_sql);
- if (sql == NULL)
- return false;
+ sql = xstrdup(raw_sql);
cmd->argc = 1;
p = sql;
}
sprintf(var, "$%d", cmd->argc);
- if ((p = replaceVariable(&sql, p, eaten, var)) == NULL)
- return false;
+ p = replaceVariable(&sql, p, eaten, var);
cmd->argv[cmd->argc] = name;
cmd->argc++;
return NULL;
/* Allocate and initialize Command structure */
- my_commands = (Command *) malloc(sizeof(Command));
- if (my_commands == NULL)
- return NULL;
- my_commands->line = strdup(buf);
- if (my_commands->line == NULL)
- return NULL;
+ my_commands = (Command *) xmalloc(sizeof(Command));
+ my_commands->line = xstrdup(buf);
my_commands->command_num = num_commands++;
my_commands->type = 0; /* until set */
my_commands->argc = 0;
while (tok != NULL)
{
- if ((my_commands->argv[j] = strdup(tok)) == NULL)
- return NULL;
-
+ my_commands->argv[j++] = xstrdup(tok);
my_commands->argc++;
-
- j++;
tok = strtok(NULL, delim);
}
if (my_commands->argc < 4)
{
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
- return NULL;
+ exit(1);
}
for (j = 4; j < my_commands->argc; j++)
if (my_commands->argc < 3)
{
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
- return NULL;
+ exit(1);
}
for (j = my_commands->argc < 5 ? 3 : 5; j < my_commands->argc; j++)
if (my_commands->argc < 2)
{
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
- return NULL;
+ exit(1);
}
/*
{
fprintf(stderr, "%s: unknown time unit '%s' - must be us, ms or s\n",
my_commands->argv[0], my_commands->argv[2]);
- return NULL;
+ exit(1);
}
}
if (my_commands->argc < 3)
{
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
- return NULL;
+ exit(1);
}
}
else if (pg_strcasecmp(my_commands->argv[0], "shell") == 0)
if (my_commands->argc < 1)
{
fprintf(stderr, "%s: missing command\n", my_commands->argv[0]);
- return NULL;
+ exit(1);
}
}
else
{
fprintf(stderr, "Invalid command %s\n", my_commands->argv[0]);
- return NULL;
+ exit(1);
}
}
else
switch (querymode)
{
case QUERY_SIMPLE:
- if ((my_commands->argv[0] = strdup(p)) == NULL)
- return NULL;
+ my_commands->argv[0] = xstrdup(p);
my_commands->argc++;
break;
case QUERY_EXTENDED:
case QUERY_PREPARED:
if (!parseQuery(my_commands, p))
- return NULL;
+ exit(1);
break;
default:
- return NULL;
+ exit(1);
}
}
}
alloc_num = COMMANDS_ALLOC_NUM;
- my_commands = (Command **) malloc(sizeof(Command *) * alloc_num);
- if (my_commands == NULL)
- return false;
+ my_commands = (Command **) xmalloc(sizeof(Command *) * alloc_num);
if (strcmp(filename, "-") == 0)
fd = stdin;
if (lineno >= alloc_num)
{
alloc_num += COMMANDS_ALLOC_NUM;
- my_commands = realloc(my_commands, sizeof(Command *) * alloc_num);
- if (my_commands == NULL)
- {
- fclose(fd);
- return false;
- }
+ my_commands = xrealloc(my_commands, sizeof(Command *) * alloc_num);
}
}
fclose(fd);
char buf[BUFSIZ];
int alloc_num;
- if (*tb == '\0')
- return NULL;
-
alloc_num = COMMANDS_ALLOC_NUM;
- my_commands = (Command **) malloc(sizeof(Command *) * alloc_num);
- if (my_commands == NULL)
- return NULL;
+ my_commands = (Command **) xmalloc(sizeof(Command *) * alloc_num);
lineno = 0;
if (lineno >= alloc_num)
{
alloc_num += COMMANDS_ALLOC_NUM;
- my_commands = realloc(my_commands, sizeof(Command *) * alloc_num);
- if (my_commands == NULL)
- {
- return NULL;
- }
+ my_commands = xrealloc(my_commands, sizeof(Command *) * alloc_num);
}
}
else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
login = env;
- state = (CState *) malloc(sizeof(CState));
- if (state == NULL)
- {
- fprintf(stderr, "Couldn't allocate memory for state\n");
- exit(1);
- }
-
- memset(state, 0, sizeof(*state));
+ state = (CState *) xmalloc(sizeof(CState));
+ memset(state, 0, sizeof(CState));
while ((c = getopt(argc, argv, "ih:nvp:dSNc:j:Crs:t:T:U:lf:D:F:M:")) != -1)
{
if (nclients > 1)
{
- state = (CState *) realloc(state, sizeof(CState) * nclients);
- if (state == NULL)
- {
- fprintf(stderr, "Couldn't allocate memory for state\n");
- exit(1);
- }
-
- memset(state + 1, 0, sizeof(*state) * (nclients - 1));
+ state = (CState *) xrealloc(state, sizeof(CState) * nclients);
+ memset(state + 1, 0, sizeof(CState) * (nclients - 1));
/* copy any -D switch values to all clients */
for (i = 1; i < nclients; i++)
}
/* set up thread data structures */
- threads = (TState *) malloc(sizeof(TState) * nthreads);
+ threads = (TState *) xmalloc(sizeof(TState) * nthreads);
for (i = 0; i < nthreads; i++)
{
TState *thread = &threads[i];
int t;
thread->exec_elapsed = (instr_time *)
- malloc(sizeof(instr_time) * num_commands);
+ xmalloc(sizeof(instr_time) * num_commands);
thread->exec_count = (int *)
- malloc(sizeof(int) * num_commands);
+ xmalloc(sizeof(int) * num_commands);
for (t = 0; t < num_commands; t++)
{
int remains = nstate; /* number of remaining clients */
int i;
- result = malloc(sizeof(TResult));
+ result = xmalloc(sizeof(TResult));
INSTR_TIME_SET_ZERO(result->conn_time);
/* open log file if requested */
void *ret;
instr_time start_time;
- th = (fork_pthread *) malloc(sizeof(fork_pthread));
- pipe(th->pipes);
+ th = (fork_pthread *) xmalloc(sizeof(fork_pthread));
+ if (pipe(th->pipes) < 0)
+ {
+ free(th);
+ return errno;
+ }
th->pid = fork();
if (th->pid == -1) /* error */
if (thread_return != NULL)
{
/* assume result is TResult */
- *thread_return = malloc(sizeof(TResult));
+ *thread_return = xmalloc(sizeof(TResult));
if (read(th->pipes[0], *thread_return, sizeof(TResult)) != sizeof(TResult))
{
free(*thread_return);
int save_errno;
win32_pthread *th;
- th = (win32_pthread *) malloc(sizeof(win32_pthread));
+ th = (win32_pthread *) xmalloc(sizeof(win32_pthread));
th->routine = start_routine;
th->arg = arg;
th->result = NULL;