switch (td->runstate) {
case TD_REAPED:
- c = '_';
+ if (td->error)
+ c = 'X';
+ else if (td->sig)
+ c = 'K';
+ else
+ c = '_';
break;
case TD_EXITED:
c = 'E';
static void calc_rate(unsigned long mtime, unsigned long long *io_bytes,
unsigned long long *prev_io_bytes, unsigned int *rate)
{
- rate[0] = (io_bytes[0] - prev_io_bytes[0]) / mtime;
- rate[1] = (io_bytes[1] - prev_io_bytes[1]) / mtime;
+ int i;
+
+ for (i = 0; i <= DDIR_WRITE; i++) {
+ unsigned long long diff;
+
+ diff = io_bytes[i] - prev_io_bytes[i];
+ rate[i] = ((1000 * diff) / mtime) / 1024;
+ }
prev_io_bytes[0] = io_bytes[0];
prev_io_bytes[1] = io_bytes[1];
}
* Print status of the jobs we know about. This includes rate estimates,
* ETA, thread state, etc.
*/
-int calc_thread_status(struct jobs_eta *je)
+int calc_thread_status(struct jobs_eta *je, int force)
{
struct thread_data *td;
int i;
static unsigned long long disp_io_bytes[2];
static unsigned long long disp_io_iops[2];
static struct timeval rate_prev_time, disp_prev_time;
- int i2p = 0;
- if (temp_stall_ts || terse_output || eta_print == FIO_ETA_NEVER)
- return 0;
+ if (!force) {
+ if (temp_stall_ts || terse_output || eta_print == FIO_ETA_NEVER)
+ return 0;
- if (!isatty(STDOUT_FILENO) && (eta_print != FIO_ETA_ALWAYS))
- return 0;
+ if (!isatty(STDOUT_FILENO) && (eta_print != FIO_ETA_ALWAYS))
+ return 0;
+ }
if (!rate_io_bytes[0] && !rate_io_bytes[1])
fill_start_time(&rate_prev_time);
io_iops[0] = io_iops[1] = 0;
bw_avg_time = ULONG_MAX;
for_each_td(td, i) {
+ if (is_power_of_2(td->o.kb_base))
+ je->is_pow2 = 1;
if (td->o.bw_avg_time < bw_avg_time)
bw_avg_time = td->o.bw_avg_time;
if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING
|| td->runstate == TD_FSYNCING
|| td->runstate == TD_PRE_READING) {
je->nr_running++;
- je->t_rate += td->o.rate[0] + td->o.rate[1];
- je->m_rate += td->o.ratemin[0] + td->o.ratemin[1];
- je->t_iops += td->o.rate_iops[0] + td->o.rate_iops[1];
- je->m_iops += td->o.rate_iops_min[0] +
- td->o.rate_iops_min[1];
+ if (td_read(td)) {
+ je->t_rate += td->o.rate[DDIR_READ];
+ je->t_iops += td->o.rate_iops[DDIR_READ];
+ je->m_rate += td->o.ratemin[DDIR_READ];
+ je->m_iops += td->o.rate_iops_min[DDIR_READ];
+ }
+ if (td_write(td)) {
+ je->t_rate += td->o.rate[DDIR_WRITE];
+ je->t_iops += td->o.rate_iops[DDIR_WRITE];
+ je->m_rate += td->o.ratemin[DDIR_WRITE];
+ je->m_iops += td->o.rate_iops_min[DDIR_WRITE];
+ }
je->files_open += td->nr_open_files;
} else if (td->runstate == TD_RAMP) {
je->nr_running++;
je->eta_sec = 0;
for_each_td(td, i) {
- if (!i2p && is_power_of_2(td->o.kb_base))
- i2p = 1;
if (exitall_on_terminate) {
if (eta_secs[i] < je->eta_sec)
je->eta_sec = eta_secs[i];
/*
* Allow a little slack, the target is to print it every 1000 msecs
*/
- if (disp_time < 900)
+ if (!force && disp_time < 900)
return 0;
calc_rate(disp_time, io_bytes, disp_io_bytes, je->rate);
memcpy(&disp_prev_time, &now, sizeof(now));
- if (!je->nr_running && !je->nr_pending)
+ if (!force && !je->nr_running && !je->nr_pending)
return 0;
je->nr_threads = thread_number;
{
static int linelen_last;
static int eta_good;
- char output[512], *p = output;
+ char output[REAL_MAX_JOBS + 512], *p = output;
char eta_str[128];
double perc = 0.0;
- int i2p = 0;
if (je->eta_sec != INT_MAX && je->elapsed_sec) {
perc = (double) je->elapsed_sec / (double) (je->elapsed_sec + je->eta_sec);
if (je->m_rate || je->t_rate) {
char *tr, *mr;
- mr = num2str(je->m_rate, 4, 0, i2p);
- tr = num2str(je->t_rate, 4, 0, i2p);
+ mr = num2str(je->m_rate, 4, 0, je->is_pow2);
+ tr = num2str(je->t_rate, 4, 0, je->is_pow2);
p += sprintf(p, ", CR=%s/%s KB/s", tr, mr);
free(tr);
free(mr);
char perc_str[32];
char *iops_str[2];
char *rate_str[2];
+ size_t left;
int l;
if ((!je->eta_sec && !eta_good) || je->nr_ramp == je->nr_running)
sprintf(perc_str, "%3.1f%% done", perc);
}
- rate_str[0] = num2str(je->rate[0], 5, 10, i2p);
- rate_str[1] = num2str(je->rate[1], 5, 10, i2p);
+ rate_str[0] = num2str(je->rate[0], 5, 1024, je->is_pow2);
+ rate_str[1] = num2str(je->rate[1], 5, 1024, je->is_pow2);
iops_str[0] = num2str(je->iops[0], 4, 1, 0);
iops_str[1] = num2str(je->iops[1], 4, 1, 0);
- l = sprintf(p, ": [%s] [%s] [%s/%s /s] [%s/%s iops] [eta %s]",
+ left = sizeof(output) - (p - output) - 1;
+
+ l = snprintf(p, left, ": [%s] [%s] [%s/%s /s] [%s/%s iops] [eta %s]",
je->run_str, perc_str, rate_str[0],
rate_str[1], iops_str[0], iops_str[1], eta_str);
p += l;
void print_thread_status(void)
{
struct jobs_eta *je;
+ size_t size;
- je = malloc(sizeof(*je) + thread_number * sizeof(char));
+ if (!thread_number)
+ return;
- memset(je, 0, sizeof(*je) + thread_number * sizeof(char));
+ size = sizeof(*je) + thread_number * sizeof(char) + 1;
+ je = malloc(size);
+ memset(je, 0, size);
- if (calc_thread_status(je))
+ if (calc_thread_status(je, 0))
display_thread_status(je);
free(je);