On Jan 13, 2009, at 8:19 PM, Brent Roman wrote:

>
> Evan,
>
> Have you thought about the impact on this patch on multi- 
> (green)threaded
> Ruby scripts that "run small, fast programs as children, in true unix
> fashion"?
>
> Won't all the other threads pause during your new "QUICKSLEEP"  
> polling loop?

Yes, they will. But thats why it's only a 5ms window. Ruby's threading  
is decent, but my hunch is that an extra 5ms window here won't even be  
noticed.

Again, it was a bit of a quick hack. It proved quite useful in my  
friends use case, so I thought I'd post it.

>
>
> How about this non-polling alternative, that should be portable  
> among POSIX
> systems:
>
> Install a signal handler on SIGCHLD that wakes the appropriate waiting
> thread.  That thread simply does the waitpid(..., WNOHANG) as before
> (to free process table resouces).

I've implemented this before, and it does work ok. It's a bit more  
work, thats why my patch didn't implement it. We'd need to check what  
the code path through rb_thread_schedule() is, mainly if it searches  
for a runnable thread if select() is interrupted due to a signal.

>
>
> Ultimately, it should be possible to remove these two nasty
> rb_thread_polling() calls
> in process.c via this technique.
>
> In the short term, one could probably prototype the idea with a Ruby  
> trap
> handler and
> a wrapper around Kernel.spawn()
>
> What do you think?
>
> - brent
>
>
> Evan Phoenix wrote:
>>
>> This evening I wrote this patch while helping a friend diagnose why,
>> when Threads are off, `system("date")` takes 2.2ms, and when Threads
>> are on, 60ms.
>>
>> The radical difference is a symptom of MRI's green threads and how  
>> you
>> wait for a child in unix. The current implementation of system
>> immediately calls rb_syswait(), which calls rb_waitpid() right after
>> forking the child. rb_waitpid() calls waitpid(..., WNOHANG), which
>> almost always returns nothing, since the child probably hasn't even
>> actually started yet.
>>
>> My patch improves upon this by adding a 5ms 'quicksleep' zone. At
>> intervals of 0.5ms for the first 5ms after rb_waitpid is called,
>> waitpid() is called in a loop. This allows short-lived, fast exiting
>> children to be caught and processed almost right away, without
>> incurring the 60ms minimum time we currently have.
>>
>> The patch also adds a poll time backoff for use after the first 5ms.
>> Rather than jumping right to backing off for 60ms, it backs off
>> increments up to 60ms. This allows for children children that take
>> just a little bit longer to be processed a bit quicker too.
>>
>> For long running children, the behavior is the same.
>>
>> This improves behavior a lot for users who run a lot of small, fast
>> programs as children, in true unix style.
>>
>>  - Evan Phoenix // evan / fallingsnow.net
>>
>>
>>
>>
>>
>>
>
> -- 
> View this message in context: http://www.nabble.com/-ruby-core%3A21302---PATCH--drastically-improve-rb_waitpid-for-short-lived-children-tp21431928p21449840.html
> Sent from the ruby-core mailing list archive at Nabble.com.
>
>