public
Created

  • Download Gist
gvl_release.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
require 'fiddle'
 
class GVL
handle = Fiddle::Handle::DEFAULT
address = handle['rb_thread_blocking_region']
func = Fiddle::Function.new address, [Fiddle::TYPE_VOIDP,
Fiddle::TYPE_VOIDP,
Fiddle::TYPE_VOIDP,
Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOIDP
 
define_method(:concurrently) do |&block|
closure = Class.new(Fiddle::Closure) {
define_method(:call) { |ptr|
Fiddle.dlwrap block.call
}
}.new(Fiddle::TYPE_VOIDP, [Fiddle::TYPE_VOIDP])
 
func.call(closure, nil, nil, nil).to_value
end
end
 
def fib n
if n < 3
1
else
fib(n-1) + fib(n-2)
end
end
 
gvl = GVL.new
p gvl.concurrently { fib(34) }

Found this in intern.h :

/* Use rb_thread_call_without_gvl family instead. */

btw, should that be parallely instead of concurrently?

@luikore, rb_thread_blocking_region calls rb_thread_call_without_gvl but with some extra args (one i.e. is a signal in case Ruby needs to kill the thread) and returns a VALUE.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.