[pypy-commit] pypy stacklet: Adding another experimental feature, which may more primitive

arigo noreply at buildbot.pypy.org
Sat Aug 20 11:18:22 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46658:2a0bb6951b10
Date: 2011-08-20 08:59 +0200
http://bitbucket.org/pypy/pypy/changeset/2a0bb6951b10/

Log:	Adding another experimental feature, which may more primitive than
	switch() and throw().

diff --git a/pypy/module/_continuation/__init__.py b/pypy/module/_continuation/__init__.py
--- a/pypy/module/_continuation/__init__.py
+++ b/pypy/module/_continuation/__init__.py
@@ -33,4 +33,5 @@
 
     interpleveldefs = {
         'continulet': 'interp_continuation.W_Continulet',
+        'permute': 'interp_continuation.permute',
     }
diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py
--- a/pypy/module/_continuation/interp_continuation.py
+++ b/pypy/module/_continuation/interp_continuation.py
@@ -17,14 +17,6 @@
         #  - normal:      self.sthread != None, not is_empty_handle(self.h)
         #  - finished:    self.sthread != None, is_empty_handle(self.h)
 
-    def build_sthread(self):
-        space = self.space
-        ec = space.getexecutioncontext()
-        sthread = ec.stacklet_thread
-        if not sthread:
-            sthread = ec.stacklet_thread = SThread(space, ec)
-        self.sthread = sthread
-
     def check_sthread(self):
         ec = self.space.getexecutioncontext()
         if ec.stacklet_thread is not self.sthread:
@@ -38,7 +30,7 @@
         start_state.origin = self
         start_state.w_callable = w_callable
         start_state.args = __args__
-        self.build_sthread()
+        self.sthread = build_sthread(self.space)
         try:
             self.h = self.sthread.new(new_stacklet_callback)
             if self.sthread.is_empty_handle(self.h):    # early return
@@ -222,3 +214,32 @@
     w_value = start_state.w_value
     start_state.w_value = None
     return w_value
+
+def build_sthread(space):
+    ec = space.getexecutioncontext()
+    sthread = ec.stacklet_thread
+    if not sthread:
+        sthread = ec.stacklet_thread = SThread(space, ec)
+    return sthread
+
+# ____________________________________________________________
+
+def permute(space, args_w):
+    sthread = build_sthread(space)
+    #
+    contlist = []
+    for w_cont in args_w:
+        cont = space.interp_w(W_Continulet, w_cont)
+        if cont.sthread is not sthread:
+            if cont.sthread is None:
+                raise geterror(space, "got a non-initialized continulet")
+            else:
+                raise geterror(space, "inter-thread support is missing")
+        elif sthread.is_empty_handle(cont.h):
+            raise geterror(space, "got an already-finished continulet")
+        contlist.append(cont)
+    #
+    if len(contlist) > 1:
+        other = contlist[-1].h
+        for cont in contlist:
+            other, cont.h = cont.h, other
diff --git a/pypy/module/_continuation/test/test_stacklet.py b/pypy/module/_continuation/test/test_stacklet.py
--- a/pypy/module/_continuation/test/test_stacklet.py
+++ b/pypy/module/_continuation/test/test_stacklet.py
@@ -608,6 +608,24 @@
         res = c1.switch()
         assert res == "ok"
 
+    def test_permute(self):
+        from _continuation import continulet, permute
+        #
+        def f1(c1):
+            res = c1.switch()
+            assert res == "ok"
+            return "done"
+        #
+        def f2(c2):
+            permute(c1, c2)
+            return "ok"
+        #
+        c1 = continulet(f1)
+        c2 = continulet(f2)
+        c1.switch()
+        res = c2.switch()
+        assert res == "done"
+
     def test_various_depths(self):
         skip("may fail on top of CPython")
         # run it from test_translated, but not while being actually translated


More information about the pypy-commit mailing list