Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
FFI
                           MAKING CROSS ENGINE EXTENSIONS


                             Jeremy Hinegardner
          ...
COPIOUS FREE TIME
                            Fedora         Ruby
                           Packaging       Gems

       ...
I LOVE RUBY

Saturday, March 14, 2009
I LIKE C

Saturday, March 14, 2009
ANY
                 EXTENSION DEVELOPERS
                     IN THE HOUSE ?



Saturday, March 14, 2009
WHO HAS USED FFI?




Saturday, March 14, 2009
WHO HAS HEARD OF FFI?




Saturday, March 14, 2009
WHAT IS FFI?




Saturday, March 14, 2009
LIBFFI
                               http://sourceware.org/libffi/

                            “A foreign function interf...
libsomething.so




Saturday, March 14, 2009
Application
                               uses
                           libsomething_foo()




                        ...
Application
                               uses
                           libsomething_foo()



                         ...
e
                                       m
                                      i
                               Applicat...
App
                                Matz Ruby
                                Interpreter


                           rub...
App                                         App
        JRuby                                                 Rubinius
   ...
App                              App
        JRuby                                      Rubinius
        Interpreter      ...
App            App               App
        JRuby                    Matz Ruby         Rubinius
        Interpreter      ...
App                App                    App
        JRuby                       Matz Ruby               Rubinius
       ...
