[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