Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r29:09c8f542c33d
Date: 2013-05-26 20:07 +0200
http://bitbucket.org/pypy/stmgc/changeset/09c8f542c33d/

Log:    Split these two cases into three, and implement one more.

diff --git a/c3/nursery.c b/c3/nursery.c
--- a/c3/nursery.c
+++ b/c3/nursery.c
@@ -625,10 +625,15 @@
             /*mark*/
             continue;
         }
-        /* The listed object was not visited.  Either it's because it
-           is really unreachable (in which case it cannot possibly
-           be modified any more, and the current transaction cannot
-           abort because of it) or it's because it was already modified.
+        /* The listed object was not visited.  Three cases:
+
+           1. it is really unreachable (in which case it cannot possibly
+              be modified any more, and the current transaction cannot
+              abort because of it)
+
+           2. it is a stolen object
+
+           3. it is not visited because it has already been modified.
         */
         if (obj->h_revision & 1) {
             /* first case: untrack it.  Note that this case can occur
@@ -637,8 +642,15 @@
             items[i] = items[--d->list_of_read_objects.size];
             /*mark*/
         }
+        else if (obj->h_tid & GCFLAG_STOLEN) {
+            /* second case: 'obj' was stolen.  Just replace it in the
+               list with its new copy, which should be identical
+               (and public, so no more processing it needed). */
+            assert(dclassify((gcptr)obj->h_revision) == K_PUBLIC);
+            items[i] = (gcptr)obj->h_revision;
+        }
         else {
-            /* second case */
+            /* third case */
             abort();//XXX
             /* ABRT_COLLECT_MINOR ... check
                for stolen object */
diff --git a/c3/test/test_nursery.py b/c3/test/test_nursery.py
--- a/c3/test/test_nursery.py
+++ b/c3/test/test_nursery.py
@@ -384,3 +384,22 @@
     assert p2 == p1
     # but now, p1 is no longer a root
     minor_collect()
+
+def test_read_from_stolen_object():
+    pg = palloc(HDR + WORD)
+    def f1(r):
+        lib.setlong(pg, 0, 519833)
+        def cb(c):
+            assert c == 0
+            p1 = lib.stm_read_barrier(pg)
+            r.wait_while_in_parallel()
+            minor_collect()
+        perform_transaction(cb)
+    def f2(r):
+        def cb(c):
+            assert c == 0
+            r.enter_in_parallel()
+            assert lib.getlong(pg, 0) == 519833    # steal object
+        perform_transaction(cb)
+        r.leave_in_parallel()
+    run_parallel(f1, f2)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to