[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: continuations and threads

This page is part of the web mail archives of SRFI 18 from before July 7th, 2015. The new archives for SRFI 18 contain all messages, not just those from before July 7th, 2015.



Jim> Now that you mention it, there is something I remember Roland McGrath
Jim> implementing for SMLNJ, while working for Olin Shivers.

Jim> I think the basic idea was that frames (activation records) for ML
Jim> functions were kept on the heap (as normal), while frames for C
Jim> functions were kept on a C stack.  You let the ML frames behave like
Jim> the first-class objects they are --- you can call/cc to your heart's
Jim> content --- but if you try to return to a C frame in a non-stacklike
Jim> order, the ML/C boundary code detects this and throws an exception.

Jim> I think he even arranged it so that if you returned early to an older
Jim> C frame, the younger frames would be popped appropriately (via
Jim> longjmp), and any references to younger C frames would be marked
Jim> invalid, so you'd get an error if you tried to use them.

Mike> The C FFI Richard Kelsey and I implemented for Scheme 48 does this as
Mike> well.  Here's the relevant blurb from the documentation:
Mike> 
Mike>    There are some complications that occur when mixing calls from C to
Mike>    Scheme with continuations and threads. C only supports downward
Mike>    continuations (via longjmp()). Scheme continuations that capture a
Mike>    portion of the C stack have to follow the same restriction. For
Mike>    example, suppose Scheme procedure s0 captures continuation a and
Mike>    then calls C procedure c0, which in turn calls Scheme procedure s1.
Mike>    Procedure s1 can safely call the continuation a, because that is a
Mike>    downward use. When a is called Scheme 48 will remove the portion of
Mike>    the C stack used by the call to c0. On the other hand, if s1
Mike>    captures a continuation, that continuation cannot be used from s0,
Mike>    because by the time control returns to s0 the C stack used by c0
Mike>    will no longer be valid. An attempt to invoke an upward
Mike>    continuation that is closed over a portion of the C stack will
Mike>    raise an exception.

Actually, this is less powerful than what I described.  In Roland's
system, you don't need to unwind the C stack when s1 invokes a.  You
only need to unwind the C stack when s0 returns.  If s0 instead
invokes some continuation b captured by s1, that's fine.

The key observation here is that the only necessary connection between
C frames and Scheme frames occurs when control crosses a Scheme/C or
C/Scheme boundary.  Each C frame may be exited only once, and you may
only return to a C frame after popping all younger C frames.  But
beyond those rules, there's no necessary restriction on the way Scheme
frames may behave.