static struct timeval prev_time;
static unsigned int r_rate, w_rate;
unsigned long long io_bytes[2];
- unsigned long mtime;
+ unsigned long mtime, bw_avg_time;
if (temp_stall_ts || terse_output)
return;
io_bytes[0] = io_bytes[1] = 0;
nr_pending = nr_running = t_rate = m_rate = 0;
+ bw_avg_time = ULONG_MAX;
for_each_td(td, i) {
+ if (td->bw_avg_time < bw_avg_time)
+ bw_avg_time = td->bw_avg_time;
if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING||
td->runstate == TD_FSYNCING) {
nr_running++;
}
mtime = mtime_since_now(&prev_time);
- if (mtime > 1000) {
+ if (mtime > bw_avg_time) {
r_rate = (io_bytes[0] - prev_io_bytes[0]) / mtime;
w_rate = (io_bytes[1] - prev_io_bytes[1]) / mtime;
fio_gettime(&prev_time, NULL);
+ add_agg_sample(r_rate, DDIR_READ);
+ add_agg_sample(w_rate, DDIR_WRITE);
memcpy(prev_io_bytes, io_bytes, sizeof(io_bytes));
}
static volatile int startup_sem;
static volatile int fio_abort;
+struct io_log *agg_io_log[2];
+
#define TERMINATE_ALL (-1)
#define JOB_START_TIMEOUT (5 * 1000)
return 1;
}
+ if (write_bw_log) {
+ setup_log(&agg_io_log[DDIR_READ]);
+ setup_log(&agg_io_log[DDIR_WRITE]);
+ }
+
disk_util_timer_arm();
run_threads();
- if (!fio_abort)
+ if (!fio_abort) {
show_run_stats();
+ if (write_bw_log) {
+ __finish_log(agg_io_log[DDIR_READ],"agg-read_bw.log");
+ __finish_log(agg_io_log[DDIR_WRITE],"agg-write_bw.log");
+ }
+ }
return 0;
}
extern void disk_util_timer_arm(void);
extern void setup_log(struct io_log **);
extern void finish_log(struct thread_data *, struct io_log *, const char *);
+extern void __finish_log(struct io_log *, const char *);
extern int setup_rate(struct thread_data *);
+extern struct io_log *agg_io_log[2];
+extern int write_bw_log;
+extern void add_agg_sample(unsigned long, enum fio_ddir);
/*
* Time functions
FILE *f_err = NULL;
static int write_lat_log = 0;
-static int write_bw_log = 0;
+int write_bw_log = 0;
/*
* Return a free job structure.
*log = l;
}
-void finish_log(struct thread_data *td, struct io_log *log, const char *name)
+void __finish_log(struct io_log *log, const char *name)
{
- char file_name[256];
- FILE *f;
unsigned int i;
+ FILE *f;
- snprintf(file_name, 200, "client%d_%s.log", td->thread_number, name);
- f = fopen(file_name, "w");
+ f = fopen(name, "w");
if (!f) {
perror("fopen log");
return;
free(log->log);
free(log);
}
+
+void finish_log(struct thread_data *td, struct io_log *log, const char *name)
+{
+ char file_name[256];
+
+ snprintf(file_name, 200, "client%d_%s.log", td->thread_number, name);
+ __finish_log(log, file_name);
+}
if (!(td->io_bytes[0] + td->io_bytes[1]) && !td->error)
return;
- fprintf(f_out, "%s: (groupid=%d): err=%2d:\n",td->name, td->groupid, td->error);
+ fprintf(f_out, "%s: (groupid=%d): err=%2d: pid=%d\n",td->name, td->groupid, td->error, td->pid);
show_ddir_status(td, rs, td->ddir);
if (td->io_bytes[td->ddir ^ 1])
is->samples++;
}
-static void add_log_sample(struct thread_data *td, struct io_log *iolog,
- unsigned long val, enum fio_ddir ddir)
+static void __add_log_sample(struct io_log *iolog, unsigned long val,
+ enum fio_ddir ddir, unsigned long time)
{
if (iolog->nr_samples == iolog->max_samples) {
int new_size = sizeof(struct io_sample) * iolog->max_samples*2;
}
iolog->log[iolog->nr_samples].val = val;
- iolog->log[iolog->nr_samples].time = mtime_since_now(&td->epoch);
+ iolog->log[iolog->nr_samples].time = time;
iolog->log[iolog->nr_samples].ddir = ddir;
iolog->nr_samples++;
}
+static void add_log_sample(struct thread_data *td, struct io_log *iolog,
+ unsigned long val, enum fio_ddir ddir)
+{
+ __add_log_sample(iolog, val, ddir, mtime_since_now(&td->epoch));
+}
+
+void add_agg_sample(unsigned long val, enum fio_ddir ddir)
+{
+ struct io_log *iolog = agg_io_log[ddir];
+
+ __add_log_sample(iolog, val, ddir, mtime_since_genesis());
+}
+
void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
unsigned long msec)
{