Ruby 1.9 Threading Support

Hi,

Are there any plans to pepper the codebase with rb_blocking_region
calls? If so, is there a preferred way to approach it?

I’ve attached a sample patch for Gdk::Pixbuf.new that allows loading
from disk to play nicely with threads, but it’s rather ugly. On the
plus side, it makes a script like the following take about ~1s instead
of >4.5s when run on my 6 core AMD with an 8Mb JPEG.

—8<—
require ‘glib2’
$:.unshift ‘./gdk_pixbuf2/ext/gdk_pixbuf2/’
require ‘gdk_pixbuf2.so’

require ‘thread’

threads = []
pixbufs = []

m = Mutex.new
Thread.new { loop { GC.start; Thread.sleep(0.01) } }
12.times do
threads << Thread.new {
pb = Gdk::Pixbuf.new(ARGV[0])
m.synchronize { pixbufs << pb }
}
end
threads.each(&:join)
p pixbufs
—8<—

So - any thoughts on whether the best way to implement Ruby 1.9 thread
support for those sections of ruby-gnome2 which are usefully
threadable?

TTFN,

G

On Tue, Oct 4, 2011 at 19:33, Geoff Y. [email protected] wrote:

Are there any plans to pepper the codebase with rb_blocking_region
calls? If so, is there a preferred way to approach it?

I’ve attached a sample patch for Gdk::Pixbuf.new that allows loading
from disk to play nicely with threads, but it’s rather ugly. On the
plus side, it makes a script like the following take about ~1s instead
of >4.5s when run on my 6 core AMD with an 8Mb JPEG.

Oh, my. I think that the current source has to be reviewed thoroughly
before we add something as complicated as this.

On 4 October 2011 22:11, Nikolai W. [email protected] wrote:

On Tue, Oct 4, 2011 at 19:33, Geoff Y. [email protected] wrote:

Are there any plans to pepper the codebase with rb_blocking_region
calls? If so, is there a preferred way to approach it?

Oh, my. I think that the current source has to be reviewed thoroughly
before we add something as complicated as this.

I did choose one of the most complicated examples - I don’t think
there are many methods that have quite so many C functions to map
onto, or fallback options for old versions of GTK, or that call
rb_gc() and retry the call if it fails :slight_smile:

The scope of the changes would be limited - for most functions I don’t
think there’d be much benefit. The main areas I hit and wish could be
handled in background threads are pixbuf loading, saving, scaling and
a few librsvg functions. And there are probably a few places in
poppler.

As I understand it, these functions are prime candidates because they
can take a noticeable period of time to complete and they don’t
interact with Ruby C API, so it should be quite safe to release the
GVL while they’re called.

So, any thoughts on any of the following?

1 - Are there any existing plans for better integration with the Ruby
1.9 threading model that I’ve missed? Is there something specific
that we’re waiting for here?

2 - Would it be better to have a struct type & separate function for
each wrapped function rather than (as in the previously attached
patch) a single function and an enum/union structure?

3 - Are there any thoughts on guidelines for naming of types and
functions for use with rb_thread_blocking_region?

Thanks,

G.

Random Musing - http://www.frafferz.com/
Geek Blog - http://geoffyoungs.github.com/

On Wed, Oct 5, 2011 at 12:26, Geoff Y. [email protected] wrote:

there are many methods that have quite so many C functions to map
onto, or fallback options for old versions of GTK, or that call
rb_gc() and retry the call if it fails :slight_smile:

OK. I’d still claim that cleaning up before updating to 3.0 would be
a good thing to do before we get to optimizing for Ruby 1.9, but this
does sound like something that we should definitely look into. I’m
sorry I don’t have any more input, as I didn’t even know that this
functionality existed.