[pypy-svn] r20886 - pypy/dist/pypy/translator/c/test
rxe at codespeak.net
rxe at codespeak.net
Thu Dec 8 12:48:59 CET 2005
Author: rxe
Date: Thu Dec 8 12:48:58 2005
New Revision: 20886
Added:
pypy/dist/pypy/translator/c/test/test_tasklets.py (contents, props changed)
Log:
Proof of concept tasklet switching in rpython.
Added: pypy/dist/pypy/translator/c/test/test_tasklets.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/test/test_tasklets.py Thu Dec 8 12:48:58 2005
@@ -0,0 +1,120 @@
+from pypy.translator.translator import TranslationContext
+from pypy.translator.c.genc import CStandaloneBuilder
+from pypy.annotation.model import SomeList, SomeString
+from pypy.annotation.listdef import ListDef
+from pypy.rpython.rstack import stack_unwind, stack_frames_depth, stack_too_big
+from pypy.rpython.rstack import yield_current_frame_to_caller
+import os
+
+def wrap_stackless_function(fn):
+ def entry_point(argv):
+ os.write(1, str(fn()))
+ return 0
+
+ s_list_of_strings = SomeList(ListDef(None, SomeString()))
+ s_list_of_strings.listdef.resize()
+ t = TranslationContext()
+ t.buildannotator().build_types(entry_point, [s_list_of_strings])
+ t.buildrtyper().specialize()
+ cbuilder = CStandaloneBuilder(t, entry_point)
+ cbuilder.stackless = True
+ cbuilder.generate_source()
+ cbuilder.compile()
+ return cbuilder.cmdexec('')
+
+# ____________________________________________________________
+
+def debug(s):
+ #os.write(1, "%s\n" % s)
+ pass
+
+class Tasklet(object):
+
+ def __init__(self, name, fn):
+ self.fn = fn
+ self.name = name
+ self.alive = False
+
+ def start(self):
+ debug("starting %s" % self.name)
+ self.caller = yield_current_frame_to_caller()
+
+ debug("entering %s" % self.name)
+ self.fn(self.name)
+ debug("leaving %s" % self.name)
+ return self.caller
+
+ def setalive(self, resumable):
+ self.alive = True
+ self.resumable = resumable
+
+ def schedule(self):
+ debug("scheduling %s" % self.name)
+ self.caller = self.caller.switch()
+
+ def resume(self):
+ debug("resuming %s" % self.name)
+ self.resumable = self.resumable.switch()
+ self.alive = self.resumable is not None
+
+
+class Scheduler(object):
+ def __init__(self):
+ self.runnables = []
+ self.current_tasklet = None
+
+ def add_tasklet(self, tasklet):
+ self.runnables.append(tasklet)
+
+ def run(self):
+ debug("running: length of runnables %s" % len(self.runnables))
+ while len(self.runnables):
+ t = self.runnables.pop(0)
+ debug("resuming %s(%s)" % (t.name, t.alive))
+ self.current_tasklet = t
+ t.resume()
+ self.current_tasklet = None
+ if t.alive:
+ self.runnables.append(t)
+
+ debug("ran")
+
+scheduler = Scheduler()
+def start_tasklet(tasklet):
+ res = tasklet.start()
+ tasklet.setalive(res)
+ scheduler.add_tasklet(tasklet)
+
+def run():
+ scheduler.run()
+
+def schedule():
+ assert scheduler.current_tasklet
+ scheduler.current_tasklet.schedule()
+
+def test_simple():
+ class Counter:
+ def __init__(self):
+ self.count = 0
+
+ def increment(self):
+ self.count += 1
+
+ def get_count(self):
+ return self.count
+
+ c = Counter()
+
+ def simple(name):
+ for ii in range(5):
+ debug("xxx %s %s" % (name, ii))
+ c.increment()
+ schedule()
+
+ def f():
+ for ii in range(5):
+ start_tasklet(Tasklet("T%s" % ii, simple))
+ run()
+ return c.get_count() == 25
+
+ assert wrap_stackless_function(f) == '1'
More information about the Pypy-commit
mailing list