static int repeatable = DEF_RAND_REPEAT;
static int rate_quit = 1;
+static int write_lat_log;
+static int write_bw_log;
static int thread_number;
static char *ini_file;
unsigned long samples;
};
+struct io_sample {
+ unsigned long time;
+ unsigned long val;
+};
+
+struct io_log {
+ unsigned long nr_samples;
+ unsigned long max_samples;
+ struct io_sample *log;
+};
+
#define td_read(td) ((td)->ddir == DDIR_READ)
#define should_fsync(td) (!td_read(td) && !(td)->odirect)
unsigned long stat_io_blocks;
struct timeval stat_sample_time;
+ struct io_log *lat_log;
+ struct io_log *bw_log;
+
struct timeval start;
};
is->samples++;
}
+static void add_log_sample(struct thread_data *td, struct io_log *log,
+ unsigned long val)
+{
+ if (log->nr_samples == log->max_samples) {
+ int new_size = sizeof(struct io_sample) * log->max_samples * 2;
+
+ log->log = realloc(log->log, new_size);
+ log->max_samples <<= 1;
+ }
+
+ log->log[log->nr_samples].val = val;
+ log->log[log->nr_samples].time = mtime_since_now(&td->start);
+ log->nr_samples++;
+}
+
static void add_clat_sample(struct thread_data *td, unsigned long msec)
{
add_stat_sample(td, &td->clat_stat, msec);
+
+ if (td->lat_log)
+ add_log_sample(td, td->lat_log, msec);
}
static void add_slat_sample(struct thread_data *td, unsigned long msec)
rate = ((td->io_blocks - td->stat_io_blocks) * td->bs) / spent;
add_stat_sample(td, &td->bw_stat, rate);
+ if (td->bw_log)
+ add_log_sample(td, td->bw_log, rate);
+
gettimeofday(&td->stat_sample_time, NULL);
td->stat_io_blocks = td->io_blocks;
}
}
}
+static void setup_log(struct io_log **log)
+{
+ struct io_log *l = malloc(sizeof(*l));
+
+ l->nr_samples = 0;
+ l->max_samples = 1024;
+ l->log = malloc(l->max_samples * sizeof(struct io_sample));
+ *log = l;
+}
+
+static void finish_log(struct thread_data *td, struct io_log *log, char *name)
+{
+ char file_name[128];
+ FILE *f;
+ int i;
+
+ sprintf(file_name, "client%d_%s.log", td->thread_number, name);
+ f = fopen(file_name, "w");
+ if (!f) {
+ perror("fopen log");
+ return;
+ }
+
+ for (i = 0; i < log->nr_samples; i++)
+ fprintf(f, "%lu, %lu\n", log->log[i].time, log->log[i].val);
+
+ fclose(f);
+ free(log->log);
+ free(log);
+}
+
static int create_file(struct thread_data *td)
{
unsigned int i;
td->runtime = mtime_since_now(&td->start);
ret = 0;
+
+ if (td->bw_log)
+ finish_log(td, td->bw_log, "bw");
+ if (td->lat_log)
+ finish_log(td, td->lat_log, "lat");
err:
if (td->use_aio)
cleanup_aio(td);
if (setup_rate(td))
return -1;
+ if (write_lat_log)
+ setup_log(&td->lat_log);
+ if (write_bw_log)
+ setup_log(&td->bw_log);
+
printf("Client%d: file=%s, rw=%d, prio=%d/%d, seq=%d, odir=%d, bs=%d, rate=%d, aio=%d, aio_depth=%d\n", td->thread_number, filename, td->ddir, prioclass, prio, td->sequential, td->odirect, td->bs, td->rate, td->use_aio, td->aio_depth);
return 0;
}
ini_file = strdup(argv[i+1]);
i++;
break;
+ case 'l':
+ write_lat_log = 1;
+ break;
+ case 'w':
+ write_bw_log = 1;
+ break;
default:
printf("bad option %s\n", argv[i]);
break;