App                 App                    App
        JRuby                        Matz Ruby               Rubinius
     ...
 1    #ifndef __SIMPLE_METRICS_H__
             2    #define __SIMPLE_METRICS_H__
             3    #include <stdlib.h>
  ...
 1   class Metric
                            2     attr_reader :name
                            3     def initialize( na...
142     void Init_simple_metrics_ext()
            143     {
            144         VALUE cSM_Common;
            145
   ...
142     void Init_simple_metrics_ext()
            143     {
            144         VALUE cSM_Common;
            145
   ...
7   module SimpleMetrics
              8     module FFI
              9
             10       class Struct < ::FFI::Manage...
7   module SimpleMetrics
              8     module FFI
              9
             10       class Struct < ::FFI::Manage...
35    module SimpleMetrics
              36      module FFI
              37        class Metric < ::SimpleMetrics::Common...
10   class Struct < ::FFI::ManagedStruct                  6   typedef struct _simple_metrics{
 11     layout :min, :double...
21    extend ::FFI::Library
         22    ffi_lib quot;libsimple_metricsquot;
         23
         24    attach_function ...
MEANINGLESS METRICS
                                                   Traditional C
                                     ...
% ruby ~/Projects/simple_metrics/example/bench.rb 1000000
                           generating 1000000 random numbers bet...
FFI GEMS




Saturday, March 14, 2009
FFI GEMS



                            4
Saturday, March 14, 2009
FFI GEMS
                       ffi-ncurses              tidy_ffi




                                     4
             ffi...
GEMS WITH EXTENSIONS




                           Out of 4,501 gems


Saturday, March 14, 2009
GEMS WITH EXTENSIONS



                           346
                           Out of 4,501 gems


Saturday, March 14, ...
GET
                            TO
                           WORK!!



Saturday, March 14, 2009
THANKS

    • Wayne      Meissner - adding libffi to JRuby and providing the
        ffi gem for MRI.

    • Evan           ...
LINKS

        http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html
    •

        http://kenai.com/projects/rub...
QUESTIONS?




Saturday, March 14, 2009
Upcoming SlideShare
Loading in …5
×

FFI - building cross engine ruby extensions

5,749 views

Published on

Presentation given on FFI and Ruby at MoutainWest Ruby Conference in Salt Lake City on March 13, 2009.

Published in: Technology, Education
  • Be the first to comment

FFI - building cross engine ruby extensions

  1. 1. FFI MAKING CROSS ENGINE EXTENSIONS Jeremy Hinegardner jeremy@copiousfreetime.org twitter: copiousfreetime Saturday, March 14, 2009
  2. 2. COPIOUS FREE TIME Fedora Ruby Packaging Gems •beanstalkd •keybox •haproxy •rabal •libtomcrypt •launchy •libtommath •heel •nginx •htauth •ragel •amalgalite •tinyproxy •hitimes •stickler •crate Saturday, March 14, 2009
  3. 3. I LOVE RUBY Saturday, March 14, 2009
  4. 4. I LIKE C Saturday, March 14, 2009
  5. 5. ANY EXTENSION DEVELOPERS IN THE HOUSE ? Saturday, March 14, 2009
  6. 6. WHO HAS USED FFI? Saturday, March 14, 2009
  7. 7. WHO HAS HEARD OF FFI? Saturday, March 14, 2009
  8. 8. WHAT IS FFI? Saturday, March 14, 2009
  9. 9. LIBFFI http://sourceware.org/libffi/ “A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language.” Saturday, March 14, 2009
  10. 10. libsomething.so Saturday, March 14, 2009
  11. 11. Application uses libsomething_foo() libsomething.so Saturday, March 14, 2009
  12. 12. Application uses libsomething_foo() FFI libsomething.so Saturday, March 14, 2009
  13. 13. e m i Application t n uses u libsomething_foo() R FFI libsomething.so Saturday, March 14, 2009
  14. 14. App Matz Ruby Interpreter ruby-something C extension libsomething.so Saturday, March 14, 2009
  15. 15. App App JRuby Rubinius Interpreter Interpreter App Matz Ruby Interpreter ruby-something C extension libsomething.so Saturday, March 14, 2009
  16. 16. App App JRuby Rubinius Interpreter Interpreter App Matz Ruby Interpreter libsomething.so Saturday, March 14, 2009
  17. 17. App App App JRuby Matz Ruby Rubinius Interpreter Interpreter Interpreter libsomething.so Saturday, March 14, 2009
  18. 18. App App App JRuby Matz Ruby Rubinius Interpreter Interpreter Interpreter built-in libffi or ffi gem libsomething.so Saturday, March 14, 2009
  19. 19. App App App JRuby Matz Ruby Rubinius Interpreter Interpreter Interpreter something-ffi (pure ruby) built-in libffi or ffi gem libsomething.so Saturday, March 14, 2009
  20. 20.  1 #ifndef __SIMPLE_METRICS_H__  2 #define __SIMPLE_METRICS_H__  3 #include <stdlib.h>  4 #include <math.h>  5  6 typedef struct _simple_metrics{  7     double min;  8     double max;  9     double sum; 10     double sumsq; 11     long   count; 12 } simple_metrics ; 13 14 simple_metrics* simple_metrics_new(); 15 void            simple_metrics_free(   simple_metrics* sm ); 16 void            simple_metrics_update( simple_metrics* sm, double value ); 17 double          simple_metrics_mean(   simple_metrics* sm ); 18 double          simple_metrics_min(    simple_metrics* sm ); 19 double          simple_metrics_max(    simple_metrics* sm ); 20 double          simple_metrics_sum(    simple_metrics* sm ); 21 long            simple_metrics_count(  simple_metrics* sm ); 22 double          simple_metrics_stddev( simple_metrics* sm ); 23 double          simple_metrics_rate(   simple_metrics* sm ); 24 25 #endif Saturday, March 14, 2009
  21. 21.  1 class Metric  2   attr_reader :name  3   def initialize( name )  4     @name  5   end  6  7   def update( new_value) ... end  8   def count  ... end  9   def max    ... end 10   def mean   ... end 11   def min    ... end 12   def rate   ... end 13   def sum    ... end 14   def stddev ... end 15 end Saturday, March 14, 2009
  22. 22. 142 void Init_simple_metrics_ext() 143 { 144     VALUE cSM_Common; 145 146     mSM  = rb_define_module( quot;SimpleMetricsquot; ); 147     mSME = rb_define_module_under( mSM, quot;Extquot; ); 148 149     /* load the class we inherit from */ 150     rb_require(quot;simplemetrics/commonquot;); 151 152     cSM_Common = rb_const_get( mSM, rb_intern( quot;Commonquot; ) ); 153 154     cSME_Metric = rb_define_class_under( mSME, quot;Metricquot;, cSM_Common ); 155 156     rb_define_alloc_func(cSME_Metric, sm_alloc); 157     rb_define_method( cSME_Metric, quot;initializequot;, sm_initialize, 1 ); 158     rb_define_method( cSME_Metric, quot;updatequot;, sm_update, 1 ); 159     rb_define_method( cSME_Metric, quot;countquot;, sm_count, 0 ); 160     rb_define_method( cSME_Metric, quot;maxquot;, sm_max, 0 ); 161     rb_define_method( cSME_Metric, quot;minquot;, sm_min, 0 ); 162     rb_define_method( cSME_Metric, quot;meanquot;, sm_mean, 0 ); 163     rb_define_method( cSME_Metric, quot;ratequot;, sm_rate, 0 ); 164     rb_define_method( cSME_Metric, quot;sumquot;, sm_sum, 0 ); 165     rb_define_method( cSME_Metric, quot;stddevquot;, sm_stddev, 0 ); 166 167 } Saturday, March 14, 2009
  23. 23. 142 void Init_simple_metrics_ext() 143 { 144     VALUE cSM_Common; 145 146     mSM  = rb_define_module( quot;SimpleMetricsquot; ); 147     mSME = rb_define_module_under( mSM, quot;Extquot; ); 148 149     /* load the class we inherit from */ 150     rb_require(quot;simplemetrics/commonquot;); 151 152     cSM_Common = rb_const_get( mSM, rb_intern( quot;Commonquot; ) ); 153 154     cSME_Metric = rb_define_class_under( mSME, quot;Metricquot;, cSM_Common ); 155 156     rb_define_alloc_func(cSME_Metric, sm_alloc); 157     rb_define_method( cSME_Metric, quot;initializequot;, sm_initialize, 1 ); 158     rb_define_method( cSME_Metric, quot;updatequot;, sm_update, 1 ); 159     rb_define_method( cSME_Metric, quot;countquot;, sm_count, 0 ); 160     rb_define_method( cSME_Metric, quot;maxquot;, sm_max, 0 ); 161     rb_define_method( cSME_Metric, quot;minquot;, sm_min, 0 ); 162     rb_define_method( cSME_Metric, quot;meanquot;, sm_mean, 0 ); 163     rb_define_method( cSME_Metric, quot;ratequot;, sm_rate, 0 ); 164     rb_define_method( cSME_Metric, quot;sumquot;, sm_sum, 0 ); 165     rb_define_method( cSME_Metric, quot;stddevquot;, sm_stddev, 0 ); 166 167 } Saturday, March 14, 2009
  24. 24. 7 module SimpleMetrics  8   module FFI  9 10     class Struct < ::FFI::ManagedStruct 11       layout :min, :double, :max, :double, :sum, :double, 12              :sumsq, :double, :count, :long 13       def self.release( ptr ) 14         SimpleMetrics::FFI.simple_metrics_free( ptr ) 15       end 16     end 17 18     extend ::FFI::Library 19     ffi_lib quot;libsimple_metricsquot; 20 21     attach_function :simple_metrics_new,   [          ], :pointer 22     attach_function :simple_metrics_free,  [ :pointer ], :void 23     attach_function :simple_metrics_update,[ :pointer, :double  ], :void 24     attach_function :simple_metrics_min,   [ :pointer ], :double 25     attach_function :simple_metrics_max,   [ :pointer ], :double 26     attach_function :simple_metrics_mean,  [ :pointer ], :double 27     attach_function :simple_metrics_sum,   [ :pointer ], :double 28     attach_function :simple_metrics_count, [ :pointer ], :long 29     attach_function :simple_metrics_stddev,[ :pointer ], :double 30     attach_function :simple_metrics_rate,  [ :pointer ], :double 31 32   end 33 end Saturday, March 14, 2009
  25. 25. 7 module SimpleMetrics  8   module FFI  9 10     class Struct < ::FFI::ManagedStruct 11       layout :min, :double, :max, :double, :sum, :double, 12              :sumsq, :double, :count, :long 13       def self.release( ptr ) 14         SimpleMetrics::FFI.simple_metrics_free( ptr ) 15       end library function parameters return type 16     end 17 18     extend ::FFI::Library 19     ffi_lib quot;libsimple_metricsquot; 20 21     attach_function :simple_metrics_new,   [          ], :pointer 22     attach_function :simple_metrics_free,  [ :pointer ], :void 23     attach_function :simple_metrics_update,[ :pointer, :double  ], :void 24     attach_function :simple_metrics_min,   [ :pointer ], :double 25     attach_function :simple_metrics_max,   [ :pointer ], :double 26     attach_function :simple_metrics_mean,  [ :pointer ], :double 27     attach_function :simple_metrics_sum,   [ :pointer ], :double 28     attach_function :simple_metrics_count, [ :pointer ], :long 29     attach_function :simple_metrics_stddev,[ :pointer ], :double 30     attach_function :simple_metrics_rate,  [ :pointer ], :double 31 32   end 33 end Saturday, March 14, 2009
  26. 26. 35 module SimpleMetrics 36   module FFI 37     class Metric < ::SimpleMetrics::Common 38       include ::SimpleMetrics::FFI 39       def initialize( name ) 40         super 41         @impl = FFI.simple_metrics_new 42       end 43 44       def update( v ) 45         simple_metrics_update( @impl, v ) 46       end 47 48       self.keys.each do |f| 49         module_eval <<-code 50         def #{f} 51           simple_metrics_#{f}( @impl ) 52         end 53         code 54       end 55     end 56   end 57 end Saturday, March 14, 2009
  27. 27. 10 class Struct < ::FFI::ManagedStruct  6 typedef struct _simple_metrics{ 11   layout :min, :double,  7     double min; 12          :max, :double,  8     double max; 13          :sum, :double,  9     double sum; 14          :sumsq, :double, 10     double sumsq; 15          :count, :long 11     long   count; 16   def self.release( ptr ) 12 } simple_metrics ; 17     SimpleMetrics::FFI.simple_metrics_free( ptr ) 18   end 19 end Saturday, March 14, 2009
  28. 28. 21 extend ::FFI::Library 22 ffi_lib quot;libsimple_metricsquot; 23 24 attach_function :simple_metrics_new,   [          ], :pointer 25 attach_function :simple_metrics_free,  [ :pointer ], :void 26 attach_function :simple_metrics_update,[ :pointer, :double  ], :void 27 attach_function :simple_metrics_mean,  [ :pointer ], :double 28 attach_function :simple_metrics_min,   [ :pointer ], :double 29 attach_function :simple_metrics_max,   [ :pointer ], :double 30 attach_function :simple_metrics_sum,   [ :pointer ], :double 31 attach_function :simple_metrics_count, [ :pointer ], :long 32 attach_function :simple_metrics_stddev,[ :pointer ], :double 33 attach_function :simple_metrics_rate,  [ :pointer ], :double 14 simple_metrics* simple_metrics_new(); 15 void            simple_metrics_free(   simple_metrics* sm ); 16 void            simple_metrics_update( simple_metrics* sm, double value ); 17 double          simple_metrics_mean(   simple_metrics* sm ); 18 double          simple_metrics_min(    simple_metrics* sm ); 19 double          simple_metrics_max(    simple_metrics* sm ); 20 double          simple_metrics_sum(    simple_metrics* sm ); 21 long            simple_metrics_count(  simple_metrics* sm ); 22 double          simple_metrics_stddev( simple_metrics* sm ); 23 double          simple_metrics_rate(   simple_metrics* sm ); Saturday, March 14, 2009
  29. 29. MEANINGLESS METRICS Traditional C FFI Extension Jeremy’s Time 40 minutes 70 minutes 1 Million update() 1.16 sec 0.42 sec calls Will it Blend run Yes No on JRuby? Saturday, March 14, 2009
  30. 30. % ruby ~/Projects/simple_metrics/example/bench.rb 1000000 generating 1000000 random numbers between 0 and 10,000 Rehearsal ----------------------------------------------- ext 0.420000 0.000000 0.420000 ( 0.460806) ffi 1.160000 0.000000 1.160000 ( 1.171498) -------------------------------------- total: 1.580000sec user system total real ext 0.420000 0.010000 0.430000 ( 0.424809) ffi 1.160000 0.000000 1.160000 ( 1.182928) % ./bin/jruby ~/Projects/simple_metrics/example/bench.rb 1000000 generating 1000000 random numbers between 0 and 10,000 Skipping Ext Rehearsal ----------------------------------------------- ffi 0.922000 0.000000 0.922000 ( 0.922000) -------------------------------------- total: 0.922000sec user system total real ffi 0.834000 0.000000 0.834000 ( 0.834000) Saturday, March 14, 2009
  31. 31. FFI GEMS Saturday, March 14, 2009
  32. 32. FFI GEMS 4 Saturday, March 14, 2009
  33. 33. FFI GEMS ffi-ncurses tidy_ffi 4 ffi-swig-generator ffi-zlib Saturday, March 14, 2009
  34. 34. GEMS WITH EXTENSIONS Out of 4,501 gems Saturday, March 14, 2009
  35. 35. GEMS WITH EXTENSIONS 346 Out of 4,501 gems Saturday, March 14, 2009
  36. 36. GET TO WORK!! Saturday, March 14, 2009
  37. 37. THANKS • Wayne Meissner - adding libffi to JRuby and providing the ffi gem for MRI. • Evan Phoenix - using libffi in Rubinius • Authors of the examples on the Project Kenai wiki Saturday, March 14, 2009
  38. 38. LINKS http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html • http://kenai.com/projects/ruby-ffi • http://wmeissner.blogspot.com/ • http://www.igvita.com/2009/01/15/bridging-mri-jruby-rubinius-with-ffi/ • http://blog.segment7.net/articles/2008/01/15/rubinius-foreign-function- • interface Saturday, March 14, 2009
  39. 39. QUESTIONS? Saturday, March 14, 2009

×