} else
perc = -1;
- if (str_to_decimal(fname, &val, 1, o)) {
+ if (str_to_decimal(fname, &val, 1, o, 0)) {
log_err("fio: bssplit conversion failed\n");
free(bssplit);
return 1;
else {
long long val;
- if (str_to_decimal(nr, &val, 1, o)) {
+ if (str_to_decimal(nr, &val, 1, o, 0)) {
log_err("fio: rw postfix parsing failed\n");
free(nr);
return 1;
}
#ifdef FIO_HAVE_CPU_AFFINITY
+int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu_index)
+{
+ unsigned int i, index, cpus_in_mask;
+ const long max_cpu = cpus_online();
+
+ cpus_in_mask = fio_cpu_count(mask);
+ cpu_index = cpu_index % cpus_in_mask;
+
+ index = 0;
+ for (i = 0; i < max_cpu; i++) {
+ if (!fio_cpu_isset(mask, i))
+ continue;
+
+ if (cpu_index != index)
+ fio_cpu_clear(mask, i);
+
+ index++;
+ }
+
+ return fio_cpu_count(mask);
+}
+
static int str_cpumask_cb(void *data, unsigned long long *val)
{
struct thread_data *td = data;
while ((fname = get_next_name(&str)) != NULL) {
if (!strlen(fname))
break;
- add_file(td, fname, 0);
- td->o.nr_files++;
+ add_file(td, fname, 0, 1);
}
free(p);
.off2 = td_var_offset(start_delay_high),
.help = "Only start job when this period has passed",
.def = "0",
+ .is_seconds = 1,
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_RUNTIME,
},
.off1 = td_var_offset(timeout),
.help = "Stop workload when this amount of time has passed",
.def = "0",
+ .is_seconds = 1,
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_RUNTIME,
},
.type = FIO_OPT_STR_VAL_TIME,
.off1 = td_var_offset(ramp_time),
.help = "Ramp up time before measuring performance",
+ .is_seconds = 1,
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_RUNTIME,
},
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_CRED,
},
+ {
+ .name = "cpus_allowed_policy",
+ .lname = "CPUs allowed distribution policy",
+ .type = FIO_OPT_STR,
+ .off1 = td_var_offset(cpus_allowed_policy),
+ .help = "Distribution policy for cpus_allowed",
+ .parent = "cpus_allowed",
+ .prio = 1,
+ .posval = {
+ { .ival = "shared",
+ .oval = FIO_CPUS_SHARED,
+ .help = "Mask shared between threads",
+ },
+ { .ival = "split",
+ .oval = FIO_CPUS_SPLIT,
+ .help = "Mask split between threads",
+ },
+ },
+ .category = FIO_OPT_C_GENERAL,
+ .group = FIO_OPT_G_CRED,
+ },
#endif
#ifdef CONFIG_LIBNUMA
{
void fio_fill_default_options(struct thread_data *td)
{
+ td->o.magic = OPT_MAGIC;
fill_default_options(td, fio_options);
}
struct thread_options *o = data;
unsigned int kb_base = 0;
- if (o)
+ /*
+ * This is a hack... For private options, *data is not holding
+ * a pointer to the thread_options, but to private data. This means
+ * we can't safely dereference it, but magic is first so mem wise
+ * it is valid. But this also means that if the job first sets
+ * kb_base and expects that to be honored by private options,
+ * it will be disappointed. We will return the global default
+ * for this.
+ */
+ if (o && o->magic == OPT_MAGIC)
kb_base = o->kb_base;
if (!kb_base)
kb_base = 1024;