|
# test_thread_sched.rb
|
|
#
|
|
# use this file for analyze gil/gvl em linux environment
|
|
# time should be as near as possible to 20 seconds
|
|
# ruby with 100% cpu usage time problems with input/output
|
|
#
|
|
# use --postgres to analyze input/output problem with 100% cpu usage
|
|
# use --taskset to force use one processor
|
|
#
|
|
# Written & maintained by Alexandre Riveira <alexandre@objectdata.com.br>.
|
|
# This program is free software. You can re-distribute and/or
|
|
# modify this program under the same terms as Ruby itself,
|
|
# Ruby Distribute License.
|
|
|
|
if ARGV.include? '--help'
|
|
puts "usage: ruby test_thread_sched.rb --postgres --taskset"
|
|
exit
|
|
end
|
|
|
|
#postgres
|
|
postgres = ARGV.include? '--postgres'
|
|
require 'pg' if postgres
|
|
|
|
# taskset to analyze linux environment for 1 processor
|
|
taskset = ARGV.include? '--taskset'
|
|
system("taskset -c -p 2 #{Process.pid}") if taskset
|
|
|
|
# general time
|
|
time_start = Time.now
|
|
|
|
# align for best view
|
|
align = 15
|
|
|
|
# first test 10 seconds for one thread
|
|
puts "first test..."
|
|
t1 = Thread.new do
|
|
Thread.current[:target] = 0
|
|
loop do
|
|
Thread.current[:target] += 1
|
|
end
|
|
end
|
|
|
|
# print time for sleep with one thread using 100% cpu
|
|
10.times do
|
|
time_local = Time.now
|
|
sleep(1)
|
|
puts "first".ljust(align, '.') + ": #{t1[:target]}"
|
|
puts "time".ljust(15, '.') + ": #{Time.now - time_local} secs\n\n"
|
|
end
|
|
|
|
puts "\n" * 3
|
|
|
|
# second test 10 seconds for three threads
|
|
puts "second test..."
|
|
t1[:target] = 0
|
|
|
|
t2 = Thread.new do
|
|
Thread.current[:target] = 0
|
|
loop do
|
|
Thread.current[:target] += 1
|
|
end
|
|
end
|
|
|
|
t3 = Thread.new do
|
|
Thread.current[:target] = 0
|
|
if postgres
|
|
conn = PGconn.open(:dbname => 'postgres', :user => 'postgres', :host => 'localhost')
|
|
loop do
|
|
conn.exec("SELECT * FROM pg_stat_activity")
|
|
Thread.current[:target] += 1
|
|
end
|
|
else
|
|
loop do
|
|
Thread.current[:target] += 1
|
|
end
|
|
end
|
|
end
|
|
|
|
label = postgres ? 'postgres' : 'three'
|
|
10.times do
|
|
time_local = Time.now
|
|
sleep(1)
|
|
puts "first".ljust(align, '.') + ": #{t1[:target]}"
|
|
puts "second".ljust(align, '.') + ": #{t2[:target]}"
|
|
puts label.ljust(align, '.') + ": #{t3[:target]}"
|
|
puts "time".ljust(15, '.') + ": #{Time.now - time_local} secs\n\n"
|
|
end
|
|
|
|
# resume
|
|
time = Time.now - time_start
|
|
total = t1[:target] + t2[:target] + t3[:target]
|
|
|
|
# processor
|
|
lines = File.readlines("/proc/cpuinfo")
|
|
model = lines.detect{|line| line.start_with? 'model name'}.split(':').last
|
|
number = lines.count{|line| line.start_with? 'processor'}
|
|
puts "processor".ljust(align, '.') + ": #{model} with (#{number} processores)".gsub(/\s+/, ' ')
|
|
puts "taskset".ljust(align, '.') + ": #{taskset}"
|
|
|
|
# ruby version
|
|
puts "ruby version".ljust(align, '.') + ": #{RUBY_VERSION}-#{RUBY_ENGINE}"
|
|
|
|
# total
|
|
puts "total".ljust(align, '.') + ": #{total}"
|
|
puts "postgres".ljust(align, '.') + ": #{t3[:target]}" if postgres
|
|
puts "time".ljust(align, '.') + ": #{time} (ideal value of 20 seconds)"
|