Eric Hodel
3/1/2007 8:11:00 PM
On Mar 1, 2007, at 07:12, Avdi Grimm wrote:
> On 3/1/07, Tomas Pospisek <tpo2@sourcepole.ch> wrote:
>> However, this applies in exactly the same way to libc-select as
>> well and thus
>> replacing the select/gettimeofday mechanism by libc-sleep should
>> at least work
>> no worse. Objections?
>
> My first reaction was: good god, the scheduler uses wallclock time?!
> Speaking as someone who works on realtime systems (and thus has to
> think about scheduler implementation often), this is never a good
> idea. I don't know the background for Ruby's scheduler design, but
> normally I'd regard a scheduler which uses wallclock time as just
> plain *broken*. I'm heartily in favor of changing it to something
> which isn't dependent on the clock.
The Ruby thread scheduler uses setitimer(2) and select(2). It
depends on the wall-clock for implementing features defined in terms
of the wall-clock (Kernel#sleep and Thread#join).
> That "indeterminate amount" referenced above is simply the price you
> pay for running in userspace ion a modern multitasking OS. Yes,
> system activity could delay the return. That's what multitasking
> means: you don't get to choose when you get the CPU. In practice, if
> applications are experiencing unacceptable latency in OS scheduling
> then 1) your gettimeofday()-based implementation is going to be
> delayed right along with everything else; and 2) you have bigger
> problems, because your system is overloaded.
Kernel#sleep behaves differently in Ruby programs using threads. If
you sleep in a thread you end up context switching to other threads
instead of calling sleep(3).
Since you aren't using sleep(3) in threaded mode, Ruby instead uses
gettimeofday(2) to implement Kernel#sleep for the calling thread (has
this thread slept its N seconds?), so you may sleep longer than you
expect.
The other place gettimeofday(2) is used is Thread#join's timeout, for
similar reason.