summaryrefslogtreecommitdiff
path: root/bench
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2016-08-15 23:36:17 -0400
committerAlex Gorrod <alexander.gorrod@mongodb.com>2016-08-16 13:36:17 +1000
commita84e0799aa5aff58bc3d9ca4c49c4f0777253f84 (patch)
tree661395bea9e9087ca134f238bf7d93a1c45235f5 /bench
parent0e8a887c8c7281ab09c5c9d61a30defbdeb58bbf (diff)
downloadmongo-a84e0799aa5aff58bc3d9ca4c49c4f0777253f84.tar.gz
WT-2783 Clean up wtperf configuration object management (#2957)
The multi-database wtperf feature implementation assigns memory from the base CONFIG structure to the CONFIG copies, but then individually frees the memory referenced by the copies, resulting in OS X complaints that memory is freed more than once. Rename the config_assign() function to be config_init(), it does more than simply assign the previous values. In config_init(), create copies of the configuration strings in each new CONFIG structure. There are also a few places where CONFIG.home and CONFIG.monitor_dir are set (for example, to the value of the command line -h and -m options), change that code to free/allocate so we maintain a local copy of the strings in every CONFIG structure. Change config_init() to copy the CONFIG.home and CONFIG.monitor_dir fields along with the rest of the CONFIG structure, they get freed in config_free(), so they should be copied in config_init().
Diffstat (limited to 'bench')
-rw-r--r--bench/wtperf/config.c61
-rw-r--r--bench/wtperf/wtperf.c47
-rw-r--r--bench/wtperf/wtperf.h6
3 files changed, 68 insertions, 46 deletions
diff --git a/bench/wtperf/config.c b/bench/wtperf/config.c
index 475b6ffd2a4..a2960902ec1 100644
--- a/bench/wtperf/config.c
+++ b/bench/wtperf/config.c
@@ -94,31 +94,42 @@ config_unescape(char *orig)
}
/*
- * config_assign --
- * Assign the src config to the dest, any storage allocated in dest is
- * freed as a result.
+ * config_copy --
+ * CONFIG structure initialization, based on a source configuration.
*/
int
-config_assign(CONFIG *dest, const CONFIG *src)
+config_copy(CONFIG *dest, const CONFIG *src)
{
CONFIG_QUEUE_ENTRY *conf_line, *tmp_line;
size_t i;
char *newstr, **pstr;
- config_free(dest);
memcpy(dest, src, sizeof(CONFIG));
+ if (src->home != NULL)
+ dest->home = dstrdup(src->home);
+ if (src->monitor_dir != NULL)
+ dest->monitor_dir = dstrdup(src->monitor_dir);
+ if (src->partial_config != NULL)
+ dest->partial_config = dstrdup(src->partial_config);
+ if (src->reopen_config != NULL)
+ dest->reopen_config = dstrdup(src->reopen_config);
+ if (src->base_uri != NULL)
+ dest->base_uri = dstrdup(src->base_uri);
+
if (src->uris != NULL) {
dest->uris = dcalloc(src->table_count, sizeof(char *));
for (i = 0; i < src->table_count; i++)
dest->uris[i] = dstrdup(src->uris[i]);
}
+
+ if (src->async_config != NULL)
+ dest->async_config = dstrdup(src->async_config);
+
dest->ckptthreads = NULL;
dest->popthreads = NULL;
dest->workers = NULL;
- if (src->base_uri != NULL)
- dest->base_uri = dstrdup(src->base_uri);
if (src->workload != NULL) {
dest->workload = dcalloc(WORKLOAD_MAX, sizeof(WORKLOAD));
memcpy(dest->workload,
@@ -159,6 +170,28 @@ config_free(CONFIG *cfg)
size_t i;
char **pstr;
+ free(cfg->home);
+ free(cfg->monitor_dir);
+ free(cfg->partial_config);
+ free(cfg->reopen_config);
+ free(cfg->base_uri);
+
+ if (cfg->uris != NULL) {
+ for (i = 0; i < cfg->table_count; i++)
+ free(cfg->uris[i]);
+ free(cfg->uris);
+ }
+
+ free(cfg->async_config);
+
+ free(cfg->ckptthreads);
+ free(cfg->popthreads);
+
+ free(cfg->workers);
+ free(cfg->workload);
+
+ cleanup_truncate_config(cfg);
+
while (!TAILQ_EMPTY(&cfg->config_head)) {
config_line = TAILQ_FIRST(&cfg->config_head);
TAILQ_REMOVE(&cfg->config_head, config_line, c);
@@ -174,20 +207,6 @@ config_free(CONFIG *cfg)
free(*pstr);
*pstr = NULL;
}
- if (cfg->uris != NULL) {
- for (i = 0; i < cfg->table_count; i++)
- free(cfg->uris[i]);
- free(cfg->uris);
- }
-
- cleanup_truncate_config(cfg);
- free(cfg->base_uri);
- free(cfg->ckptthreads);
- free(cfg->partial_config);
- free(cfg->popthreads);
- free(cfg->reopen_config);
- free(cfg->workers);
- free(cfg->workload);
}
/*
diff --git a/bench/wtperf/wtperf.c b/bench/wtperf/wtperf.c
index 12730872c47..d969d625b76 100644
--- a/bench/wtperf/wtperf.c
+++ b/bench/wtperf/wtperf.c
@@ -29,9 +29,11 @@
#include "wtperf.h"
/* Default values. */
+#define DEFAULT_HOME "WT_TEST"
+#define DEFAULT_MONITOR_DIR "WT_TEST"
static const CONFIG default_cfg = {
- "WT_TEST", /* home */
- "WT_TEST", /* monitor dir */
+ NULL, /* home */
+ NULL, /* monitor dir */
NULL, /* partial logging */
NULL, /* reopen config */
NULL, /* base_uri */
@@ -1944,13 +1946,12 @@ start_all_runs(CONFIG *cfg)
{
CONFIG *next_cfg, **configs;
pthread_t *threads;
- size_t cmd_len, home_len, i;
+ size_t home_len, i;
int ret, t_ret;
- char *cmd_buf, *new_home;
+ char *new_home;
ret = 0;
configs = NULL;
- cmd_buf = NULL;
if (cfg->database_count == 1)
return (start_run(cfg));
@@ -1962,24 +1963,25 @@ start_all_runs(CONFIG *cfg)
threads = dcalloc(cfg->database_count, sizeof(pthread_t));
home_len = strlen(cfg->home);
- cmd_len = (home_len * 2) + 30; /* Add some slop. */
- cmd_buf = dcalloc(cmd_len, 1);
for (i = 0; i < cfg->database_count; i++) {
next_cfg = dcalloc(1, sizeof(CONFIG));
configs[i] = next_cfg;
- if ((ret = config_assign(next_cfg, cfg)) != 0)
+ if ((ret = config_copy(next_cfg, cfg)) != 0)
goto err;
/* Setup a unique home directory for each database. */
new_home = dmalloc(home_len + 5);
snprintf(new_home, home_len + 5, "%s/D%02d", cfg->home, (int)i);
+ free(next_cfg->home);
next_cfg->home = new_home;
/* If the monitor dir is default, update it too. */
- if (strcmp(cfg->monitor_dir, cfg->home) == 0)
- next_cfg->monitor_dir = new_home;
+ if (strcmp(cfg->monitor_dir, cfg->home) == 0) {
+ free(next_cfg->monitor_dir);
+ next_cfg->monitor_dir = dstrdup(new_home);
+ }
- /* If creating the sub-database, recreate it's home */
+ /* If creating the sub-database, recreate its home */
if (cfg->create != 0)
recreate_dir(next_cfg->home);
@@ -1991,22 +1993,19 @@ start_all_runs(CONFIG *cfg)
}
/* Wait for threads to finish. */
- for (i = 0; i < cfg->database_count; i++) {
+ for (i = 0; i < cfg->database_count; i++)
if ((t_ret = pthread_join(threads[i], NULL)) != 0) {
lprintf(cfg, ret, 0, "Error joining thread");
if (ret == 0)
ret = t_ret;
}
- }
err: for (i = 0; i < cfg->database_count && configs[i] != NULL; i++) {
- free((char *)configs[i]->home);
config_free(configs[i]);
free(configs[i]);
}
free(configs);
free(threads);
- free(cmd_buf);
return (ret);
}
@@ -2199,10 +2198,10 @@ main(int argc, char *argv[])
/* Setup the default configuration values. */
cfg = &_cfg;
memset(cfg, 0, sizeof(*cfg));
- if (config_assign(cfg, &default_cfg))
+ if (config_copy(cfg, &default_cfg))
goto err;
-
- TAILQ_INIT(&cfg->config_head);
+ cfg->home = dstrdup(DEFAULT_HOME);
+ cfg->monitor_dir = dstrdup(DEFAULT_MONITOR_DIR);
/* Do a basic validation of options, and home is needed before open. */
while ((ch = __wt_getopt("wtperf", argc, argv, opts)) != EOF)
@@ -2219,10 +2218,12 @@ main(int argc, char *argv[])
}
break;
case 'h':
- cfg->home = __wt_optarg;
+ free(cfg->home);
+ cfg->home = dstrdup(__wt_optarg);
break;
case 'm':
- cfg->monitor_dir = __wt_optarg;
+ free(cfg->monitor_dir);
+ cfg->monitor_dir = dstrdup(__wt_optarg);
monitor_set = true;
break;
case 'O':
@@ -2248,8 +2249,10 @@ main(int argc, char *argv[])
* If the user did not specify a monitor directory then set the
* monitor directory to the home dir.
*/
- if (!monitor_set)
- cfg->monitor_dir = cfg->home;
+ if (!monitor_set) {
+ free(cfg->monitor_dir);
+ cfg->monitor_dir = dstrdup(cfg->home);
+ }
/* Parse configuration settings from configuration file. */
if (config_opts != NULL && config_opt_file(cfg, config_opts) != 0)
diff --git a/bench/wtperf/wtperf.h b/bench/wtperf/wtperf.h
index 27c3832d316..e0467f4f3a1 100644
--- a/bench/wtperf/wtperf.h
+++ b/bench/wtperf/wtperf.h
@@ -116,8 +116,8 @@ typedef struct {
* an initialization in wtperf.c in the default_cfg.
*/
struct __config { /* Configuration structure */
- const char *home; /* WiredTiger home */
- const char *monitor_dir; /* Monitor output dir */
+ char *home; /* WiredTiger home */
+ char *monitor_dir; /* Monitor output dir */
char *partial_config; /* Config string for partial logging */
char *reopen_config; /* Config string for conn reopen */
char *base_uri; /* Object URI */
@@ -259,9 +259,9 @@ struct __config_thread { /* Per-thread structure */
};
void cleanup_truncate_config(CONFIG *);
-int config_assign(CONFIG *, const CONFIG *);
int config_compress(CONFIG *);
void config_free(CONFIG *);
+int config_copy(CONFIG *, const CONFIG *);
int config_opt_file(CONFIG *, const char *);
int config_opt_line(CONFIG *, const char *);
int config_opt_str(CONFIG *, const char *, const char *);