On 2014-02-12 12:13, Daniel Gollub wrote:
This makes life easier for plugins written in C++
since they do not need to deal with struct initilization issues
with the ioengine_ops symbol.

With g++ a non-static ioengine_ops in global scope like this:

struct ioengine_ops ioengine = {
         .name           = "null",
         .version        = FIO_IOOPS_VERSION,
         .queue          = fio_null_queue,
         .commit         = fio_null_commit,
};

Results in:

cpp_null2.cc: At global scope:
cpp_null2.cc:112:1: error: C99 designator ‘name’ outside aggregate initializer
cpp_null2.cc:112:1: sorry, unimplemented: non-trivial designated initializers 
not supported
cpp_null2.cc:112:1: sorry, unimplemented: non-trivial designated initializers 
not supported
cpp_null2.cc:112:1: sorry, unimplemented: non-trivial designated initializers 
not supported
cpp_null2.cc:112:1: sorry, unimplemented: non-trivial designated initializers 
not supported
$

Example get_iongine() symbol usage:

---8<---
extern "C" {
void get_ioengine(struct ioengine_ops **ioengine_ptr) {
         struct ioengine_ops *ioengine;
         *ioengine_ptr = (struct ioengine_ops *) malloc(sizeof(struct 
ioengine_ops));
         ioengine = *ioengine_ptr;

         strcpy(ioengine->name, "cpp_null");
         ioengine->version        = FIO_IOOPS_VERSION;
         ioengine->queue          = fio_null_queue;
         ioengine->commit         = fio_null_commit;
         ioengine->getevents      = fio_null_getevents;
         ioengine->event          = fio_null_event;
         ioengine->init           = fio_null_init;
         ioengine->cleanup        = fio_null_cleanup;
         ioengine->open_file      = fio_null_open;
         ioengine->flags          = FIO_DISKLESSIO;
}
}
--->8---

Signed-off-by: Daniel Gollub <[email protected]>
---
  ioengines.c |   14 ++++++++++++++
  1 file changed, 14 insertions(+)

diff --git a/ioengines.c b/ioengines.c
index d71e372..c080da3 100644
--- a/ioengines.c
+++ b/ioengines.c
@@ -90,6 +90,7 @@ static struct ioengine_ops *dlopen_ioengine(struct 
thread_data *td,
  {
        struct ioengine_ops *ops;
        void *dlhandle;
+       typedef void (*get_ioengine_t)(struct ioengine_ops **);

        dprint(FD_IO, "dload engine %s\n", engine_lib);

@@ -107,6 +108,19 @@ static struct ioengine_ops *dlopen_ioengine(struct 
thread_data *td,
        ops = dlsym(dlhandle, engine_lib);
        if (!ops)
                ops = dlsym(dlhandle, "ioengine");
+
+       /*
+        * For some external engines (like C++ ones) it is not that trivial
+        * to provide a non-static ionengine structure that we can reference.
+        * Instead we call a method which allocates the required ioengine
+        * structure.
+        */
+       if (!ops) {
+               get_ioengine_t get_ioengine = dlsym(dlhandle, "get_ioengine");
+               if (get_ioengine)
+                       get_ioengine(&ops);
+       }
+
        if (!ops) {
                td_vmsg(td, -1, dlerror(), "dlsym");
                dlclose(dlhandle);


This looks fine, but lets put that typedef in ioengine.h instead.

--
Jens Axboe

--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to