Re: continuations and threads Jim Blandy 18 Feb 2000 17:10 UTC

> > I think this is pretty gross, but it does allow a natural
> > correspondence between C function calls and Scheme function calls:
> > continuations preserve active calls to C functions, as well as Scheme
> > functions.  If it's important to your users to be able to write C
> > functions that can call and be called by Scheme functions, I think
> > this is a plausible implementation choice.  I'm not aware of any other
> > implementation that does this while requiring so little distortion of
> > your C code.  (But if you know of one, I'd love to hear about it!)
> There is another way (I have not implemented it yet though)... but it
> is too complex to describe at this hour of the night!


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

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

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

The nice thing about this arrangement is that you only pay for what
you use.  If your code is pure ML, call/cc is completely unaffected
--- you can do everything you used to.  If you call some C functions,
then you can do everything C can do with those frames, but no more.
If you have a call sequence like this:

   C func A   -->   ML func X --> C func B --> ML func Y

it's perfectly okay for control to jump (via continuations) from Y
back into X, and then back out to Y, and then return back to B.  The
only frames being used in a non-stacklike fashion are those for X and
Y, where the language implementation is prepared for this.

I'm being terse here; if it sounds like nonsense, let me know, and I
can explain more carefully.

The analogous arrangement in the context of multi-threaded Scheme
would allow Scheme frames to be used in any order by any thread, but
allow C frames to be used only in a stack-like order, on a single

Is this similar at all to your idea?