[PATCH] Separate io engines into separate loadable objects
[fio.git] / fio.h
diff --git a/fio.h b/fio.h
index cc30a15ea189b2bad02a2c64ce5a5af5a3dd85ca..64f3b2d1ae0f96a6ead8eb7fb0855b6e6e125483 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -124,13 +124,10 @@ enum fio_filetype {
        FIO_TYPE_CHAR,
 };
 
-enum fio_iotype {
+enum fio_ioengine_flags {
        FIO_SYNCIO      = 1 << 0,
-       FIO_MMAPIO      = 1 << 1 | FIO_SYNCIO,
-       FIO_LIBAIO      = 1 << 2,
-       FIO_POSIXAIO    = 1 << 3,
-       FIO_SGIO        = 1 << 4,
-       FIO_SPLICEIO    = 1 << 5 | FIO_SYNCIO,
+       FIO_CPUIO       = 1 << 1,
+       FIO_MMAPIO      = 1 << 2,
 };
 
 /*
@@ -178,7 +175,6 @@ struct thread_data {
        unsigned int fsync_blocks;
        unsigned int start_delay;
        unsigned long timeout;
-       enum fio_iotype io_engine;
        unsigned int overwrite;
        unsigned int bw_avg_time;
        unsigned int loops;
@@ -215,15 +211,7 @@ struct thread_data {
         * IO engine hooks, contains everything needed to submit an io_u
         * to any of the available IO engines.
         */
-       void *io_data;
-       char io_engine_name[16];
-       int (*io_prep)(struct thread_data *, struct io_u *);
-       int (*io_queue)(struct thread_data *, struct io_u *);
-       int (*io_getevents)(struct thread_data *, int, int, struct timespec *);
-       struct io_u *(*io_event)(struct thread_data *, int);
-       int (*io_cancel)(struct thread_data *, struct io_u *);
-       void (*io_cleanup)(struct thread_data *);
-       int (*io_sync)(struct thread_data *);
+       struct ioengine_ops *io_ops;
 
        /*
         * Current IO depth and list of free and busy io_u's.
@@ -261,6 +249,12 @@ struct thread_data {
        unsigned long *file_map;
        unsigned int num_maps;
 
+       /*
+        * CPU "io" cycle burner
+        */
+       unsigned int cpuload;
+       unsigned int cpucycle;
+
        /*
         * bandwidth and latency stats
         */
@@ -307,13 +301,17 @@ struct thread_data {
        struct list_head io_log_list;
 };
 
-#define td_verror(td, err)                                             \
+#define __td_verror(td, err, msg)                                      \
        do {                                                            \
                int e = (err);                                          \
                (td)->error = e;                                        \
-               snprintf(td->verror, sizeof(td->verror) - 1, "file:%s:%d, error=%s", __FILE__, __LINE__, strerror(e));  \
+               snprintf(td->verror, sizeof(td->verror) - 1, "file:%s:%d, error=%s", __FILE__, __LINE__, (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))
+
 extern struct io_u *__get_io_u(struct thread_data *);
 extern void put_io_u(struct thread_data *, struct io_u *);
 
@@ -409,6 +407,7 @@ extern unsigned long utime_since(struct timeval *, struct timeval *);
 extern unsigned long mtime_since(struct timeval *, struct timeval *);
 extern unsigned long mtime_since_now(struct timeval *);
 extern unsigned long time_since_now(struct timeval *);
+extern void __usec_sleep(unsigned int);
 extern void usec_sleep(struct thread_data *, unsigned long);
 extern void rate_throttle(struct thread_data *, unsigned long, unsigned int);
 
@@ -424,12 +423,12 @@ extern int init_random_state(struct thread_data *);
  * Naturally this would not work for any type of contended semaphore or
  * for real locking.
  */
-static inline void fio_sem_init(volatile int volatile *sem, int val)
+static inline void fio_sem_init(volatile int *sem, int val)
 {
        *sem = val;
 }
 
-static inline void fio_sem_down(volatile int volatile *sem)
+static inline void fio_sem_down(volatile int *sem)
 {
        while (*sem == 0)
                usleep(10000);
@@ -437,7 +436,7 @@ static inline void fio_sem_down(volatile int volatile *sem)
        (*sem)--;
 }
 
-static inline void fio_sem_up(volatile int volatile *sem)
+static inline void fio_sem_up(volatile int *sem)
 {
        (*sem)++;
 }
@@ -451,4 +450,30 @@ static inline void fio_sem_up(volatile int volatile *sem)
                fprintf(stderr, ##args);        \
        } while (0)
 
+struct ioengine_ops {
+       char name[16];
+       int version;
+       int flags;
+       int (*init)(struct thread_data *);
+       int (*prep)(struct thread_data *, struct io_u *);
+       int (*queue)(struct thread_data *, struct io_u *);
+       int (*getevents)(struct thread_data *, int, int, struct timespec *);
+       struct io_u *(*event)(struct thread_data *, int);
+       int (*cancel)(struct thread_data *, struct io_u *);
+       void (*cleanup)(struct thread_data *);
+       int (*sync)(struct thread_data *);
+       void *data;
+       void *dlhandle;
+};
+
+#define FIO_IOOPS_VERSION      1
+
+extern struct ioengine_ops *load_ioengine(struct thread_data *, char *);
+extern void close_ioengine(struct thread_data *);
+
+/*
+ * Mark unused variables passed to ops functions as unused, to silence gcc
+ */
+#define fio_unused     __attribute((__unused__))
+
 #endif