Add option to select how to service multiple files
[fio.git] / fio.h
diff --git a/fio.h b/fio.h
index aeb45bf73611bd718ae0cfd89294b04c600e9fb6..8c46b3f905b2d9eb5b320ca96d05e2b8117b8e8d 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -76,6 +76,11 @@ struct syslet_req {
 };
 #endif
 
+enum {
+       IO_U_F_FREE     = 1 << 0,
+       IO_U_F_FLIGHT   = 1 << 1,
+};
+
 /*
  * The io unit
  */
@@ -124,6 +129,8 @@ struct io_u {
                unsigned int seen;
        };
 
+       unsigned int flags;
+
        struct fio_file *file;
 
        struct list_head list;
@@ -273,7 +280,10 @@ struct thread_data {
        struct fio_file *files;
        unsigned int nr_files;
        unsigned int nr_uniq_files;
-       unsigned int next_file;
+       union {
+               unsigned int next_file;
+               os_random_state_t next_file_state;
+       };
        int error;
        pid_t pid;
        char *orig_buffer;
@@ -333,6 +343,7 @@ struct thread_data {
        unsigned int rwmixread;
        unsigned int rwmixwrite;
        unsigned int nice;
+       unsigned int file_service_type;
 
        char *read_iolog_file;
        char *write_iolog_file;
@@ -421,20 +432,43 @@ struct thread_data {
         */
        struct list_head io_hist_list;
        struct list_head io_log_list;
+
+       /*
+        * timeout handling
+        */
+       struct timeval timeout_end;
+       struct itimerval timer;
 };
 
-#define __td_verror(td, err, msg)                                      \
+/*
+ * roundrobin available files, or choose one at random.
+ */
+enum {
+       FIO_FSERVICE_RANDOM     = 1,
+       FIO_FSERVICE_RR         = 2,
+};
+
+/*
+ * 30 second per-io_u timeout, with 5 second intervals to avoid resetting
+ * the timer on each queue operation.
+ */
+#define IO_U_TIMEOUT_INC       5
+#define IO_U_TIMEOUT           30
+
+#define __td_verror(td, err, msg, func)                                        \
        do {                                                            \
                if ((td)->error)                                        \
                        break;                                          \
                int e = (err);                                          \
                (td)->error = e;                                        \
-               snprintf(td->verror, sizeof(td->verror) - 1, "file:%s:%d, error=%s", __FILE__, __LINE__, (msg));        \
+               snprintf(td->verror, sizeof(td->verror) - 1, "file:%s:%d, func=%s, error=%s", __FILE__, __LINE__, (func), (msg));       \
        } while (0)
 
 
-#define td_verror(td, err)     __td_verror((td), (err), strerror((err)))
-#define td_vmsg(td, err, msg)  __td_verror((td), (err), (msg))
+#define td_verror(td, err, func)       \
+       __td_verror((td), (err), strerror((err)), (func))
+#define td_vmsg(td, err, msg, func)    \
+       __td_verror((td), (err), (msg), (func))
 
 extern int exitall_on_terminate;
 extern int thread_number;
@@ -557,6 +591,7 @@ extern void usec_sleep(struct thread_data *, unsigned long);
 extern void rate_throttle(struct thread_data *, unsigned long, unsigned int, int);
 extern void fill_start_time(struct timeval *);
 extern void fio_gettime(struct timeval *, void *);
+extern void set_genesis_time(void);
 
 /*
  * Init functions
@@ -621,6 +656,8 @@ extern void requeue_io_u(struct thread_data *, struct io_u **);
 extern long __must_check io_u_sync_complete(struct thread_data *, struct io_u *, endio_handler *);
 extern long __must_check io_u_queued_complete(struct thread_data *, int, endio_handler *);
 extern void io_u_queued(struct thread_data *, struct io_u *);
+extern void io_u_init_timeout(void);
+extern void io_u_set_timeout(struct thread_data *);
 
 /*
  * io engine entry points