<!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> </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> </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> </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> </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, can someone shed some light with more info ? </DIV>
<DIV> </DIV>
<DIV>Thanks again.</DIV>
<DIV> </DIV>
<DIV>- Jim</DIV>
<DIV> </DIV>
<DIV><BR>On 10/14/06 Richard Tew richard.m.tew at gmail.com wrote:</DIV>
<DIV> </DIV>
<DIV>> I have a C++ event driven main loop framework that embedded the
stackless<BR>> framework.<BR>> The only way I can make these two framework
work together is: switching<BR>> between two frameworks in a fix time
range.<BR>><BR>> 1. timeout the select() call in my C++ main loop every
few hundreds<BR>> milliseconds,<BR>> 2. give a few hundress millisecond
for stackless code to run:<BR>> watchdogHandle =<BR>>
handle<>(allow_null(PyStackless_RunWatchdog(1000)));</DIV>
<DIV> </DIV>
<DIV>This runs for around 1000 instructions. 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.
As long as<BR>you know that.</DIV>
<DIV> </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. At which<BR>point the watchdog exits cleanly, cooperative
scheduling is maintained and<BR>the embedding C++ code can do whatever it
needs. 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> </DIV>
<DIV>Links of interest:</DIV>
<DIV> </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> </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> </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> </DIV>
<DIV>> 3. go back to the C++ main loop and block on select()
again<BR>><BR>> This way works but not so elegant. It might be idle and
waste a few hundred<BR>> millisecond per loop in one framework while the
other framework has work<BR>> waiting for it to do.<BR>><BR>> I am
thinking a "perfect" model will be ...<BR>><BR>> If stackless internally
is also blocking on a select( fdset2 ) call, we can<BR>> add a stackless API
to export that file descriptor set (fdset2).<BR>> Then we can merge two
select() calls of two main loops into a single select(<BR>> fdset1+ fdset2 )
call. We can then listen to all events in one blocking<BR>> select
call.</DIV>
<DIV> </DIV>
<DIV>Stackless does not do any calls to select. All it does is add
tasklets,<BR>channels and scheduling to the Python runtime. It has no need
to wait<BR>on any file descriptors itself.</DIV>
<DIV> </DIV>
<DIV>Hope this helps,<BR>Richard.</DIV>
<DIV> </DIV>
<DIV> </DIV></FONT></BODY></HTML>