rand: add 64-bit tausworthe variant with a 2^258 cycle
[fio.git] / fio.h
diff --git a/fio.h b/fio.h
index 28f459750bf53949541609015d62b3cead4ea97d..4e2532ff4db01da41ddd4d844b01e859d3182fc9 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -40,6 +40,7 @@
 #include "stat.h"
 #include "flow.h"
 #include "io_u_queue.h"
+#include "workqueue.h"
 
 #ifdef CONFIG_SOLARISAIO
 #include <sys/asynch.h>
@@ -74,6 +75,9 @@ enum {
        TD_F_COMPRESS           = 128,
        TD_F_NOIO               = 256,
        TD_F_COMPRESS_LOG       = 512,
+       TD_F_VSTATE_SAVED       = 1024,
+       TD_F_NEED_LOCK          = 2048,
+       TD_F_CHILD              = 4096,
 };
 
 enum {
@@ -93,6 +97,11 @@ enum {
        FIO_RAND_NR_OFFS,
 };
 
+enum {
+       IO_MODE_INLINE = 0,
+       IO_MODE_OFFLOAD,
+};
+
 /*
  * This describes a single thread/process executing a fio job.
  */
@@ -117,12 +126,21 @@ struct thread_data {
 
        struct tp_data *tp_data;
 
+       struct thread_data *parent;
+
        uint64_t stat_io_bytes[DDIR_RWDIR_CNT];
        struct timeval bw_sample_time;
 
        uint64_t stat_io_blocks[DDIR_RWDIR_CNT];
        struct timeval iops_sample_time;
 
+       /*
+        * Tracks the last iodepth number of completed writes, if data
+        * verification is enabled
+        */
+       uint64_t *last_write_comp;
+       unsigned int last_write_idx;
+
        volatile int update_rusage;
        struct fio_mutex *rusage_sem;
        struct rusage ru_start;
@@ -142,6 +160,7 @@ struct thread_data {
        int error;
        int sig;
        int done;
+       int stop_io;
        pid_t pid;
        char *orig_buffer;
        size_t orig_buffer_size;
@@ -171,6 +190,8 @@ struct thread_data {
        unsigned int verify_batch;
        unsigned int trim_batch;
 
+       struct thread_io_list *vstate;
+
        int shm_id;
 
        /*
@@ -221,17 +242,32 @@ struct thread_data {
        unsigned long rate_blocks[DDIR_RWDIR_CNT];
        struct timeval lastrate[DDIR_RWDIR_CNT];
 
+       /*
+        * Enforced rate submission/completion workqueue
+        */
+       struct workqueue io_wq;
+
        uint64_t total_io_size;
        uint64_t fill_device_size;
 
-       unsigned long io_issues[DDIR_RWDIR_CNT];
+       /*
+        * Issue side
+        */
+       uint64_t io_issues[DDIR_RWDIR_CNT];
+       uint64_t io_issue_bytes[DDIR_RWDIR_CNT];
+       uint64_t loops;
+
+       /*
+        * Completions
+        */
        uint64_t io_blocks[DDIR_RWDIR_CNT];
        uint64_t this_io_blocks[DDIR_RWDIR_CNT];
        uint64_t io_bytes[DDIR_RWDIR_CNT];
-       uint64_t io_skip_bytes;
        uint64_t this_io_bytes[DDIR_RWDIR_CNT];
+       uint64_t io_skip_bytes;
        uint64_t zone_bytes;
        struct fio_mutex *mutex;
+       uint64_t bytes_done[DDIR_RWDIR_CNT];
 
        /*
         * State for random io, a bitmap of blocks done vs not done
@@ -241,6 +277,7 @@ struct thread_data {
        struct timeval start;   /* start of this loop */
        struct timeval epoch;   /* time job was started */
        struct timeval last_issue;
+       long time_offset;
        struct timeval tv_cache;
        struct timeval terminate_time;
        unsigned int tv_cache_nr;
@@ -343,12 +380,23 @@ enum {
        } while (0)
 
 
-#define td_clear_error(td)             \
-       (td)->error = 0;
-#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))
+#define td_clear_error(td)             do {            \
+       (td)->error = 0;                                \
+       if ((td)->parent)                               \
+               (td)->parent->error = 0;                \
+} while (0)
+
+#define td_verror(td, err, func)       do {                    \
+       __td_verror((td), (err), strerror((err)), (func));      \
+       if ((td)->parent)                                       \
+               __td_verror((td)->parent, (err), strerror((err)), (func)); \
+} while (0)
+
+#define td_vmsg(td, err, msg, func)    do {                    \
+       __td_verror((td), (err), (msg), (func));                \
+       if ((td)->parent)                                       \
+               __td_verror((td)->parent, (err), (msg), (func));        \
+} while (0)
 
 #define __fio_stringify_1(x)   #x
 #define __fio_stringify(x)     __fio_stringify_1(x)
@@ -380,6 +428,10 @@ extern int status_interval;
 extern const char fio_version_string[];
 extern int helper_do_stat;
 extern pthread_cond_t helper_cond;
+extern char *trigger_file;
+extern char *trigger_cmd;
+extern char *trigger_remote_cmd;
+extern long long trigger_timeout;
 
 extern struct thread_data *threads;
 
@@ -412,6 +464,7 @@ extern void reset_fio_state(void);
 extern void clear_io_state(struct thread_data *);
 extern int fio_options_parse(struct thread_data *, char **, int, int);
 extern void fio_keywords_init(void);
+extern void fio_keywords_exit(void);
 extern int fio_cmd_option_parse(struct thread_data *, const char *, char *);
 extern int fio_cmd_ioengine_option_parse(struct thread_data *, const char *, char *);
 extern void fio_fill_default_options(struct thread_data *);
@@ -422,7 +475,7 @@ extern void fio_options_mem_dupe(struct thread_data *);
 extern void options_mem_dupe(void *data, struct fio_option *options);
 extern void td_fill_rand_seeds(struct thread_data *);
 extern void add_job_opts(const char **, int);
-extern char *num2str(unsigned long, int, int, int, int);
+extern char *num2str(uint64_t, int, int, int, int);
 extern int ioengine_load(struct thread_data *);
 extern int parse_dryrun(void);
 extern int fio_running_or_pending_io_threads(void);
@@ -431,6 +484,7 @@ extern int fio_set_fd_nonblocking(int, const char *);
 extern uintptr_t page_mask;
 extern uintptr_t page_size;
 extern int initialize_fio(char *envp[]);
+extern void deinitialize_fio(void);
 
 #define FIO_GETOPT_JOB         0x89000000
 #define FIO_GETOPT_IOENGINE    0x98000000
@@ -549,16 +603,15 @@ static inline int __should_check_rate(struct thread_data *td,
        return 0;
 }
 
-static inline int should_check_rate(struct thread_data *td,
-                                   uint64_t *bytes_done)
+static inline int should_check_rate(struct thread_data *td)
 {
        int ret = 0;
 
-       if (bytes_done[DDIR_READ])
+       if (td->bytes_done[DDIR_READ])
                ret |= __should_check_rate(td, DDIR_READ);
-       if (bytes_done[DDIR_WRITE])
+       if (td->bytes_done[DDIR_WRITE])
                ret |= __should_check_rate(td, DDIR_WRITE);
-       if (bytes_done[DDIR_TRIM])
+       if (td->bytes_done[DDIR_TRIM])
                ret |= __should_check_rate(td, DDIR_TRIM);
 
        return ret;
@@ -580,9 +633,9 @@ static inline unsigned int td_min_bs(struct thread_data *td)
        return min(td->o.min_bs[DDIR_TRIM], min_bs);
 }
 
-static inline int is_power_of_2(unsigned long val)
+static inline int td_async_processing(struct thread_data *td)
 {
-       return (val != 0 && ((val & (val - 1)) == 0));
+       return (td->flags & TD_F_NEED_LOCK) != 0;
 }
 
 /*
@@ -591,19 +644,19 @@ static inline int is_power_of_2(unsigned long val)
  */
 static inline void td_io_u_lock(struct thread_data *td)
 {
-       if (td->o.verify_async)
+       if (td_async_processing(td))
                pthread_mutex_lock(&td->io_u_lock);
 }
 
 static inline void td_io_u_unlock(struct thread_data *td)
 {
-       if (td->o.verify_async)
+       if (td_async_processing(td))
                pthread_mutex_unlock(&td->io_u_lock);
 }
 
 static inline void td_io_u_free_notify(struct thread_data *td)
 {
-       if (td->o.verify_async)
+       if (td_async_processing(td))
                pthread_cond_signal(&td->free_cond);
 }
 
@@ -624,11 +677,16 @@ enum {
        FIO_RAND_DIST_RANDOM    = 0,
        FIO_RAND_DIST_ZIPF,
        FIO_RAND_DIST_PARETO,
+       FIO_RAND_DIST_GAUSS,
 };
 
+#define FIO_DEF_ZIPF           1.1
+#define FIO_DEF_PARETO         0.2
+
 enum {
        FIO_RAND_GEN_TAUSWORTHE = 0,
        FIO_RAND_GEN_LFSR,
+       FIO_RAND_GEN_TAUSWORTHE64,
 };
 
 enum {
@@ -636,4 +694,7 @@ enum {
        FIO_CPUS_SPLIT,
 };
 
+extern void exec_trigger(const char *);
+extern void check_trigger_file(void);
+
 #endif