fio
*.o
+*.d
.depend
cscope.out
[netsplice] port=int
[net] port=int The TCP or UDP port to bind to or connect to.
+[netsplice] nodelay=bool
+[net] nodelay=bool Set TCP_NODELAY on TCP connections.
+
[netsplice] protocol=str
[netsplice] proto=str
[net] protocol=str
endif
OBJS = $(SOURCE:.c=.o)
+
FIO_OBJS = $(OBJS) fio.o
GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o goptions.o gerror.o \
gclient.o gcompat.o cairo_text_helpers.o printing.o
+-include $(OBJS:.o=.d)
+
T_SMALLOC_OBJS = t/stest.o
T_SMALLOC_OBJS += gettime.o mutex.o smalloc.o t/log.o
T_SMALLOC_PROGS = t/stest
mandir = $(prefix)/man
endif
-all: .depend $(PROGS) $(SCRIPTS) FORCE
+all: $(PROGS) $(SCRIPTS) FORCE
.PHONY: all install clean
.PHONY: FORCE cscope
@$(SHELL) ./FIO-VERSION-GEN
-include FIO-VERSION-FILE
-CFLAGS += -DFIO_VERSION='"$(FIO_VERSION)"'
+override CFLAGS += -DFIO_VERSION='"$(FIO_VERSION)"'
-.c.o: .depend FORCE
+.c.o: FORCE
$(QUIET_CC)$(CC) -o $@ $(CFLAGS) $(CPPFLAGS) -c $<
+ @$(CC) -MM $(CFLAGS) $(CPPFLAGS) $*.c > $*.d
+ @mv -f $*.d $*.d.tmp
+ @sed -e 's|.*:|$*.o:|' < $*.d.tmp > $*.d
+ @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \
+ sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
+ @rm -f $*.d.tmp
init.o: FIO-VERSION-FILE
$(QUIET_CC)$(CC) -o init.o $(CFLAGS) $(CPPFLAGS) -c init.c
t/axmap: $(T_AXMAP_OBJS)
$(QUIET_CC)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_AXMAP_OBJS) $(LIBS) $(LDFLAGS)
-.depend: $(SOURCE)
- $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
-
-$(PROGS): .depend
-
clean: FORCE
- -rm -f .depend $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) core.* core gfio FIO-VERSION-FILE config-host.mak cscope.out
+ -rm -f .depend $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) core.* core gfio FIO-VERSION-FILE config-host.mak cscope.out *.d
cscope:
@cscope -b -R
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
$(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
$(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
-
-ifneq ($(wildcard .depend),)
-include .depend
-endif
-
-
Windows
-------
-On Windows MinGW (http://www.mingw.org/) is required in order to
-build fio. To create an MSI installer package install WiX 3.6 from
-http://wix.sourceforge.net/releases/ and run dobuild.cmd from the
+On Windows Cygwin (http://www.cygwin.com/) is required in order to
+build fio. To create an MSI installer package install WiX 3.7 from
+http://wixtoolset.org and run dobuild.cmd from the
os/windows directory.
+How to compile FIO on 64-bit Windows:
+
+ 1. Install Cygwin (http://www.cygwin.com/setup.exe). Install 'make' and all
+ packages starting with 'mingw64-i686' and 'mingw64-x86_64'.
+ 2. Download ftp://sourceware.org/pub/pthreads-win32/prebuilt-dll-2-9-1-release/dll/x64/pthreadGC2.dll
+ and copy to the fio source directory.
+ 3. Open the Cygwin Terminal.
+ 4. Go to the fio directory (source files).
+ 5. Run 'make clean'.
+ 6. Run 'make'.
+
Command line
------------
#ifndef FIO_ARCH_X86_COMMON
#define FIO_ARCH_X86_COMMON
+#include <string.h>
+
static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
: "memory");
}
+static inline void cpuid(unsigned int op,
+ unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+{
+ *eax = op;
+ *ecx = 0;
+ do_cpuid(eax, ebx, ecx, edx);
+}
+
#define ARCH_HAVE_INIT
+
extern int tsc_reliable;
-static inline int arch_init(char *envp[])
+
+static inline int arch_init_intel(unsigned int level)
{
unsigned int eax, ebx, ecx = 0, edx;
*/
eax = 0x80000007;
do_cpuid(&eax, &ebx, &ecx, &edx);
- tsc_reliable = edx & (1U << 8);
+ return edx & (1U << 8);
+}
+
+static inline int arch_init_amd(unsigned int level)
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
+ if (eax < 0x80000007)
+ return 0;
+
+ cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+ if (edx & (1 << 8))
+ return 1;
+
+ return 0;
+}
+
+static inline int arch_init(char *envp[])
+{
+ unsigned int level;
+ char str[12];
+
+ cpuid(0, &level, (unsigned int *) &str[0],
+ (unsigned int *) &str[8],
+ (unsigned int *) &str[4]);
+
+ if (!strcmp(str, "GenuineIntel"))
+ tsc_reliable = arch_init_intel(level);
+ else if (!strcmp(str, "AuthenticAMD"))
+ tsc_reliable = arch_init_amd(level);
+
return 0;
}
i = td->cur_depth;
if (i) {
- ret = io_u_queued_complete(td, i, NULL);
+ ret = io_u_queued_complete(td, i, bytes_done);
if (td->o.fill_device && td->error == ENOSPC)
td->error = 0;
}
return 1;
}
- if (ddir_rw_sum(td->io_bytes) < td->o.size)
+ if (ddir_rw_sum(td->io_bytes) < td->o.size) {
+ uint64_t diff;
+
+ /*
+ * If the difference is less than the minimum IO size, we
+ * are done.
+ */
+ diff = td->o.size - ddir_rw_sum(td->io_bytes);
+ if (diff < td->o.rw_min_bs)
+ return 0;
+
return 1;
+ }
return 0;
}
o->trim_batch = le32_to_cpu(top->trim_batch);
o->trim_zero = le32_to_cpu(top->trim_zero);
o->clat_percentiles = le32_to_cpu(top->clat_percentiles);
- o->overwrite_plist = le32_to_cpu(top->overwrite_plist);
o->continue_on_error = le32_to_cpu(top->continue_on_error);
o->cgroup_weight = le32_to_cpu(top->cgroup_weight);
o->cgroup_nodelete = le32_to_cpu(top->cgroup_nodelete);
top->trim_batch = cpu_to_le32(o->trim_batch);
top->trim_zero = cpu_to_le32(o->trim_zero);
top->clat_percentiles = cpu_to_le32(o->clat_percentiles);
- top->overwrite_plist = cpu_to_le32(o->overwrite_plist);
top->continue_on_error = cpu_to_le32(o->continue_on_error);
top->cgroup_weight = cpu_to_le32(o->cgroup_weight);
top->cgroup_nodelete = cpu_to_le32(o->cgroup_nodelete);
fi
output_sym "CONFIG_LITTLE_ENDIAN"
output_sym "CONFIG_64BIT_LLP64"
- output_sym "CONFIG_CLOCK_GETTIME"
- output_sym "CONFIG_CLOCK_MONOTONIC"
- output_sym "CONFIG_GETTIMEOFDAY"
output_sym "CONFIG_FADVISE"
output_sym "CONFIG_SOCKLEN_T"
output_sym "CONFIG_POSIX_FALLOCATE"
output_sym "CONFIG_RUSAGE_THREAD"
output_sym "CONFIG_WINDOWSAIO"
output_sym "CONFIG_FDATASYNC"
+ output_sym "CONFIG_CLOCK_MONOTONIC"
output_sym "CONFIG_GETTIMEOFDAY"
output_sym "CONFIG_CLOCK_GETTIME"
output_sym "CONFIG_SCHED_IDLE"
static struct timeval rate_prev_time, disp_prev_time;
if (!force) {
- if (output_format != FIO_OUTPUT_NORMAL)
+ if (output_format != FIO_OUTPUT_NORMAL &&
+ f_out == stdout)
return 0;
if (temp_stall_ts || eta_print == FIO_ETA_NEVER)
return 0;
.BI (net,netsplice)port \fR=\fPint
The TCP or UDP port to bind to or connect to.
.TP
+.BI (net,netsplice)nodelay \fR=\fPbool
+Set TCP_NODELAY on TCP connections.
+.TP
.BI (net,netsplice)protocol \fR=\fPstr "\fR,\fP proto" \fR=\fPstr
The network protocol to use. Accepted values are:
.RS
extern int nr_clients;
extern int log_syslog;
extern const char fio_version_string[];
-extern const fio_fp64_t def_percentile_list[FIO_IO_U_LIST_MAX_LEN];
extern struct thread_data *threads;
static char cmd_optstr[256];
static int did_arg;
-const fio_fp64_t def_percentile_list[FIO_IO_U_LIST_MAX_LEN] = {
- { .u.f = 1.00 },
- { .u.f = 5.00 },
- { .u.f = 10.00 },
- { .u.f = 20.00 },
- { .u.f = 30.00 },
- { .u.f = 40.00 },
- { .u.f = 50.00 },
- { .u.f = 60.00 },
- { .u.f = 70.00 },
- { .u.f = 80.00 },
- { .u.f = 90.00 },
- { .u.f = 95.00 },
- { .u.f = 99.00 },
- { .u.f = 99.50 },
- { .u.f = 99.90 },
- { .u.f = 99.95 },
- { .u.f = 99.99 },
-};
-
#define FIO_CLIENT_FLAG (1 << 16)
/*
td->mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
td->ts.clat_percentiles = td->o.clat_percentiles;
- if (td->o.overwrite_plist)
- memcpy(td->ts.percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
- else
- memcpy(td->ts.percentile_list, def_percentile_list, sizeof(def_percentile_list));
+ memcpy(td->ts.percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
for (i = 0; i < DDIR_RWDIR_CNT; i++) {
td->ts.clat_stat[i].min_val = ULONG_MAX;
.lname = "Completion latency percentile list",
.type = FIO_OPT_FLOAT_LIST,
.off1 = td_var_offset(percentile_list),
- .off2 = td_var_offset(overwrite_plist),
.help = "Specify a custom list of percentiles to report",
+ .def = "1:5:10:20:30:40:50:60:70:80:90:95:99:99.5:99.9:99.95:99.99",
.maxlen = FIO_IO_U_LIST_MAX_LEN,
.minfp = 0.0,
.maxfp = 100.0,
.off1 = td_var_offset(unified_rw_rep),
.help = "Unify reporting across data direction",
.def = "0",
+ .category = FIO_OPT_C_GENERAL,
+ .group = FIO_OPT_G_INVALID,
},
{
.name = "continue_on_error",
#endif
#ifndef FIO_PREFERRED_CLOCK_SOURCE
+#ifdef CONFIG_CLOCK_GETTIME
#define FIO_PREFERRED_CLOCK_SOURCE CS_CGETTIME
+#else
+#define FIO_PREFERRED_CLOCK_SOURCE CS_GTOD
+#endif
#endif
#ifndef FIO_MAX_JOBS
#include <limits.h>
#include <stdlib.h>
#include <math.h>
+#include <float.h>
#include "parse.h"
#include "debug.h"
#include "options.h"
#include "minmax.h"
+#include "lib/ieee754.h"
static struct fio_option *__fio_options;
static void show_option_range(struct fio_option *o,
int (*logger)(const char *format, ...))
{
- if (o->type == FIO_OPT_FLOAT_LIST) {
- if (isnan(o->minfp) && isnan(o->maxfp))
+ if (o->type == FIO_OPT_FLOAT_LIST){
+ if (o->minfp == DBL_MIN && o->maxfp == DBL_MAX)
return;
logger("%20s: min=%f", "range", o->minfp);
- if (!isnan(o->maxfp))
+ if (o->maxfp != DBL_MAX)
logger(", max=%f", o->maxfp);
logger("\n");
} else {
int first, int more, int curr)
{
int il, *ilp;
- double *flp;
+ fio_fp64_t *flp;
long long ull, *ullp;
long ul1, ul2;
double uf;
break;
}
case FIO_OPT_FLOAT_LIST: {
-
- if (first) {
- ul2 = 1;
- ilp = td_var(data, o->off2);
- *ilp = ul2;
- }
if (curr >= o->maxlen) {
log_err("the list exceeding max length %d\n",
o->maxlen);
log_err("not a floating point value: %s\n", ptr);
return 1;
}
- if (!isnan(o->maxfp) && uf > o->maxfp) {
+ if (uf > o->maxfp) {
log_err("value out of range: %f"
" (range max: %f)\n", uf, o->maxfp);
return 1;
}
- if (!isnan(o->minfp) && uf < o->minfp) {
+ if (uf < o->minfp) {
log_err("value out of range: %f"
" (range min: %f)\n", uf, o->minfp);
return 1;
}
flp = td_var(data, o->off1);
- flp[curr] = uf;
+ flp[curr].u.f = uf;
break;
}
o->maxval = UINT_MAX;
}
if (o->type == FIO_OPT_FLOAT_LIST) {
-#ifndef NAN
-#define NAN __builtin_nanf("")
-#endif
- o->minfp = NAN;
- o->maxfp = NAN;
+ o->minfp = DBL_MIN;
+ o->maxfp = DBL_MAX;
}
if (o->type == FIO_OPT_STR_SET && o->def) {
log_err("Option %s: string set option with"
ts = &threadstats[j];
ts->clat_percentiles = td->o.clat_percentiles;
- if (td->o.overwrite_plist)
- memcpy(ts->percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
- else
- memcpy(ts->percentile_list, def_percentile_list, sizeof(def_percentile_list));
+ memcpy(ts->percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
idx++;
ts->members++;
unsigned int trim_zero;
unsigned long long trim_backlog;
unsigned int clat_percentiles;
- unsigned int overwrite_plist;
fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
char *read_iolog_file;
uint32_t trim_zero;
uint64_t trim_backlog;
uint32_t clat_percentiles;
- uint32_t overwrite_plist;
fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
uint8_t read_iolog_file[FIO_TOP_STR_MAX];