Hello! This page collects the code examples and perfetto visualization links for my Understanding the Ruby Global VM Lock by observing it RubyKaigi 2023 talk.

If this interests you, I suggest looking at my two other blog posts on the subject:

Observing the GVL #1


Click Open Example 1 to explore this example. Alternatively, download rk-example1.json.gz and open it with the Perfetto UI. Example code is from rk-example1.rb:

require 'gvl-tracing'

GvlTracing.start("rk-example1.json")

def counter_loop
  counter = 0
  counter += 1 while counter < 1_000_000_000
end

t2 = Thread.new { counter_loop }
counter_loop
t2.join

GvlTracing.stop

Observing the GVL #2


Click Open Example 2 to explore this example. Alternatively, download rk-example2.json.gz and open it with the Perfetto UI. Example code is from rk-example2.rb:

require 'gvl-tracing'

GvlTracing.start("rk-example2.json")

def counter_loop
  counter = 0
  counter += 1 while counter < 1_000_000_000
end

threads = 9.times.map { Thread.new { counter_loop } }
counter_loop
threads.map(&:join)

GvlTracing.stop

Observing the GVL #3


Click Open Example 3 to explore this example. Alternatively, download rk-example3.json.gz and open it with the Perfetto UI. Example code is from rk-example3.rb:

require 'gvl-tracing'

GvlTracing.start("rk-example3.json")

def counter_loop
  counter = 0
  counter += 1 while counter < 1_000_000_000
end

Thread.new { counter_loop; sleep }
3.times { counter_loop }

GvlTracing.stop

Observing the GVL #4


Click Open Example 4 to explore this example. Alternatively, download rk-example4.json.gz and open it with the Perfetto UI. Example code is from rk-example4.rb:

require 'gvl-tracing'
require 'net/http'

GvlTracing.start("rk-example4.json")

20.times do
  Net::HTTP.start('www.google.com', open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) { |it| it.get('/') }
end

GvlTracing.stop

Observing the GVL #5


Click Open Example 5 to explore this example. Alternatively, download rk-example5.json.gz and open it with the Perfetto UI. Example code is from rk-example5.rb:

require 'gvl-tracing'
require 'net/http'
require 'benchmark/ips'

GvlTracing.start("rk-example5.json")

def perform_request = \
  Net::HTTP.start('www.google.com', open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) do |http|
    http.get('/')
  end

Benchmark.ips do |x|
  x.config(time: 1, warmup: 0)
  x.report("request") { perform_request }
end

GvlTracing.stop

Observing the GVL #6


Click Open Example 6 to explore this example. Alternatively, download rk-example6.json.gz and open it with the Perfetto UI. Example code is from rk-example6.rb:

require 'gvl-tracing'
require 'net/http'
require 'benchmark/ips'

GvlTracing.start("rk-example6.json")

def counter_loop
  counter = 0
  counter += 1 while counter < 1_000_000_000
end

Thread.new { counter_loop }

def perform_request = \
  Net::HTTP.start('www.google.com', open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) do |http|
    http.get('/')
  end

Benchmark.ips do |x|
  x.config(time: 1, warmup: 0)
  x.report("request") { perform_request }
end

GvlTracing.stop

Observing the GVL #7


Click Open Example 7 to explore this example. Alternatively, download rk-example7.json.gz and open it with the Perfetto UI. Example code is from rk-example7.rb:

require 'gvl-tracing'
require 'net/http'
require 'benchmark/ips'

GvlTracing.start("rk-example7.json")

def counter_loop
  counter = 0
  counter += 1 while counter < 1_000_000_000
end

Ractor.new { counter_loop }

def perform_request = \
  Net::HTTP.start('www.google.com', open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) do |http|
    http.get('/')
  end

Benchmark.ips do |x|
  x.config(time: 1, warmup: 0)
  x.report("request") { perform_request }
end

GvlTracing.stop

Click Open Example 7-2 to explore this example. Alternatively, download rk-example7-2.json.gz and open it with the Perfetto UI. Example code is from rk-example7-2.rb:

require 'gvl-tracing'

GvlTracing.start("rk-example7-2.json")

def counter_loop
  counter = 0
  counter += 1 while counter < 1_000_000_000
end

ractors = 9.times.map { Ractor.new { counter_loop } }
counter_loop
ractors.map(&:take)

GvlTracing.stop