<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
<META content="MSHTML 6.00.2900.2802" name=GENERATOR></HEAD>
<BODY id=role_body style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Arial" 
bottomMargin=7 leftMargin=7 topMargin=7 rightMargin=7><FONT id=role_document 
face=Arial color=#000000 size=2>
<DIV>&nbsp;</DIV>
<DIV>Richard, thank you for the comment. For CCP game's custom yielding 
approach, I got a question: when finish the work in stackless world and 
switching to another world (the other event driven framework, C++ watchdog for 
low level tcp/file io, etc), how long it want to stay there before switching 
back to stackless world ?</DIV>
<DIV>&nbsp;</DIV>
<DIV>- If the approach is "stay only when it has job to do", then when the two 
event driven frameworks are idle (no job to do), the code will be busy switching 
between the two frameworks again and again. It can cause a fast tight loop with 
up to 99% cpu usage.</DIV>
<DIV>&nbsp;</DIV>
<DIV>- If the approach is "always stay for x hundreds millisecond", then that "x 
hundreds millisecond" is wasted when framework we are waiting has no job for us 
to do.</DIV>
<DIV>&nbsp;</DIV>
<DIV>The wild guess that stackless internally (at system call level) is blocking 
at select()/ poll() call (after finish all callback jobs it need to do), because 
that's only way I can think of (in Unix part of implementation) which can 
listening/bockling on many different events queues without using a tight loop to 
scan all of them. If stackless use a different way to do it at unix system call 
level,&nbsp; can someone shed some light with more info ? </DIV>
<DIV>&nbsp;</DIV>
<DIV>Thanks again.</DIV>
<DIV>&nbsp;</DIV>
<DIV>- Jim</DIV>
<DIV>&nbsp;</DIV>
<DIV><BR>On 10/14/06 Richard Tew richard.m.tew at gmail.com wrote:</DIV>
<DIV>&nbsp;</DIV>
<DIV>&gt; I have a C++ event driven main loop framework that embedded the 
stackless<BR>&gt; framework.<BR>&gt; The only way I can make these two framework 
work together is: switching<BR>&gt; between two frameworks in a fix time 
range.<BR>&gt;<BR>&gt; 1. timeout the select() call in my C++ main loop every 
few hundreds<BR>&gt; milliseconds,<BR>&gt; 2. give a few hundress millisecond 
for stackless code to run:<BR>&gt;&nbsp;&nbsp;&nbsp; watchdogHandle =<BR>&gt; 
handle&lt;&gt;(allow_null(PyStackless_RunWatchdog(1000)));</DIV>
<DIV>&nbsp;</DIV>
<DIV>This runs for around 1000 instructions.&nbsp; Which means that it will not 
exit<BR>the currently running tasklet where you explicitly cooperatively 
schedule<BR>or yield using some other manner, but in a preemptive manner.&nbsp; 
As long as<BR>you know that.</DIV>
<DIV>&nbsp;</DIV>
<DIV>At CCP Games we take a different approach, which you can read about 
in<BR>the slideshow Kristján Jónsson gave at PyCon 2006. Instead of 
interrupting<BR>the permanently scheduled tasklets, we use custom yielding 
methods (BeNice,<BR>Sleep or on a channel waiting for an event) and never 
schedule to divert<BR>all the scheduled tasklets so that it is natural for all 
tasklets that have<BR>been scheduled to run once and then the scheduler will be 
empty.&nbsp; At which<BR>point the watchdog exits cleanly, cooperative 
scheduling is maintained and<BR>the embedding C++ code can do whatever it 
needs.&nbsp; From what Kristján tells<BR>me (I don't work on this section of 
code myself) it is common that the<BR>scheduler is empty so we use a very large 
timeout for the watchdog in order<BR>to detect badly programmed tasklets which 
are infinite looping or something<BR>similar.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Links of interest:</DIV>
<DIV>&nbsp;</DIV>
<DIV>The slideshow:<BR><A 
href="http://www.stackless.com/Members/rmtew/code/PyCon2006-StacklessEvePresentation.zip/download">http://www.stackless.com/Members/rmtew/code/PyCon2006-StacklessEvePresentation.zip/download</A></DIV>
<DIV>&nbsp;</DIV>
<DIV>Basic C++ framework with alternate yielding method BeNice:<BR><A 
href="http://svn.python.org/view/stackless/sandbox/examples/embedding/watchdog-cpp/">http://svn.python.org/view/stackless/sandbox/examples/embedding/watchdog-cpp/</A></DIV>
<DIV>&nbsp;</DIV>
<DIV>Basic C framework with alternate yielding method BeNice:<BR><A 
href="http://svn.python.org/view/stackless/sandbox/examples/embedding/watchdog-c/">http://svn.python.org/view/stackless/sandbox/examples/embedding/watchdog-c/</A></DIV>
<DIV>&nbsp;</DIV>
<DIV>&gt; 3. go back to the C++ main loop and block on select() 
again<BR>&gt;<BR>&gt; This way works but not so elegant. It might be idle and 
waste a few hundred<BR>&gt; millisecond per loop in one framework while the 
other framework has work<BR>&gt; waiting for it to do.<BR>&gt;<BR>&gt; I am 
thinking a "perfect" model will be ...<BR>&gt;<BR>&gt; If stackless internally 
is also blocking on a select( fdset2 ) call, we can<BR>&gt; add a stackless API 
to export that file descriptor set (fdset2).<BR>&gt; Then we can merge two 
select() calls of two main loops into a single select(<BR>&gt; fdset1+ fdset2 ) 
call. We can then listen to all events in one blocking<BR>&gt; select 
call.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Stackless does not do any calls to select.&nbsp; All it does is add 
tasklets,<BR>channels and scheduling to the Python runtime.&nbsp; It has no need 
to wait<BR>on any file descriptors itself.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Hope this helps,<BR>Richard.</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV></FONT></BODY></HTML>