thread_number--;
}
+static int setup_rate(struct thread_data *td)
+{
+ unsigned long nr_reads_per_msec;
+ unsigned long long rate;
+ unsigned int bs;
+
+ if (!td->rate && !td->rate_iops)
+ return 0;
+
+ if (td_rw(td))
+ bs = td->rw_min_bs;
+ else if (td_read(td))
+ bs = td->min_bs[DDIR_READ];
+ else
+ bs = td->min_bs[DDIR_WRITE];
+
+ if (td->rate) {
+ rate = td->rate;
+ nr_reads_per_msec = (rate * 1024 * 1000LL) / bs;
+ } else
+ nr_reads_per_msec = td->rate_iops * 1000UL;
+
+ if (!nr_reads_per_msec) {
+ log_err("rate lower than supported\n");
+ return -1;
+ }
+
+ td->rate_usec_cycle = 1000000000ULL / nr_reads_per_msec;
+ td->rate_pending_usleep = 0;
+ return 0;
+}
+
/*
* Lazy way of fixing up options that depend on each other. We could also
* define option callback handlers, but this is easier.
*/
-static void fixup_options(struct thread_data *td)
+static int fixup_options(struct thread_data *td)
{
if (!td->rwmixread && td->rwmixwrite)
td->rwmixread = 100 - td->rwmixwrite;
if (td->open_files > td->nr_files || !td->open_files)
td->open_files = td->nr_files;
+
+ if ((td->rate && td->rate_iops) || (td->ratemin && td->rate_iops_min)) {
+ log_err("fio: rate and rate_iops are mutually exclusive\n");
+ return 1;
+ }
+ if ((td->rate < td->ratemin) || (td->rate_iops < td->rate_iops_min)) {
+ log_err("fio: minimum rate exceeds rate\n");
+ return 1;
+ }
+
+ return 0;
}
/*
td->io_ops = load_ioengine(td, engine);
if (!td->io_ops) {
log_err("fio: failed to load engine %s\n", engine);
- return 1;
+ goto err;
}
if (td->use_thread)
}
}
- fixup_options(td);
+ if (fixup_options(td))
+ goto err;
for_each_file(td, f, i) {
if (td->directory && f->filetype == FIO_TYPE_FILE) {