[pypy-svn] r20929 - pypy/dist/pypy/translator/c/test
rxe at codespeak.net
rxe at codespeak.net
Fri Dec 9 12:39:37 CET 2005
Author: rxe
Date: Fri Dec 9 12:39:36 2005
New Revision: 20929
Modified:
pypy/dist/pypy/translator/c/test/test_tasklets.py
Log:
More experiments... should probably move this out of here?
Modified: pypy/dist/pypy/translator/c/test/test_tasklets.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_tasklets.py (original)
+++ pypy/dist/pypy/translator/c/test/test_tasklets.py Fri Dec 9 12:39:36 2005
@@ -1,13 +1,35 @@
-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
+import os
+from pypy.rpython.memory.lladdress import NULL
from pypy.rpython.rstack import yield_current_frame_to_caller
-from pypy.translator.backendopt.all import backend_optimizations
import os
+# ____________________________________________________________
+# For testing
+
+from pypy.translator.c.gc import BoehmGcPolicy
+gcpolicy = None #BoehmGcPolicy
+debug_flag = True
+
+# count of loops in tests (set lower to speed up)
+loops = 5000
+
+def debug(s):
+ if debug_flag:
+ os.write(2, "%s\n" % s)
+
+class Globals:
+ def __init__(self):
+ pass
+
+globals = Globals()
+globals.count = 0
def wrap_stackless_function(fn):
+ 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.translator.backendopt.all import backend_optimizations
+
def entry_point(argv):
os.write(1, str(fn()))
return 0
@@ -18,7 +40,7 @@
t.buildannotator().build_types(entry_point, [s_list_of_strings])
t.buildrtyper().specialize()
backend_optimizations(t)
- cbuilder = CStandaloneBuilder(t, entry_point)
+ cbuilder = CStandaloneBuilder(t, entry_point, gcpolicy=gcpolicy)
cbuilder.stackless = True
cbuilder.generate_source()
cbuilder.compile()
@@ -26,39 +48,79 @@
# ____________________________________________________________
-def debug(s):
- #os.write(1, "%s\n" % s)
- pass
-
-class Tasklet(object):
-
- def __init__(self, name, fn):
+class Resumable(object):
+ def __init__(self, fn):
self.fn = fn
- self.name = name
self.alive = False
+ # propogates round suspend-resume to tell scheduler in run()
+ # XXX too late to think this thru
+ self.remove = 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
+ def set_resumable(self, resumable):
self.resumable = resumable
- def schedule(self):
- debug("scheduling %s" % self.name)
+ def suspend(self, remove):
self.caller = self.caller.switch()
-
+ self.remove = remove
+
def resume(self):
- debug("resuming %s" % self.name)
+ debug("resuming %s" % self.name)
self.resumable = self.resumable.switch()
self.alive = self.resumable is not None
+ # not sure what to do with alive yetXXX
+ #XXX arggh - why NOT??
+ #if not alive:
+ # self.caller = # None / NULL
+ return self.alive and not self.remove
+
+class Tasklet(Resumable):
+ def __init__(self, name, fn):
+ Resumable.__init__(self, fn)
+ self.name = name
+ self.blocked = False
+
+class Channel:
+ def __init__(self):
+ self.balance = 0
+ self.queue = []
+
+ def send(self, value):
+ self.balance += 1
+ if self.balance < 0:
+ t = self.queue.pop(0)
+ t.data = value
+ t.blocked = 0
+ else:
+ t = getcurrent()
+ # Remove the tasklet from the list of running tasklets.
+ #XXX dont need this - t.remove()
+
+ # let it wait for a receiver to come along
+ self.queue.append((t, value))
+ t.blocked = 1
+ scheduler.schedule()
+
+ def receive(self):
+ self.balance -= 1
+ # good to go
+ if self.balance > 0:
+ t, value = self.queue.pop(0)
+ t.blocked = 0
+ scheduler.add_tasklet(t)
+ return value
+
+ # block until ready
+ t = getcurrent()
+ self.queue.append(t)
+ t.blocked = -1
+ scheduler.schedule()
class Scheduler(object):
def __init__(self):
@@ -69,55 +131,89 @@
self.runnables.append(tasklet)
def run(self):
- debug("running: length of runnables %s" % len(self.runnables))
+ debug("len1 %s" % len(self.runnables))
while 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")
+ runnables = self.runnables
+ debug("len2 %s" % len(runnables))
+ self.runnables = []
+ for t in runnables:
+ assert self.current_tasklet is None
+ self.current_tasklet = t
+ if t.resume():
+ self.runnables.append(self.current_tasklet)
+ self.current_tasklet = None
+
+ def schedule(self, remove=False):
+ assert self.current_tasklet is not None
+ self.current_tasklet.suspend(remove)
+
+# ____________________________________________________________
scheduler = Scheduler()
def start_tasklet(tasklet):
res = tasklet.start()
- tasklet.setalive(res)
+ tasklet.set_resumable(res)
scheduler.add_tasklet(tasklet)
+def schedule():
+ scheduler.schedule()
+
+def schedule_remove():
+ scheduler.schedule(remove=True)
+
def run():
scheduler.run()
-def schedule():
- assert scheduler.current_tasklet
- scheduler.current_tasklet.schedule()
+def getcurrent():
+ return scheduler.current_tasklet
+
+# ____________________________________________________________
def test_simple():
- class Counter:
- def __init__(self):
- self.count = 0
+
+ def simple(name):
+ for ii in range(5):
+ globals.count += 1
+ schedule()
- def increment(self):
- self.count += 1
+ def f():
+ for ii in range(loops):
+ start_tasklet(Tasklet("T%s" % ii, simple))
+ run()
+ return globals.count == loops * 5
- def get_count(self):
- return self.count
+ res = wrap_stackless_function(f)
+ assert res == '1'
- c = Counter()
+def test_multiple_simple():
def simple(name):
for ii in range(5):
- debug("xxx %s %s" % (name, ii))
- c.increment()
+ globals.count += 1
schedule()
- def f():
+ def simple2(name):
for ii in range(5):
- start_tasklet(Tasklet("T%s" % ii, simple))
+ globals.count += 1
+ schedule()
+ globals.count += 1
+
+ def simple3(name):
+ schedule()
+ for ii in range(10):
+ globals.count += 1
+ if ii % 2:
+ schedule()
+ schedule()
+
+ def f():
+ globals.count = 0
+ for ii in range(loops):
+ start_tasklet(Tasklet("T1%s" % ii, simple))
+ start_tasklet(Tasklet("T2%s" % ii, simple2))
+ start_tasklet(Tasklet("T3%s" % ii, simple3))
run()
- return c.get_count() == 25
+ return globals.count == loops * 25
res = wrap_stackless_function(f)
assert res == '1'
More information about the Pypy-commit
mailing list