+ if (!force && !je->nr_running && !je->nr_pending)
+ return false;
+
+ je->nr_threads = thread_number;
+ update_condensed_str(__run_str, run_str);
+ memcpy(je->run_str, run_str, strlen(run_str));
+ return true;
+}
+
+static int gen_eta_str(struct jobs_eta *je, char *p, size_t left,
+ char **rate_str, char **iops_str)
+{
+ bool has_r = je->rate[DDIR_READ] || je->iops[DDIR_READ];
+ bool has_w = je->rate[DDIR_WRITE] || je->iops[DDIR_WRITE];
+ bool has_t = je->rate[DDIR_TRIM] || je->iops[DDIR_TRIM];
+ int l = 0;
+
+ if (!has_r && !has_w && !has_t)
+ return 0;
+
+ if (has_r) {
+ l += snprintf(p + l, left - l, "[r=%s", rate_str[DDIR_READ]);
+ if (!has_w)
+ l += snprintf(p + l, left - l, "]");
+ }
+ if (has_w) {
+ if (has_r)
+ l += snprintf(p + l, left - l, ",");
+ else
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "w=%s", rate_str[DDIR_WRITE]);
+ if (!has_t)
+ l += snprintf(p + l, left - l, "]");
+ }
+ if (has_t) {
+ if (has_r || has_w)
+ l += snprintf(p + l, left - l, ",");
+ else if (!has_r && !has_w)
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "t=%s]", rate_str[DDIR_TRIM]);
+ }
+ if (has_r) {
+ l += snprintf(p + l, left - l, "[r=%s", iops_str[DDIR_READ]);
+ if (!has_w)
+ l += snprintf(p + l, left - l, " IOPS]");
+ }
+ if (has_w) {
+ if (has_r)
+ l += snprintf(p + l, left - l, ",");
+ else
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "w=%s", iops_str[DDIR_WRITE]);
+ if (!has_t)
+ l += snprintf(p + l, left - l, " IOPS]");
+ }
+ if (has_t) {
+ if (has_r || has_w)
+ l += snprintf(p + l, left - l, ",");
+ else if (!has_r && !has_w)
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "t=%s IOPS]", iops_str[DDIR_TRIM]);
+ }
+
+ return l;
+}
+
+void display_thread_status(struct jobs_eta *je)
+{
+ static struct timespec disp_eta_new_line;
+ static int eta_new_line_init, eta_new_line_pending;
+ static int linelen_last;
+ static int eta_good;
+ char output[__THREAD_RUNSTR_SZ(REAL_MAX_JOBS) + 512], *p = output;
+ char eta_str[128];
+ double perc = 0.0;
+
+ if (je->eta_sec != INT_MAX && je->elapsed_sec) {
+ perc = (double) je->elapsed_sec / (double) (je->elapsed_sec + je->eta_sec);
+ eta_to_str(eta_str, je->eta_sec);
+ }
+
+ if (eta_new_line_pending) {
+ eta_new_line_pending = 0;
+ linelen_last = 0;
+ p += sprintf(p, "\n");
+ }
+
+ p += sprintf(p, "Jobs: %d (f=%d)", je->nr_running, je->files_open);
+
+ /* rate limits, if any */
+ if (je->m_rate[0] || je->m_rate[1] || je->m_rate[2] ||
+ je->t_rate[0] || je->t_rate[1] || je->t_rate[2]) {
+ char *tr, *mr;
+
+ mr = num2str(je->m_rate[0] + je->m_rate[1] + je->m_rate[2],
+ je->sig_figs, 0, je->is_pow2, N2S_BYTEPERSEC);
+ tr = num2str(je->t_rate[0] + je->t_rate[1] + je->t_rate[2],
+ je->sig_figs, 0, je->is_pow2, N2S_BYTEPERSEC);
+
+ p += sprintf(p, ", %s-%s", mr, tr);
+ free(tr);
+ free(mr);
+ } else if (je->m_iops[0] || je->m_iops[1] || je->m_iops[2] ||
+ je->t_iops[0] || je->t_iops[1] || je->t_iops[2]) {
+ p += sprintf(p, ", %d-%d IOPS",
+ je->m_iops[0] + je->m_iops[1] + je->m_iops[2],
+ je->t_iops[0] + je->t_iops[1] + je->t_iops[2]);
+ }
+
+ /* current run string, % done, bandwidth, iops, eta */
+ if (je->eta_sec != INT_MAX && je->nr_running) {
+ char perc_str[32];
+ char *iops_str[DDIR_RWDIR_CNT];
+ char *rate_str[DDIR_RWDIR_CNT];
+ size_t left;
+ int l;
+ int ddir;
+ int linelen;
+
+ if ((!je->eta_sec && !eta_good) || je->nr_ramp == je->nr_running ||
+ je->eta_sec == -1)
+ strcpy(perc_str, "-.-%");
+ else {
+ double mult = 100.0;
+
+ if (je->nr_setting_up && je->nr_running)
+ mult *= (1.0 - (double) je->nr_setting_up / (double) je->nr_running);
+
+ eta_good = 1;
+ perc *= mult;
+ sprintf(perc_str, "%3.1f%%", perc);
+ }
+
+ for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++) {
+ rate_str[ddir] = num2str(je->rate[ddir], 4,
+ 1024, je->is_pow2, je->unit_base);
+ iops_str[ddir] = num2str(je->iops[ddir], 4, 1, 0, N2S_NONE);
+ }
+
+ left = sizeof(output) - (p - output) - 1;
+ l = snprintf(p, left, ": [%s][%s]", je->run_str, perc_str);
+ l += gen_eta_str(je, p + l, left - l, rate_str, iops_str);
+ l += snprintf(p + l, left - l, "[eta %s]", eta_str);
+
+ /* If truncation occurred adjust l so p is on the null */
+ if (l >= left)
+ l = left - 1;
+ p += l;
+ linelen = p - output;
+ if (l >= 0 && linelen < linelen_last)
+ p += sprintf(p, "%*s", linelen_last - linelen, "");
+ linelen_last = linelen;
+
+ for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++) {
+ free(rate_str[ddir]);
+ free(iops_str[ddir]);
+ }
+ }
+ sprintf(p, "\r");
+
+ printf("%s", output);