[pypy-svn] r27668 - in pypy/dist/pypy/module/stackless: . test

arigo at codespeak.net arigo at codespeak.net
Thu May 25 16:21:22 CEST 2006


Author: arigo
Date: Thu May 25 16:21:21 2006
New Revision: 27668

Modified:
   pypy/dist/pypy/module/stackless/interp_clonable.py
   pypy/dist/pypy/module/stackless/interp_coroutine.py
   pypy/dist/pypy/module/stackless/test/test_interp_clonable.py
Log:
Finished the draft ClonableCoroutine.  Needed to reorganize a bit when
hello() and goodbye() are called, to put the frames in the correct
malloc pool.



Modified: pypy/dist/pypy/module/stackless/interp_clonable.py
==============================================================================
--- pypy/dist/pypy/module/stackless/interp_clonable.py	(original)
+++ pypy/dist/pypy/module/stackless/interp_clonable.py	Thu May 25 16:21:21 2006
@@ -51,3 +51,7 @@
     # we resume here twice.  The following would need explanations about
     # why it returns the correct thing in both the parent and the child...
     return thunk.newcoroutine
+
+##    from pypy.rpython.lltypesystem import lltype, lloperation
+##    lloperation.llop.debug_view(lltype.Void, current, thunk,
+##        lloperation.llop.gc_x_size_header(lltype.Signed))

Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py
==============================================================================
--- pypy/dist/pypy/module/stackless/interp_coroutine.py	(original)
+++ pypy/dist/pypy/module/stackless/interp_coroutine.py	Thu May 25 16:21:21 2006
@@ -39,13 +39,8 @@
         self.current = self.main = self.last = None
 
     def update(self, new):
-        old = self.current
-        if old is not None:
-            old.goodbye()
-        self.last, self.current = old, new
+        self.last, self.current = self.current, new
         frame, new.frame = new.frame, None
-        if new is not None:
-            new.hello()
         return frame
 
 class CoState(BaseCoState):
@@ -124,7 +119,11 @@
     def _bind(self, thunk):
         state = self.costate
         self.parent = state.current
-        state.last.frame = yield_current_frame_to_caller()
+        incoming_frame = yield_current_frame_to_caller()
+        left = state.last
+        left.frame = incoming_frame
+        left.goodbye()
+        self.hello()
         try:
             costate.do_things_to_do()
             thunk.call()
@@ -146,8 +145,11 @@
             # greenlets and tasklets have different ideas about this.
             raise CoroutineDamage
         state = self.costate
-        state.last.frame = state.update(self).switch()
-        # note that last gets updated before assignment!
+        incoming_frame = state.update(self).switch()
+        left = state.last
+        left.frame = incoming_frame
+        left.goodbye()
+        self.hello()
         costate.do_things_to_do()
 
     def kill(self):
@@ -195,7 +197,7 @@
         "Called when execution is transferred into this coroutine."
 
     def goodbye(self):
-        "Called just before execution is transferred away from this coroutine."
+        "Called just after execution is transferred away from this coroutine."
 
 costate = None
 costate = CoState()

Modified: pypy/dist/pypy/module/stackless/test/test_interp_clonable.py
==============================================================================
--- pypy/dist/pypy/module/stackless/test/test_interp_clonable.py	(original)
+++ pypy/dist/pypy/module/stackless/test/test_interp_clonable.py	Thu May 25 16:21:21 2006
@@ -45,8 +45,42 @@
         res = run([])
         assert res == 1234546
 
+    def test_clone_local_state(self):
+        class T(AbstractThunk):
+            def __init__(self, result):
+                self.result = result
+            def call(self):
+                localstate = []
+                localstate.append(10)
+                self.result.append(2)
+                costate.main.switch()
+                localstate.append(20)
+                if localstate == [10, 20]:
+                    self.result.append(4)
+                else:
+                    self.result.append(0)
+        def f():
+            result = []
+            coro = ClonableCoroutine()
+            coro.bind(T(result))
+            result.append(1)
+            coro.switch()
+            coro2 = coro.clone()
+            result.append(3)
+            coro2.switch()
+            result.append(5)
+            coro.switch()
+            result.append(6)
+            n = 0
+            for i in result:
+                n = n*10 + i
+            return n
+
+        run = self.runner(f)
+        res = run([])
+        assert res == 1234546
+
     def test_fork(self):
-        import py; py.test.skip("in-progress")
         class T(AbstractThunk):
             def __init__(self, result):
                 self.result = result



More information about the Pypy-commit mailing list