Description

The idea is to use "idle time" when process is otherwise sleeping

and using no CPU time to perform GC. It makes sense because real

world traffic sees idle time due to network latency and waiting

for user input.

Right now, it's Linux-only. Future patches will affect other sleeping

functions:

IO.select, Kernel#sleep, Thread#join, Process.waitpid, etc...

I don't know if this patch can be implemented for win32, right

now it's just dummy functions and that will be somebody elses

job. But all pthreads platforms should eventually benefit.

Before this patch, the entropy-dependent script below takes 95MB

consistently on my system. Now, depending on the amount of

entropy on my system, it takes anywhere from 43MB to 75MB.

I'm using /dev/urandom to simulate real-world network latency

variations. There is no improvement when using /dev/zero

because the process is never idle.

require 'net/http'

require 'digest/md5'

Thread.abort_on_exception = true

s = TCPServer.new('127.0.0.1', 0)

len = 1024 * 1024 * 1024

th = Thread.new do

c = s.accept

c.readpartial(16384)

c.write("HTTP/1.0 200 OK\r

Content-Length: #{len}\r

\r

")

IO.copy_stream('/dev/urandom', c, len)

c.close

end

addr = s.addr

Net::HTTP.start(addr[3], addr[1]) do |http|

http.request_get('/') do |res|

dig = Digest::MD5.new

res.read_body { |buf|

dig.update(buf)

}

puts dig.hexdigest

end

end

The above script is also dependent on net/protocol using

read_nonblock. Ordinary IO objects will need IO#nonblock=true

to see benefits (because they never hit rb_wait_for_single_fd)

gc.c (rb_gc_inprogress): new function (rb_gc_step): ditto

internal.h: declare prototypes for new gc.c functions

thread_pthread.c (gvl_contended_p): new function

thread_win32.c (gvl_contended_p): ditto (dummy)

thread.c (rb_wait_for_single_fd w/ ppoll): use new functions to perform GC while GVL is uncontended and GC is lazy sweeping or incremental marking [ruby-core:86265] ```

2 part patch broken out

https://80x24.org/spew/20180429035007.6499-2-e@80x24.org/raw

https://80x24.org/spew/20180429035007.6499-3-e@80x24.org/raw

Also on my "sleepy-gc" git branch @ git://80x24.org/ruby.git