Change IO engine queuing
[fio.git] / fio.h
diff --git a/fio.h b/fio.h
index 6e0c5b18cb8fefef632396431164fc3633554491..b087f97285f0a7b7682538cc1d76c34846a3cc1e 100644 (file)
--- a/fio.h
+++ b/fio.h
 #include "arch.h"
 #include "os.h"
 
+#ifdef FIO_HAVE_SYSLET
+#include "syslet.h"
+#endif
+
 enum fio_ddir {
        DDIR_READ = 0,
        DDIR_WRITE,
        DDIR_SYNC,
 };
 
+/*
+ * Use for maintaining statistics
+ */
 struct io_stat {
        unsigned long max_val;
        unsigned long min_val;
@@ -33,26 +40,42 @@ struct io_stat {
        double S;
 };
 
+/*
+ * A single data sample
+ */
 struct io_sample {
        unsigned long time;
        unsigned long val;
        enum fio_ddir ddir;
 };
 
+/*
+ * Dynamically growing data sample log
+ */
 struct io_log {
        unsigned long nr_samples;
        unsigned long max_samples;
        struct io_sample *log;
 };
 
+/*
+ * When logging io actions, this matches a single sent io_u
+ */
 struct io_piece {
        struct list_head list;
        struct fio_file *file;
        unsigned long long offset;
-       unsigned int len;
+       unsigned long len;
        enum fio_ddir ddir;
 };
 
+#ifdef FIO_HAVE_SYSLET
+struct syslet_req {
+       struct syslet_uatom atom;
+       long ret;
+};
+#endif
+
 /*
  * The io unit
  */
@@ -66,15 +89,28 @@ struct io_u {
 #endif
 #ifdef FIO_HAVE_SGIO
                struct sg_io_hdr hdr;
+#endif
+#ifdef FIO_HAVE_SYSLET
+               struct syslet_req req;
 #endif
        };
        struct timeval start_time;
        struct timeval issue_time;
 
+       /*
+        * Allocated/set buffer and length
+        */
        void *buf;
-       unsigned int buflen;
+       unsigned long buflen;
        unsigned long long offset;
 
+       /*
+        * IO engine state, may be different from above when we get
+        * partial transfers / residual data counts
+        */
+       void *xfer_buf;
+       unsigned long xfer_buflen;
+
        unsigned int resid;
        unsigned int error;
 
@@ -93,14 +129,25 @@ struct io_u {
        struct list_head list;
 };
 
+/*
+ * io_ops->queue() return values
+ */
+enum {
+       FIO_Q_COMPLETED = 0,            /* completed sync */
+       FIO_Q_QUEUED    = 1,            /* queued, will complete async */
+};
+
 #define FIO_HDR_MAGIC  0xf00baaef
 
 enum {
-       VERIFY_NONE = 0,
-       VERIFY_MD5,
-       VERIFY_CRC32,
+       VERIFY_NONE = 0,                /* no verification */
+       VERIFY_MD5,                     /* md5 sum data blocks */
+       VERIFY_CRC32,                   /* crc32 sum data blocks */
 };
 
+/*
+ * A header structure associated with each checksummed data block
+ */
 struct verify_header {
        unsigned int fio_magic;
        unsigned int len;
@@ -133,18 +180,24 @@ enum fio_memtype {
  * The type of object we are working on
  */
 enum fio_filetype {
-       FIO_TYPE_FILE = 1,
-       FIO_TYPE_BD,
-       FIO_TYPE_CHAR,
+       FIO_TYPE_FILE = 1,              /* plain file */
+       FIO_TYPE_BD,                    /* block device */
+       FIO_TYPE_CHAR,                  /* character device */
 };
 
 enum fio_ioengine_flags {
-       FIO_SYNCIO      = 1 << 0,
-       FIO_CPUIO       = 1 << 1,
-       FIO_MMAPIO      = 1 << 2,
-       FIO_RAWIO       = 1 << 3,
+       FIO_SYNCIO      = 1 << 0,       /* io engine has synchronous ->queue */
+       FIO_CPUIO       = 1 << 1,       /* cpu burner, doesn't do real io */
+       FIO_MMAPIO      = 1 << 2,       /* uses memory mapped io */
+       FIO_RAWIO       = 1 << 3,       /* some sort of direct/raw io */
+       FIO_NETIO       = 1 << 4,       /* networked io */
+       FIO_NULLIO      = 1 << 5,       /* no real data transfer (cpu/null) */
 };
 
+/*
+ * Each thread_data structure has a number of files associated with it,
+ * this structure holds state information for a single file.
+ */
 struct fio_file {
        /*
         * A file may not be a file descriptor, let the io engine decide
@@ -161,8 +214,12 @@ struct fio_file {
        unsigned long long last_pos;
        unsigned long long last_completed_pos;
 
+       /*
+        * block map for random io
+        */
        unsigned long *file_map;
        unsigned int num_maps;
+       unsigned int last_free_lookup;
 
        unsigned int unlink;
 };
@@ -171,11 +228,13 @@ struct fio_file {
  * How many depth levels to log
  */
 #define FIO_IO_U_MAP_NR        8
+#define FIO_IO_U_LAT_NR 12
 
 /*
  * This describes a single thread/process executing a fio job.
  */
 struct thread_data {
+       char *description;
        char *name;
        char *directory;
        char *filename;
@@ -223,6 +282,7 @@ struct thread_data {
        unsigned int hugepage_size;
        unsigned int rw_min_bs;
        unsigned int thinktime;
+       unsigned int thinktime_spin;
        unsigned int thinktime_blocks;
        unsigned int fsync_blocks;
        unsigned int start_delay;
@@ -270,6 +330,7 @@ struct thread_data {
         */
        unsigned int cur_depth;
        unsigned int io_u_map[FIO_IO_U_MAP_NR];
+       unsigned int io_u_lat[FIO_IO_U_LAT_NR];
        unsigned long total_io_u;
        struct list_head io_u_freelist;
        struct list_head io_u_busylist;
@@ -401,6 +462,9 @@ static inline int should_fsync(struct thread_data *td)
        return 0;
 }
 
+/*
+ * Disk utils as read in /sys/block/<dev>/stat
+ */
 struct disk_util_stat {
        unsigned ios[2];
        unsigned merges[2];
@@ -410,6 +474,9 @@ struct disk_util_stat {
        unsigned time_in_queue;
 };
 
+/*
+ * Per-device disk util management
+ */
 struct disk_util {
        struct list_head list;
 
@@ -424,6 +491,9 @@ struct disk_util {
        struct timeval time;
 };
 
+/*
+ * Used for passing io_u completion data
+ */
 struct io_completion_data {
        int nr;                         /* input */
 
@@ -546,6 +616,7 @@ extern struct io_u *get_io_u(struct thread_data *, struct fio_file *);
 extern void put_io_u(struct thread_data *, struct io_u *);
 extern void ios_completed(struct thread_data *, struct io_completion_data *);
 extern void io_completed(struct thread_data *, struct io_u *, struct io_completion_data *);
+extern void init_icd(struct io_completion_data *);
 
 /*
  * io engine entry points
@@ -604,9 +675,10 @@ struct ioengine_ops {
        void (*cleanup)(struct thread_data *);
        void *data;
        void *dlhandle;
+       unsigned long priv;
 };
 
-#define FIO_IOOPS_VERSION      3
+#define FIO_IOOPS_VERSION      4
 
 extern struct ioengine_ops *load_ioengine(struct thread_data *, const char *);
 extern int register_ioengine(struct ioengine_ops *);
@@ -625,4 +697,14 @@ extern void close_ioengine(struct thread_data *);
 #define for_each_file(td, f, i)        \
        for ((i) = 0, (f) = &(td)->files[0]; (i) < (int) (td)->nr_files; (i)++, (f)++)
 
+#define fio_assert(td, cond)   do {    \
+       if (!(cond)) {                  \
+               int *__foo = NULL;      \
+               fprintf(stderr, "file:%s:%d, assert %s failed\n", __FILE__, __LINE__, #cond);   \
+               (td)->runstate = TD_EXITED;     \
+               (td)->error = EFAULT;           \
+               *__foo = 0;                     \
+       }       \
+} while (0)
+
 #endif