Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Last active February 25, 2019 19:03
Show Gist options
  • Save tenderlove/5733632 to your computer and use it in GitHub Desktop.
Save tenderlove/5733632 to your computer and use it in GitHub Desktop.
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(:unlocked) 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.unlocked { fib(34) }
@luikore
Copy link

luikore commented Jun 8, 2013

Found this in intern.h :

/* Use rb_thread_call_without_gvl family instead. */

btw, should that be parallely instead of concurrently?

@DAddYE
Copy link

DAddYE commented Jun 9, 2013

@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.

@ko1
Copy link

ko1 commented Jun 11, 2014

Now, rb_thread_blocking_region is obsolete.

@hone
Copy link

hone commented Nov 19, 2014

it's replaced with rb_thread_call_without_gvl according to @nobu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment