Add support for waiting for other jobs by name
[fio.git] / fio.h
diff --git a/fio.h b/fio.h
index e74bdb3c81e3f8590db68cc0d3158bd9326b2f5b..66211e9da74d80cafc2398ddf001ed8ff0499a8c 100644 (file)
--- a/fio.h
+++ b/fio.h
 #include <inttypes.h>
 #include <assert.h>
 
-struct thread_data;
-
 #include "compiler/compiler.h"
+#include "thread_options.h"
 #include "flist.h"
 #include "fifo.h"
-#include "rbtree.h"
 #include "arch/arch.h"
 #include "os/os.h"
 #include "mutex.h"
@@ -32,13 +30,17 @@ struct thread_data;
 #include "helpers.h"
 #include "options.h"
 #include "profile.h"
-#include "time.h"
+#include "fio_time.h"
 #include "gettime.h"
 #include "lib/getopt.h"
 #include "lib/rand.h"
+#include "lib/rbtree.h"
+#include "client.h"
 #include "server.h"
 #include "stat.h"
 #include "flow.h"
+#include "io_u_queue.h"
+#include "workqueue.h"
 
 #ifdef CONFIG_SOLARISAIO
 #include <sys/asynch.h>
@@ -54,17 +56,6 @@ struct thread_data;
 #define MPOL_LOCAL MPOL_MAX
 #endif
 
-/*
- * What type of allocation to use for io buffers
- */
-enum fio_memtype {
-       MEM_MALLOC = 0, /* ordinary malloc */
-       MEM_SHM,        /* use shared memory segments */
-       MEM_SHMHUGE,    /* use shared memory segments with huge pages */
-       MEM_MMAP,       /* use anonynomous mmap */
-       MEM_MMAPHUGE,   /* memory mapped huge file */
-};
-
 /*
  * offset generator types
  */
@@ -73,250 +64,21 @@ enum {
        RW_SEQ_IDENT,
 };
 
