[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()
t.insert()
stackless.schedule()
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.
~Brian
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
http://www.stackless.com/mailman/listinfo/stackless
More information about the Stackless
mailing list