[Stackless] comments on PEP 219

Christian Tismer tismer at tismer.com
Tue Mar 13 14:29:53 CET 2001

Ok, I'm adding some comments.

Jeremy Hylton wrote:
> Here are some comments on Gordon's new draft of PEP 219 and the
> stackless dev day discussion at Spam 9.
> I left the dev day discussion with the following takehome message:
> There is a tension between Stackless Python on the one hand and making
> Python easy to embed in and extend with C programs on the other hand.
> The PEP describes this as the major difficulty with C Python.  I won't
> repeat the discussion of the problem there.
> I would like to seem a somewhat more detailed discussion of this in
> the PEP.  I think it's an important issue to work out before making a
> decision about a stack-light patch.
> The problem of nested interpreters and the C API seems to come up in
> several ways.  These are all touched on in the PEP, but not in much
> detail.  This message is mostly a request for more detail :-).
>   - Stackless disallows transfer out of a nested interpreter.  (It
>     has, too; anything else would be insane.)  Therefore, the
>     specification for microthreads &c. will be complicated by a
>     listing of the places where control transfers are not possible.

To be more precise: Stackless catches any attempt to transfer to a
frame that has been locked (is run) by an interpreter that is not
the topmost of the C stack. That's all. You might even run Microthreads
in the fifth interpreter recursion, and later return to other
(stalled) microthreads, if only this condition is met.

>     The PEP says this is not ideal, but not crippling.  I'd like to
>     see an actual spec for where it's not allowed in pure Python.  It
>     may not be crippling, but it may be a tremendous nuisance in
>     practice; e.g. remember that __init__ calls create a critical
>     section.

At the moment, *all* of the __xxx__ methods are restricted to stack-
like behavior. __init__ and __getitem__ should probably be the first
methods beyond Stack-lite, which should get extra treatment.

>   - If an application makes use of C extensions that do create nested
>     interpreters, they will make it even harder to figure out when
>     Python code is executing in a nested interpreter.  For a large
>     systems with several C extensions, this could be complicated.  I
>     presume, therefore, that there will be a C API for playing nice
>     with stackless.  I'd like to see a PEP that discusses what this C
>     API would look like.

Ok. I see the need for an interface for frames here.
An extension should be able to create a frame, together with
necessary local memory.
It appears to need two or three functions in the extension:
1) Preparation phase
   The extension provides an "interpreter" function which is in
   charge to handle this frame. The preparation phase puts a
   pointer to this function into the frame.
2) Execution phase
   The frame is run by the frame dispatcher, which calls the
   interpreter function.
   For every nested call into Python, the interpreter function
   needs to return with a special signal for the scheduler,
   that there is now a different frame to be scheduled.
   These notifications, and midifying the frame chain, should
   be hidden by API calls.
3) cleanup phase (necessary?)
   A finalization function may be (optionally) provided for
   the frame destructor.

>   - Would allow of the internal Python calls that create nested
>     functions be replaced?  I'm thinking of things like
>     PySequence_Fast() and the ternary_op() call in abstract.c.  How
>     hard will it be to convert all these functions to be stackless?

PySequence_Fast() calls back into PySequence_Tuple(). In the generic
sequence case, it calls 
       PyObject *item = (*m->sq_item)(v, i);

This call may now need to return to the frame dispatcher without
having its work done. But we cannot do this, because the current
API guarantees that this method will return either with a result
or an exception. This means, we can of course modify the interpreter
to deal with a third kind of state, but this would probably break
some existing extensions.
It was the reason why I didn't try to go further here: Whatever
is exposed to other code but Python itself might break by such
an extension, unless we find a way to distinguish *who* calls.
On the other hand, if we are really at a new Python,
incompatibility would be just ok, and the problem would vanish.

>     How many functions are affected?  And how many places are they
>     called from?

This needs more investigation.

>   - What is the performance impact of adding the stackless patches?  I
>     think Christian mentioned a 10% slowdown at dev day, which doesn't
>     sound unreasonable.  Will reworking the entire interpreter to be
>     stackless make that slowdown larger or smaller?

No, it is about 5 percent. My optimization gains about 15 percent,
which makes a win of 10 percent overall.
The speed loss seems to be related to extra initialization calls
for frames, and the somewhat more difficult parameter protocol.
The fact that recusions are turned into repetitive calls from
a scheduler seems to have no impact. In other words: Further
"stackless" versions of internal functions will probably not
produce another slowdown.
This matches the observation that the number of function calls
is nearly the same, whether recursion is used or stackless.
It is mainly the order of function calls that is changed.

> One other set of issues, that is sort-of out of bounds for this
> particular PEP, is what control features do we want that can only be
> implemented with stackless.  Can we implement generators or coroutines
> efficiently without a stackless approach?

For some limitated view of generators: Yes, absolutely. *)
For coroutines: For sure not.

*) generators which live in the context of the calling
function, like the stack-based generator implementation of
one of the first ICON implementations, I think.
That is, these generators cannot be re-used somewhere else.

ciao - chris

Christian Tismer             :^)   <mailto:tismer at tismer.com>
Mission Impossible 5oftware  :     Have a break! Take a ride on Python's
Kaunstr. 26                  :    *Starship* http://starship.python.net/
14163 Berlin                 :     PGP key -> http://wwwkeys.pgp.net/
PGP Fingerprint       E182 71C7 1A9D 66E9 9D15  D3CC D4D7 93E2 1FAE F6DF
     where do you want to jump today?   http://www.stackless.com/
Stackless mailing list
Stackless at starship.python.net

More information about the Stackless mailing list