This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: tselect


[For those who haven't followed this discussion previously: Marius and
 I are discussing how to obtain non-blocking I/O with the current
 cooperative threads package.  Currently, any blocking I/O call will
 in fact block all threads, since context switch only occurs at certain
 safe points during evaluation.

 Marius is interested in supporting event call-backs.  I'm interested
 in using all I/O functions just as usual, and still have context
 switching going.  I'm also interested in being able to implement a
 server which can support multiple repl sessions into the same Guile
 process, and I want this to be easy to implement.

 The current idea is that we only should allow Guile primitives to
 block on a call to scm_internal_select ().  scm_internal_select ()
 will contain all magic to allow context switching to happen and
 call-backs to be called.

 Thus, the basic idea is that all I/O blocking is "channeled" through
 scm_internal_select ().
]

Marius Vollmer <mvo@zagadka.ping.de> writes:

> Mikael Djurfeldt <mdj@nada.kth.se> writes:
>  
> > I should say that this is not simply my way of forcing preemptive COOP
>                                                          ^^^^^^^^^^ ^^^^
> That's a contradiction, isn't it?

Well, I used COOP as a proper noun, i. e., I only meant to say a
preemtive version of the thread package which we're currently using
(which is named COOP).  (If anyone thinks we're using QuickThreads,
that is true too: COOP is the layer on top of QuickThreads.)

But you're right that it is confusing.  :)

> It is the right thing.  Please consider exposing the event-loop that
> is at the heart of scm_internal_select to allow people to use it
> without threads.

Yes, given my current ideas about the internal structure of
scm_internal_select, it won't be difficult to support a call-back
interface as well, and it wouldn't decrease performance.  And, as you
say, that would allow people to use the same mechanism even if they
haven't got threads.

How should the call-back interface look like?

Since it is a subfunction of select (I will say "select" when I mean
the Scheme procedure select.  This is a wrapper for the C level
"scm_internal_select" (former tselect) which, in turn, uses what I'll
call "OS select".) it is probably wise to let it have an interface
reminding of select.  Here comes a modified version of select together
with the new procedures `add-select-callback' and
`remove-select-callback':

  (select <reads> <writes> <excepts> [<secs> <usecs>])

    Add this thread to the global set of activation subscribers and
    call OS select on the union of the activation conditions (the
    arguments to select) for all activation subscribers.

    An activation subscriber is either a thread or a thread-associated
    callback.  If all threads are waiting for I/O or sleeping, the
    Guile process will be sleeping inside OS select.  When an activation
    condition for any activation subscriber is met, it will be
    activated.  If any thread is running, OS select will instead be
    called at each context switch point.

    Threads can only become activation subscribers by a call to
    select, so for a thread, activation simply means waking up and
    continuing after select.

  (add-select-callback <callback> <reads> <writes> <excepts> [<secs> <usecs>])

    Add <callback> for this thread to the global set of activation
    subscribers.

    For a callback, activation means that the *current* thread evaluates
    the callback in the dynamic context of the thread with which the
    callback is associated.

  (remove-select-callback <callback>)

    Remove <callback> from the global set of activation subscribers.

> The event business is the basic semantic thing.  Threads are only a
> convenient way to avoid converting your program to
> continuation-passing-style and using callbacks throughout.

Well, while I sympathize with this view theoretically, we still have
to keep in mind that our threads have separate physical stacks
lying around somewhere in space.

> > I'll certainly not commit anything until people beg me to do it.  ;-)
> 
> Please... ;-)

You know, I just got the urge to convert Guile into
continuation-passing-style.  It's OK if I commit it to night, isn't
it?  8-)