[Stackless] Stackless based replacement

Larry Dickson ldickson at cuttedge.com
Fri Oct 3 17:45:08 CEST 2008


Hi Arnar,

Am I following io_operation right: the callback is an externally spawned (?)
process which blocks waiting on the real IO operation but does not take up a
slot in the Stackless round robin? And event.notify_when_ready_for_op
returns instantly even if not ready? If so, then libevent seems to introduce
a layer of multitasking that is not under the Stackless umbrella.

The half-busy loop (with the time.sleep(0.0001)) is not necessary if the
blocking select is used when no tasklets can run.

The 1 ms and 2.5 ms were determined by experiment (you just loop on a usleep
or nanosleep of some tiny positive amount - this always waits one tick, at
least in C/Linux). This is obviously motherboard-dependent, and the newer
motherboard had the slower response. I suspect interrupt response in general
is getting sluggish, and they are afraid of a pileup of event code chained
to the timer tick.

Larry

On 10/3/08, Arnar Birgisson <arnarbi at gmail.com> wrote:
>
> Hi Larry,
>
> On Fri, Oct 3, 2008 at 01:01, Larry Dickson <ldickson at cuttedge.com> wrote:
> > Wow! If that's your idea of a simple solution, I'd hate to see a
> complicated
> > one ;-)
>
> Well, if you look closely you'll see that it is basically a repeat of
> the same pattern over and over:
>
> def io_operation(*args,**kwargs):
>    def callback():
>        result = perform_real_io_operation(*args,**kwargs)
>        channel_dedicated_to_this_op.send(result)
>    event.notify_when_ready_for_op(callback)
>    return channel_dedicated_to_this_op.receive()
>
> This pattern is simply applied to file.read, file.write, socket.send,
> socket.recv and socket.accept. The sleep function is even simpler.
>
> As for the dispatching tasklet:
>
> def _loop():
>   while _loop.running:
>       event.loop(True)
>       if stackless.getruncount() == 1:
>           time.sleep(0.0001)
>       stackless.schedule()
> _loop.running = False
>
> the time.sleep(0.0001) is simply an optimization in the case where
> there are no other tasklets runnable, in which case this would become
> a busy loop eating 100% of cpu. You could leave it out and the
> semantics would hold, in which case the loop is simply:
>
> while running:
>    event.loop(True)      # dispatch any ready IO events
>    stackless.schedule()  # run other tasklets
>
> > Give me a week or so and I'll figure out how that works. What I do notice
> is
> > the time.sleep(0.0001) [by the way, I believe the minimum sleep is
> actually
> > 1 ms in older PCs and 2.5 ms in newer PCs].
>
> 2.5 ms? That's ages.. do you have some references for this?
>
> > Unless C/Linux select is
> > designed horribly (and it could be), my second select approach gets an
> > instant response as soon as the hard interrupt handler returns control to
> > the program. So my notion is not really reinventing the wheel - it is an
> > improvement. And it seems to me it is an awful lot simpler. The only
> danger
> > - like any select - would be huge numbers of simultaneously waiting IOs.
>
> Well, libevent uses the best available method on each platform, for
> linux I believe it uses epoll and not select.
>
> cheers,
> Arnar
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.stackless.com/pipermail/stackless/attachments/20081003/3362fcf0/attachment.htm>


More information about the Stackless mailing list