summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/bench/wtperf/track.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/bench/wtperf/track.c')
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/track.c324
1 files changed, 324 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/bench/wtperf/track.c b/src/third_party/wiredtiger/bench/wtperf/track.c
new file mode 100644
index 00000000000..3919d0eb1ab
--- /dev/null
+++ b/src/third_party/wiredtiger/bench/wtperf/track.c
@@ -0,0 +1,324 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "wtperf.h"
+
+/*
+ * Return total insert operations for the populate phase.
+ */
+uint64_t
+sum_pop_ops(CONFIG *cfg)
+{
+ CONFIG_THREAD *thread;
+ uint64_t total;
+ u_int i;
+
+ total = 0;
+
+ for (i = 0, thread = cfg->popthreads;
+ thread != NULL && i < cfg->populate_threads; ++i, ++thread)
+ total += thread->insert.ops;
+ return (total);
+}
+
+/*
+ * Return total checkpoint operations.
+ */
+uint64_t
+sum_ckpt_ops(CONFIG *cfg)
+{
+ CONFIG_THREAD *thread;
+ uint64_t total;
+ u_int i;
+
+ total = 0;
+
+ for (i = 0, thread = cfg->ckptthreads;
+ thread != NULL && i < cfg->checkpoint_threads; ++i, ++thread)
+ total += thread->ckpt.ops;
+ return (total);
+}
+
+/*
+ * Return total operations count for the worker threads.
+ */
+static uint64_t
+sum_ops(CONFIG *cfg, size_t field_offset)
+{
+ CONFIG_THREAD *thread;
+ uint64_t total;
+ int64_t i, th_cnt;
+
+ total = 0;
+ if (cfg->popthreads == NULL) {
+ thread = cfg->workers;
+ th_cnt = cfg->workers_cnt;
+ } else {
+ thread = cfg->popthreads;
+ th_cnt = cfg->populate_threads;
+ }
+ for (i = 0; thread != NULL && i < th_cnt; ++i, ++thread)
+ total += ((TRACK *)((uint8_t *)thread + field_offset))->ops;
+
+ return (total);
+}
+uint64_t
+sum_insert_ops(CONFIG *cfg)
+{
+ return (sum_ops(cfg, offsetof(CONFIG_THREAD, insert)));
+}
+uint64_t
+sum_read_ops(CONFIG *cfg)
+{
+ return (sum_ops(cfg, offsetof(CONFIG_THREAD, read)));
+}
+uint64_t
+sum_update_ops(CONFIG *cfg)
+{
+ return (sum_ops(cfg, offsetof(CONFIG_THREAD, update)));
+}
+
+/*
+ * latency_op --
+ * Get average, minimum and maximum latency for this period for a
+ * particular operation.
+ */
+static void
+latency_op(CONFIG *cfg,
+ size_t field_offset, uint32_t *avgp, uint32_t *minp, uint32_t *maxp)
+{
+ CONFIG_THREAD *thread;
+ TRACK *track;
+ uint64_t ops, latency, tmp;
+ int64_t i, th_cnt;
+ uint32_t max, min;
+
+ ops = latency = 0;
+ max = 0;
+ min = UINT32_MAX;
+
+ if (cfg->popthreads == NULL) {
+ thread = cfg->workers;
+ th_cnt = cfg->workers_cnt;
+ } else {
+ thread = cfg->popthreads;
+ th_cnt = cfg->populate_threads;
+ }
+ for (i = 0; thread != NULL && i < th_cnt; ++i, ++thread) {
+ track = (TRACK *)((uint8_t *)thread + field_offset);
+ tmp = track->latency_ops;
+ ops += tmp - track->last_latency_ops;
+ track->last_latency_ops = tmp;
+ tmp = track->latency;
+ latency += tmp - track->last_latency;
+ track->last_latency = tmp;
+
+ if (min > track->min_latency)
+ min = track->min_latency;
+ track->min_latency = UINT32_MAX;
+ if (max < track->max_latency)
+ max = track->max_latency;
+ track->max_latency = 0;
+ }
+
+ if (ops == 0)
+ *avgp = *minp = *maxp = 0;
+ else {
+ *minp = min;
+ *maxp = max;
+ *avgp = (uint32_t)(latency / ops);
+ }
+}
+void
+latency_read(CONFIG *cfg, uint32_t *avgp, uint32_t *minp, uint32_t *maxp)
+{
+ static uint32_t last_avg = 0, last_max = 0, last_min = 0;
+
+ latency_op(cfg, offsetof(CONFIG_THREAD, read), avgp, minp, maxp);
+
+ /*
+ * If nothing happened, graph the average, minimum and maximum as they
+ * were the last time, it keeps the graphs from having discontinuities.
+ */
+ if (*minp == 0) {
+ *avgp = last_avg;
+ *minp = last_min;
+ *maxp = last_max;
+ } else {
+ last_avg = *avgp;
+ last_min = *minp;
+ last_max = *maxp;
+ }
+}
+void
+latency_insert(CONFIG *cfg, uint32_t *avgp, uint32_t *minp, uint32_t *maxp)
+{
+ static uint32_t last_avg = 0, last_max = 0, last_min = 0;
+
+ latency_op(cfg, offsetof(CONFIG_THREAD, insert), avgp, minp, maxp);
+
+ /*
+ * If nothing happened, graph the average, minimum and maximum as they
+ * were the last time, it keeps the graphs from having discontinuities.
+ */
+ if (*minp == 0) {
+ *avgp = last_avg;
+ *minp = last_min;
+ *maxp = last_max;
+ } else {
+ last_avg = *avgp;
+ last_min = *minp;
+ last_max = *maxp;
+ }
+}
+void
+latency_update(CONFIG *cfg, uint32_t *avgp, uint32_t *minp, uint32_t *maxp)
+{
+ static uint32_t last_avg = 0, last_max = 0, last_min = 0;
+
+ latency_op(cfg, offsetof(CONFIG_THREAD, update), avgp, minp, maxp);
+
+ /*
+ * If nothing happened, graph the average, minimum and maximum as they
+ * were the last time, it keeps the graphs from having discontinuities.
+ */
+ if (*minp == 0) {
+ *avgp = last_avg;
+ *minp = last_min;
+ *maxp = last_max;
+ } else {
+ last_avg = *avgp;
+ last_min = *minp;
+ last_max = *maxp;
+ }
+}
+
+/*
+ * sum_latency --
+ * Sum latency for a set of threads.
+ */
+static void
+sum_latency(CONFIG *cfg, size_t field_offset, TRACK *total)
+{
+ CONFIG_THREAD *thread;
+ TRACK *trk;
+ int64_t i;
+ u_int j;
+
+ memset(total, 0, sizeof(*total));
+
+ for (i = 0, thread = cfg->workers;
+ thread != NULL && i < cfg->workers_cnt; ++i, ++thread) {
+ trk = (TRACK *)((uint8_t *)thread + field_offset);
+
+ for (j = 0; j < ELEMENTS(trk->us); ++j) {
+ total->ops += trk->us[j];
+ total->us[j] += trk->us[j];
+ }
+ for (j = 0; j < ELEMENTS(trk->ms); ++j) {
+ total->ops += trk->ms[j];
+ total->ms[j] += trk->ms[j];
+ }
+ for (j = 0; j < ELEMENTS(trk->sec); ++j) {
+ total->ops += trk->sec[j];
+ total->sec[j] += trk->sec[j];
+ }
+ }
+}
+static void
+sum_insert_latency(CONFIG *cfg, TRACK *total)
+{
+ sum_latency(cfg, offsetof(CONFIG_THREAD, insert), total);
+}
+static void
+sum_read_latency(CONFIG *cfg, TRACK *total)
+{
+ sum_latency(cfg, offsetof(CONFIG_THREAD, read), total);
+}
+static void
+sum_update_latency(CONFIG *cfg, TRACK *total)
+{
+ sum_latency(cfg, offsetof(CONFIG_THREAD, update), total);
+}
+
+static void
+latency_print_single(CONFIG *cfg, TRACK *total, const char *name)
+{
+ FILE *fp;
+ u_int i;
+ uint64_t cumops;
+ char path[1024];
+
+ snprintf(path, sizeof(path), "%s/latency.%s", cfg->monitor_dir, name);
+ if ((fp = fopen(path, "w")) == NULL) {
+ lprintf(cfg, errno, 0, "%s", path);
+ return;
+ }
+
+ fprintf(fp,
+ "#usecs,operations,cumulative-operations,total-operations\n");
+ cumops = 0;
+ for (i = 0; i < ELEMENTS(total->us); ++i) {
+ if (total->us[i] == 0)
+ continue;
+ cumops += total->us[i];
+ fprintf(fp,
+ "%u,%" PRIu32 ",%" PRIu64 ",%" PRIu64 "\n",
+ (i + 1), total->us[i], cumops, total->ops);
+ }
+ for (i = 1; i < ELEMENTS(total->ms); ++i) {
+ if (total->ms[i] == 0)
+ continue;
+ cumops += total->ms[i];
+ fprintf(fp,
+ "%llu,%" PRIu32 ",%" PRIu64 ",%" PRIu64 "\n",
+ ms_to_us(i + 1), total->ms[i], cumops, total->ops);
+ }
+ for (i = 1; i < ELEMENTS(total->sec); ++i) {
+ if (total->sec[i] == 0)
+ continue;
+ cumops += total->sec[i];
+ fprintf(fp,
+ "%llu,%" PRIu32 ",%" PRIu64 ",%" PRIu64 "\n",
+ sec_to_us(i + 1), total->sec[i], cumops, total->ops);
+ }
+
+ (void)fclose(fp);
+}
+
+void
+latency_print(CONFIG *cfg)
+{
+ TRACK total;
+
+ sum_insert_latency(cfg, &total);
+ latency_print_single(cfg, &total, "insert");
+ sum_read_latency(cfg, &total);
+ latency_print_single(cfg, &total, "read");
+ sum_update_latency(cfg, &total);
+ latency_print_single(cfg, &total, "update");
+}