diff options
author | Keith Bostic <keith.bostic@mongodb.com> | 2016-08-15 23:36:17 -0400 |
---|---|---|
committer | Alex Gorrod <alexander.gorrod@mongodb.com> | 2016-08-16 13:36:17 +1000 |
commit | a84e0799aa5aff58bc3d9ca4c49c4f0777253f84 (patch) | |
tree | 661395bea9e9087ca134f238bf7d93a1c45235f5 /bench | |
parent | 0e8a887c8c7281ab09c5c9d61a30defbdeb58bbf (diff) | |
download | mongo-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.c | 61 | ||||
-rw-r--r-- | bench/wtperf/wtperf.c | 47 | ||||
-rw-r--r-- | bench/wtperf/wtperf.h | 6 |
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 *); |