-/*
- * What type of errors to continue on when continue_on_error is used
- */
-enum error_type_bit {
-       ERROR_TYPE_READ_BIT = 0,
-       ERROR_TYPE_WRITE_BIT = 1,
-       ERROR_TYPE_VERIFY_BIT = 2,
-       ERROR_TYPE_CNT = 3,
-};
-
-enum error_type {
-        ERROR_TYPE_NONE = 0,
-        ERROR_TYPE_READ = 1 << ERROR_TYPE_READ_BIT,
-        ERROR_TYPE_WRITE = 1 << ERROR_TYPE_WRITE_BIT,
-        ERROR_TYPE_VERIFY = 1 << ERROR_TYPE_VERIFY_BIT,
-        ERROR_TYPE_ANY = 0xffff,
-};
-
-struct bssplit {
-       unsigned int bs;
-       unsigned char perc;
-};
-
-struct thread_options {
-       int pad;
-       char *description;
-       char *name;
-       char *directory;
-       char *filename;
-       char *filename_format;
-       char *opendir;
-       char *ioengine;
-       enum td_ddir td_ddir;
-       unsigned int rw_seq;
-       unsigned int kb_base;
-       unsigned int unit_base;
-       unsigned int ddir_seq_nr;
-       long ddir_seq_add;
-       unsigned int iodepth;
-       unsigned int iodepth_low;
-       unsigned int iodepth_batch;
-       unsigned int iodepth_batch_complete;
-
-       unsigned long long size;
-       unsigned int size_percent;
-       unsigned int fill_device;
-       unsigned long long file_size_low;
-       unsigned long long file_size_high;
-       unsigned long long start_offset;
-
-       unsigned int bs[DDIR_RWDIR_CNT];
-       unsigned int ba[DDIR_RWDIR_CNT];
-       unsigned int min_bs[DDIR_RWDIR_CNT];
-       unsigned int max_bs[DDIR_RWDIR_CNT];
-       struct bssplit *bssplit[DDIR_RWDIR_CNT];
-       unsigned int bssplit_nr[DDIR_RWDIR_CNT];
-
-       int *ignore_error[ERROR_TYPE_CNT];
-       unsigned int ignore_error_nr[ERROR_TYPE_CNT];
-       unsigned int error_dump;
-
-       unsigned int nr_files;
-       unsigned int open_files;
-       enum file_lock_mode file_lock_mode;
-
-       unsigned int odirect;
-       unsigned int invalidate_cache;
-       unsigned int create_serialize;
-       unsigned int create_fsync;
-       unsigned int create_on_open;
-       unsigned int create_only;
-       unsigned int end_fsync;
-       unsigned int pre_read;
-       unsigned int sync_io;
-       unsigned int verify;
-       unsigned int do_verify;
-       unsigned int verifysort;
-       unsigned int verifysort_nr;
-       unsigned int verify_interval;
-       unsigned int verify_offset;
-       char verify_pattern[MAX_PATTERN_SIZE];
-       unsigned int verify_pattern_bytes;
-       unsigned int verify_fatal;
-       unsigned int verify_dump;
-       unsigned int verify_async;
-       unsigned long long verify_backlog;
-       unsigned int verify_batch;
-       unsigned int experimental_verify;
-       unsigned int use_thread;
-       unsigned int unlink;
-       unsigned int do_disk_util;
-       unsigned int override_sync;
-       unsigned int rand_repeatable;
-       unsigned int use_os_rand;
-       unsigned int write_lat_log;
-       unsigned int write_bw_log;
-       unsigned int write_iops_log;
-       unsigned int log_avg_msec;
-       unsigned int norandommap;
-       unsigned int softrandommap;
-       unsigned int bs_unaligned;
-       unsigned int fsync_on_close;
-
-       unsigned int random_distribution;
-       double zipf_theta;
-       double pareto_h;
-
-       unsigned int random_generator;
-
-       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 fdatasync_blocks;
-       unsigned int barrier_blocks;
-       unsigned long long start_delay;
-       unsigned long long timeout;
-       unsigned long long ramp_time;
-       unsigned int overwrite;
-       unsigned int bw_avg_time;
-       unsigned int iops_avg_time;
-       unsigned int loops;
-       unsigned long long zone_range;
-       unsigned long long zone_size;
-       unsigned long long zone_skip;
-       enum fio_memtype mem_type;
-       unsigned int mem_align;
-
-       unsigned int max_latency;
-
-       unsigned int stonewall;
-       unsigned int new_group;
-       unsigned int numjobs;
-       os_cpu_mask_t cpumask;
-       unsigned int cpumask_set;
-       os_cpu_mask_t verify_cpumask;
-       unsigned int verify_cpumask_set;
-#ifdef CONFIG_LIBNUMA
-       struct bitmask *numa_cpunodesmask;
-       unsigned int numa_cpumask_set;
-       unsigned short numa_mem_mode;
-       unsigned int numa_mem_prefer_node;
-       struct bitmask *numa_memnodesmask;
-       unsigned int numa_memmask_set;
-#endif
-       unsigned int iolog;
-       unsigned int rwmixcycle;
-       unsigned int rwmix[2];
-       unsigned int nice;
-       unsigned int file_service_type;
-       unsigned int group_reporting;
-       unsigned int fadvise_hint;
-       enum fio_fallocate_mode fallocate_mode;
-       unsigned int zero_buffers;
-       unsigned int refill_buffers;
-       unsigned int scramble_buffers;
-       unsigned int compress_percentage;
-       unsigned int compress_chunk;
-       unsigned int time_based;
-       unsigned int disable_lat;
-       unsigned int disable_clat;
-       unsigned int disable_slat;
-       unsigned int disable_bw;
-       unsigned int unified_rw_rep;
-       unsigned int gtod_reduce;
-       unsigned int gtod_cpu;
-       unsigned int gtod_offload;
-       enum fio_cs clocksource;
-       unsigned int no_stall;
-       unsigned int trim_percentage;
-       unsigned int trim_batch;
-       unsigned int trim_zero;
-       unsigned long long trim_backlog;
-       unsigned int clat_percentiles;
-       unsigned int percentile_precision;      /* digits after decimal for percentiles */
-       fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
-
-       char *read_iolog_file;
-       char *write_iolog_file;
-       char *bw_log_file;
-       char *lat_log_file;
-       char *iops_log_file;
-       char *replay_redirect;
-
-       /*
-        * Pre-run and post-run shell
-        */
-       char *exec_prerun;
-       char *exec_postrun;
-
-       unsigned int rate[DDIR_RWDIR_CNT];
-       unsigned int ratemin[DDIR_RWDIR_CNT];
-       unsigned int ratecycle;
-       unsigned int rate_iops[DDIR_RWDIR_CNT];
-       unsigned int rate_iops_min[DDIR_RWDIR_CNT];
-
-       char *ioscheduler;
-
-       /*
-        * CPU "io" cycle burner
-        */
-       unsigned int cpuload;
-       unsigned int cpucycle;
-
-       /*
-        * I/O Error handling
-        */
-       enum error_type continue_on_error;
-
-       /*
-        * Benchmark profile type
-        */
-       char *profile;
-
-       /*
-        * blkio cgroup support
-        */
-       char *cgroup;
-       unsigned int cgroup_weight;
-       unsigned int cgroup_nodelete;
-
-       unsigned int uid;
-       unsigned int gid;
-
-       int flow_id;
-       int flow;
-       int flow_watermark;
-       unsigned int flow_sleep;
-
-       unsigned long long offset_increment;
-
-       unsigned int sync_file_range;
-};
-
 enum {
-       TD_F_VER_BACKLOG        = 1,
-       TD_F_TRIM_BACKLOG       = 2,
-       TD_F_READ_IOLOG         = 4,
-       TD_F_REFILL_BUFFERS     = 8,
-       TD_F_SCRAMBLE_BUFFERS   = 16,
-       TD_F_VER_NONE           = 32,
-       TD_F_PROFILE_OPS        = 64,
+       TD_F_VER_BACKLOG        = 1U << 0,
+       TD_F_TRIM_BACKLOG       = 1U << 1,
+       TD_F_READ_IOLOG         = 1U << 2,
+       TD_F_REFILL_BUFFERS     = 1U << 3,
+       TD_F_SCRAMBLE_BUFFERS   = 1U << 4,
+       TD_F_VER_NONE           = 1U << 5,
+       TD_F_PROFILE_OPS        = 1U << 6,
+       TD_F_COMPRESS           = 1U << 7,
+       TD_F_NOIO               = 1U << 8,
+       TD_F_COMPRESS_LOG       = 1U << 9,
+       TD_F_VSTATE_SAVED       = 1U << 10,
+       TD_F_NEED_LOCK          = 1U << 11,
+       TD_F_CHILD              = 1U << 12,
+       TD_F_NO_PROGRESS        = 1U << 13,
 };
 
 enum {
@@ -328,34 +90,71 @@ enum {
        FIO_RAND_FILE_SIZE_OFF,
        FIO_RAND_TRIM_OFF,
        FIO_RAND_BUF_OFF,
+       FIO_RAND_SEQ_RAND_READ_OFF,
+       FIO_RAND_SEQ_RAND_WRITE_OFF,
+       FIO_RAND_SEQ_RAND_TRIM_OFF,
+       FIO_RAND_START_DELAY,
+       FIO_DEDUPE_OFF,
+       FIO_RAND_POISSON_OFF,
        FIO_RAND_NR_OFFS,
 };
 
+enum {
+       IO_MODE_INLINE = 0,
+       IO_MODE_OFFLOAD = 1,
+
+       RATE_PROCESS_LINEAR = 0,
+       RATE_PROCESS_POISSON = 1,
+};
+
+/*
+ * Per-thread/process specific data. Only used for the network client
+ * for now.
+ */
+struct sk_out;
+void sk_out_assign(struct sk_out *);
+void sk_out_drop(void);
+
 /*
  * This describes a single thread/process executing a fio job.
  */
 struct thread_data {
        struct thread_options o;
+       struct flist_head opt_list;
        unsigned long flags;
        void *eo;
        char verror[FIO_VERROR_SIZE];
        pthread_t thread;
-       int thread_number;
-       int groupid;
+       unsigned int thread_number;
+       unsigned int subjob_number;
+       unsigned int groupid;
        struct thread_stat ts;
 
+       int client_type;
+
        struct io_log *slat_log;
        struct io_log *clat_log;
        struct io_log *lat_log;
        struct io_log *bw_log;
        struct io_log *iops_log;
 
+       struct workqueue log_compress_wq;
+
+       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;
@@ -370,23 +169,20 @@ struct thread_data {
        unsigned int nr_normal_files;
        union {
                unsigned int next_file;
-               os_random_state_t next_file_state;
-               struct frand_state __next_file_state;
+               struct frand_state next_file_state;
        };
        int error;
        int sig;
        int done;
+       int stop_io;
        pid_t pid;
        char *orig_buffer;
        size_t orig_buffer_size;
        volatile int terminate;
        volatile int runstate;
-       unsigned int ioprio;
-       unsigned int ioprio_set;
        unsigned int last_was_sync;
        enum fio_ddir last_ddir;
 
-       char *mmapfile;
        int mmapfd;
 
        void *iolog_buf;
@@ -396,24 +192,20 @@ struct thread_data {
 
        unsigned long rand_seeds[FIO_RAND_NR_OFFS];
 
-       union {
-               os_random_state_t bsrange_state;
-               struct frand_state __bsrange_state;
-       };
-       union {
-               os_random_state_t verify_state;
-               struct frand_state __verify_state;
-       };
-       union {
-               os_random_state_t trim_state;
-               struct frand_state __trim_state;
-       };
+       struct frand_state bsrange_state;
+       struct frand_state verify_state;
+       struct frand_state trim_state;
+       struct frand_state delay_state;
 
        struct frand_state buf_state;
+       struct frand_state buf_state_prev;
+       struct frand_state dedupe_state;
 
        unsigned int verify_batch;
        unsigned int trim_batch;
 
+       struct thread_io_list *vstate;
+
        int shm_id;
 
        /*
@@ -440,9 +232,9 @@ struct thread_data {
        /*
         * List of free and busy io_u's
         */
-       struct flist_head io_u_freelist;
-       struct flist_head io_u_busylist;
-       struct flist_head io_u_requeues;
+       struct io_u_ring io_u_requeues;
+       struct io_u_queue io_u_freelist;
+       struct io_u_queue io_u_all;
        pthread_mutex_t io_u_lock;
        pthread_cond_t free_cond;
 
@@ -459,50 +251,80 @@ struct thread_data {
         * Rate state
         */
        uint64_t rate_bps[DDIR_RWDIR_CNT];
-       long rate_pending_usleep[DDIR_RWDIR_CNT];
+       unsigned long rate_next_io_time[DDIR_RWDIR_CNT];
        unsigned long rate_bytes[DDIR_RWDIR_CNT];
        unsigned long rate_blocks[DDIR_RWDIR_CNT];
+       unsigned long rate_io_issue_bytes[DDIR_RWDIR_CNT];
        struct timeval lastrate[DDIR_RWDIR_CNT];
+       int64_t last_usec;
+       struct frand_state poisson_state;
+
+       /*
+        * 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
         */
-       union {
-               os_random_state_t random_state;
-               struct frand_state __random_state;
-       };
+       struct frand_state random_state;
 
        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;
        unsigned int tv_cache_mask;
        unsigned int ramp_time_over;
 
+       /*
+        * Time since last latency_window was started
+        */
+       struct timeval latency_ts;
+       unsigned int latency_qd;
+       unsigned int latency_qd_high;
+       unsigned int latency_qd_low;
+       unsigned int latency_failed;
+       uint64_t latency_ios;
+       int latency_end_run;
+
        /*
         * read/write mixed workload state
         */
-       union {
-               os_random_state_t rwmix_state;
-               struct frand_state __rwmix_state;
-       };
+       struct frand_state rwmix_state;
        unsigned long rwmix_issues;
        enum fio_ddir rwmix_ddir;
        unsigned int ddir_seq_nr;
 
+       /*
+        * rand/seq mixed workload state
+        */
+       struct frand_state seq_rand_state[DDIR_RWDIR_CNT];
+
        /*
         * IO history logs for verification. We use a tree for sorting,
         * if we are overwriting. Otherwise just use a fifo.
@@ -536,10 +358,7 @@ struct thread_data {
        /*
         * For generating file sizes
         */
-       union {
-               os_random_state_t file_size_state;
-               struct frand_state __file_size_state;
-       };
+       struct frand_state file_size_state;
 
        /*
         * Error counts
@@ -554,6 +373,8 @@ struct thread_data {
         */
        struct prof_io_ops prof_io_ops;
        void *prof_data;
+
+       void *pinned_mem;
 };
 
 /*
@@ -567,21 +388,32 @@ enum {
 
 #define __td_verror(td, err, msg, func)                                        \
        do {                                                            \
+               unsigned int ____e = (err);                             \
                if ((td)->error)                                        \
                        break;                                          \
-               int e = (err);                                          \
-               (td)->error = e;                                        \
+               (td)->error = ____e;                                    \
                if (!(td)->first_error)                                 \
                        snprintf(td->verror, sizeof(td->verror), "file:%s:%d, func=%s, error=%s", __FILE__, __LINE__, (func), (msg));           \
        } 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)
@@ -589,12 +421,11 @@ enum {
 extern int exitall_on_terminate;
 extern unsigned int thread_number;
 extern unsigned int stat_number;
-extern unsigned int nr_process, nr_thread;
 extern int shm_id;
 extern int groupid;
 extern int output_format;
+extern int append_terse_output;
 extern int temp_stall_ts;
-extern unsigned long long mlock_size;
 extern uintptr_t page_mask, page_size;
 extern int read_only;
 extern int eta_print;
@@ -610,52 +441,25 @@ extern int terse_version;
 extern int is_backend;
 extern int nr_clients;
 extern int log_syslog;
+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 char *aux_path;
 
 extern struct thread_data *threads;
 
-static inline void fio_ro_check(struct thread_data *td, struct io_u *io_u)
+static inline void fio_ro_check(const struct thread_data *td, struct io_u *io_u)
 {
        assert(!(io_u->ddir == DDIR_WRITE && !td_write(td)));
 }
 
 #define REAL_MAX_JOBS          2048
 
-static inline enum error_type_bit td_error_type(enum fio_ddir ddir, int err)
-{
-       if (err == EILSEQ)
-               return ERROR_TYPE_VERIFY_BIT;
-       if (ddir == DDIR_READ)
-               return ERROR_TYPE_READ_BIT;
-       return ERROR_TYPE_WRITE_BIT;
-}
-
-static int __NON_FATAL_ERR[] = {EIO, EILSEQ};
-static inline int td_non_fatal_error(struct thread_data *td,
-                                    enum error_type_bit etype, int err)
-{
-       int i;
-       if (!td->o.ignore_error[etype]) {
-               td->o.ignore_error[etype] = __NON_FATAL_ERR;
-               td->o.ignore_error_nr[etype] = sizeof(__NON_FATAL_ERR)
-                       / sizeof(int);
-       }
-
-       if (!(td->o.continue_on_error & (1 << etype)))
-               return 0;
-       for (i = 0; i < td->o.ignore_error_nr[etype]; i++)
-               if (td->o.ignore_error[etype][i] == err)
-                       return 1;
-       return 0;
-}
-
-static inline void update_error_count(struct thread_data *td, int err)
-{
-       td->total_err_count++;
-       if (td->total_err_count == 1)
-               td->first_error = err;
-}
-
 static inline int should_fsync(struct thread_data *td)
 {
        if (td->last_was_sync)
@@ -669,14 +473,16 @@ static inline int should_fsync(struct thread_data *td)
 /*
  * Init/option functions
  */
+extern int __must_check fio_init_options(void);
 extern int __must_check parse_options(int, char **);
-extern int parse_jobs_ini(char *, int, int);
-extern int parse_cmd_line(int, char **);
-extern int fio_backend(void);
+extern int parse_jobs_ini(char *, int, int, int);
+extern int parse_cmd_line(int, char **, int);
+extern int fio_backend(struct sk_out *);
 extern void reset_fio_state(void);
-extern void clear_io_state(struct thread_data *);
+extern void clear_io_state(struct thread_data *, int);
 extern int fio_options_parse(struct thread_data *, char **, 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 *);
@@ -686,9 +492,19 @@ extern void fio_options_dup_and_init(struct option *);
 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 **);
-extern char *num2str(unsigned long, int, int, int, int);
+extern void add_job_opts(const char **, 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);
+extern int fio_set_fd_nonblocking(int, const char *);
+extern void sig_show_status(int sig);
+extern struct thread_data *get_global_options(void);
+
+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
@@ -699,6 +515,7 @@ extern int ioengine_load(struct thread_data *);
  */
 extern void print_thread_status(void);
 extern void print_status_init(int);
+extern char *fio_uint_to_kmg(unsigned int val);
 
 /*
  * Thread life cycle. Once a thread has a runstate beyond TD_INITIALIZED, it
@@ -716,21 +533,35 @@ enum {
        TD_PRE_READING,
        TD_VERIFYING,
        TD_FSYNCING,
+       TD_FINISHING,
        TD_EXITED,
        TD_REAPED,
+       TD_LAST,
 };
 
 extern void td_set_runstate(struct thread_data *, int);
-#define TERMINATE_ALL          (-1)
-extern void fio_terminate_threads(int);
+extern int td_bump_runstate(struct thread_data *, int);
+extern void td_restore_runstate(struct thread_data *, int);
+extern const char *runstate_to_name(int runstate);
+
+/*
+ * Allow 60 seconds for a job to quit on its own, otherwise reap with
+ * a vengeance.
+ */
+#define FIO_REAP_TIMEOUT       60
+
+#define TERMINATE_ALL          (-1U)
+extern void fio_terminate_threads(unsigned int);
+extern void fio_mark_td_terminate(struct thread_data *);
 
 /*
  * Memory helpers
  */
-extern int __must_check fio_pin_memory(void);
-extern void fio_unpin_memory(void);
+extern int __must_check fio_pin_memory(struct thread_data *);
+extern void fio_unpin_memory(struct thread_data *);
 extern int __must_check allocate_io_mem(struct thread_data *);
 extern void free_io_mem(struct thread_data *);
+extern void free_threads_shm(void);
 
 /*
  * Reset stats after ramp time completes
@@ -741,16 +572,20 @@ extern void reset_all_stats(struct thread_data *);
  * blktrace support
  */
 #ifdef FIO_HAVE_BLKTRACE
-extern int is_blktrace(const char *);
-extern int load_blktrace(struct thread_data *, const char *);
+extern int is_blktrace(const char *, int *);
+extern int load_blktrace(struct thread_data *, const char *, int);
 #endif
 
+extern int io_queue_event(struct thread_data *td, struct io_u *io_u, int *ret,
+                  enum fio_ddir ddir, uint64_t *bytes_issued, int from_verify,
+                  struct timeval *comp_time);
+
 /*
- * Mark unused variables passed to ops functions as unused, to silence gcc
+ * Latency target helpers
  */
-#define fio_unused     __attribute((__unused__))
-#define fio_init       __attribute__((constructor))
-#define fio_exit       __attribute__((destructor))
+extern void lat_target_check(struct thread_data *);
+extern void lat_target_init(struct thread_data *);
+extern void lat_target_reset(struct thread_data *);
 
 #define for_each_td(td, i)     \
        for ((i) = 0, (td) = &threads[0]; (i) < (int) thread_number; (i)++, (td)++)
@@ -794,16 +629,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;
@@ -817,9 +651,17 @@ static inline unsigned int td_max_bs(struct thread_data *td)
        return max(td->o.max_bs[DDIR_TRIM], max_bs);
 }
 
-static inline int is_power_of_2(unsigned int val)
+static inline unsigned int td_min_bs(struct thread_data *td)
+{
+       unsigned int min_bs;
+
+       min_bs = min(td->o.min_bs[DDIR_READ], td->o.min_bs[DDIR_WRITE]);
+       return min(td->o.min_bs[DDIR_TRIM], min_bs);
+}
+
+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;
 }
 
 /*
@@ -828,40 +670,65 @@ static inline int is_power_of_2(unsigned int 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);
 }
 
 extern const char *fio_get_arch_string(int);
 extern const char *fio_get_os_string(int);
 
+#ifdef FIO_INTERNAL
+#define ARRAY_SIZE(x)    (sizeof((x)) / (sizeof((x)[0])))
+#define FIELD_SIZE(s, f) (sizeof(((typeof(s))0)->f))
+#endif
+
 enum {
-       FIO_OUTPUT_TERSE        = 0,
-       FIO_OUTPUT_JSON,
-       FIO_OUTPUT_NORMAL,
+       __FIO_OUTPUT_TERSE      = 0,
+       __FIO_OUTPUT_JSON       = 1,
+       __FIO_OUTPUT_NORMAL     = 2,
+        __FIO_OUTPUT_JSON_PLUS  = 3,
+       FIO_OUTPUT_NR           = 4,
+
+       FIO_OUTPUT_TERSE        = 1U << __FIO_OUTPUT_TERSE,
+       FIO_OUTPUT_JSON         = 1U << __FIO_OUTPUT_JSON,
+       FIO_OUTPUT_NORMAL       = 1U << __FIO_OUTPUT_NORMAL,
+       FIO_OUTPUT_JSON_PLUS    = 1U << __FIO_OUTPUT_JSON_PLUS,
 };
 
 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 {
+       FIO_CPUS_SHARED         = 0,
+       FIO_CPUS_SPLIT,
+};
+
+extern void exec_trigger(const char *);
+extern void check_trigger_file(void);
+
 #endif