[pypy-commit] pypy stacklet: Save and restore the topframe from the executioncontext.
arigo
noreply at buildbot.pypy.org
Sat Aug 6 12:49:09 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46317:f67665a962f6
Date: 2011-08-06 12:50 +0200
http://bitbucket.org/pypy/pypy/changeset/f67665a962f6/
Log: Save and restore the topframe from the executioncontext.
diff --git a/pypy/module/_stacklet/interp_stacklet.py b/pypy/module/_stacklet/interp_stacklet.py
--- a/pypy/module/_stacklet/interp_stacklet.py
+++ b/pypy/module/_stacklet/interp_stacklet.py
@@ -12,9 +12,10 @@
class SThread(object):
- def __init__(self, space):
+ def __init__(self, space, ec):
w_module = space.getbuiltinmodule('_stacklet')
self.space = space
+ self.ec = ec
self.w_error = space.getattr(w_module, space.wrap('error'))
self.pending_exception = None
self.main_stacklet = None
@@ -80,7 +81,10 @@
def switch(self, space):
h = self.consume_handle()
sthread = self.sthread
+ ec = sthread.ec
+ saved_frame_top = ec.topframeref
h = rstacklet.switch(sthread.thrd, h)
+ ec.topframeref = saved_frame_top
return sthread.new_stacklet_object(h)
def is_pending(self, space):
@@ -137,10 +141,12 @@
ec = space.getexecutioncontext()
sthread = ec.stacklet_thread
if not sthread:
- sthread = ec.stacklet_thread = SThread(space)
+ sthread = ec.stacklet_thread = SThread(space, ec)
start_state.sthread = sthread
start_state.w_callable = w_callable
start_state.args = __args__
+ saved_frame_top = ec.topframeref
h = rstacklet.new(sthread.thrd, new_stacklet_callback,
lltype.nullptr(rffi.VOIDP.TO))
+ ec.topframeref = saved_frame_top
return sthread.new_stacklet_object(h)
diff --git a/pypy/module/_stacklet/test/test_stacklet.py b/pypy/module/_stacklet/test/test_stacklet.py
--- a/pypy/module/_stacklet/test/test_stacklet.py
+++ b/pypy/module/_stacklet/test/test_stacklet.py
@@ -99,7 +99,9 @@
assert seen == [1, 2, 3]
def test_various_depths(self):
+ skip("may fail on top of CPython")
# run it from test_translated, but not while being actually translated
d = {}
execfile(self.translated, d)
- d['test_various_depths'](max=100)
+ d['set_fast_mode']()
+ d['test_various_depths']()
diff --git a/pypy/module/_stacklet/test/test_translated.py b/pypy/module/_stacklet/test/test_translated.py
--- a/pypy/module/_stacklet/test/test_translated.py
+++ b/pypy/module/_stacklet/test/test_translated.py
@@ -7,6 +7,18 @@
# ____________________________________________________________
+STATUS_MAX = 50000
+MAIN_RECURSION_MAX = 50
+SUB_RECURSION_MAX = 20
+
+def set_fast_mode():
+ global STATUS_MAX, MAIN_RECURSION_MAX, SUB_RECURSION_MAX
+ STATUS_MAX = 100
+ MAIN_RECURSION_MAX = 7
+ SUB_RECURSION_MAX = 3
+
+# ____________________________________________________________
+
class Task:
def __init__(self, n):
self.n = n
@@ -18,7 +30,7 @@
else:
res = 0
n = random.randrange(10)
- if n == self.n or (Task.status >= Task.max and
+ if n == self.n or (Task.status >= STATUS_MAX and
not Task.tasks[n].h):
return 1
@@ -75,7 +87,7 @@
Task.comefrom = -1
Task.gointo = -1
- while self.withdepth(random.randrange(20)) == 0:
+ while self.withdepth(random.randrange(SUB_RECURSION_MAX)) == 0:
pass
assert self.h is None
@@ -94,15 +106,16 @@
print "LEAVING %d to go to %d" % (self.n, n)
return h
+def any_alive():
+ return any([task.h is not None for task in Task.tasks])
-def test_various_depths(max=50000):
+def test_various_depths():
Task.tasks = [Task(i) for i in range(10)]
Task.nextstep = -1
Task.comefrom = -1
Task.status = 0
- Task.max = max
- while Task.status < max or any_alive():
- Task.tasks[0].withdepth(random.randrange(0, 50))
+ while Task.status < STATUS_MAX or any_alive():
+ Task.tasks[0].withdepth(random.randrange(MAIN_RECURSION_MAX))
# ____________________________________________________________
More information about the pypy-commit
mailing list