[Stackless] Explicit yield/break to Preemptive Stackless Loop

Brian Hardie bhardie at cs.usfca.edu
Sun Nov 5 00:13:25 CET 2006

Thanks again for your help.  This new solution seems to work well.

I looked into this a little deeper with the help of Prof. Greg 
Benson(http://www.cs.usfca.edu/~benson).  Together we determined that 
when calling stackless.run() the main tasklet is removed from the 
runnable queue.  Normally the main tasklet is put back on the queue 
after all other tasklets have run to completion or the preemption count 
has been reached.  It seems that the fallback code provided in 
schedule_task_block() only recovers the main tasklet if we are running 
in the initial main thread.

static PyObject *
schedule_task_block(PyTaskletObject *prev, int stackless)
    if (check_for_deadlock()) {
       /*revive real main if floating */
       if (ts == slp_initial_tstate && ts->st.main->next == NULL) {
          /* emulate old revive main behavior:
           * passing a value only if it is an exception
             if (PyBomb_Check(prev->tempval))
                TASKLET_SETVAL(ts->st.main, prev->tempval);
             return slp_schedule_task(prev, ts->st.main, stackless);

I think the expression 'ts == slp_initial_tstate' is checking to see if 
we are running within the main thread.  If so, it recovers the main 
tasklet.  My tasklets are not run by the main thread; perhaps this has 
been a problem.

As an alternative to the solution that you provided, but in a similar 
vein, at the point where a 'yield to main' is desired we can just 
reinsert the main tasklet.  Thus, rewriting the count() function from my 
previous example we have:

def count(self):
    i = 0
    while 1:
        print i
        i += 1
        t = stackless.getmain()

This avoids having to create another tasklet to perform the remove.  I don't think this solution will work with multiple tasklets, but as I am only using one it seems to work fine.


Jeff Senn wrote:
> On Nov 2, 2006, at 8:10 PM, Brian Hardie wrote:
>> I think I should describe my situation a bit more.
> ...snipped for brevity...
> Brian - I'm at a loss to explain the channel behavior your
> example exhibits at the moment... let me just suggest something
> simpler (since you want to pickle anyway....)  if I get a chance
> I'll look into it more later.
> Instead of using a channel just remove the tasklet from runnables.
> (There is a trick to doing this -- since you can't just remove yourself).

Stackless mailing list
Stackless at stackless.com

More information about the Stackless mailing list