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

Log:    Test and implementation of another "abort();//XXX".

diff --git a/c3/et.c b/c3/et.c
--- a/c3/et.c
+++ b/c3/et.c
@@ -513,7 +513,7 @@
 {
   if (d->active >= 0)
     {
-      assert(d->active == 1);
+      assert(d->active == 1);   /* not 2, which means inevitable */
       d->active = -reason;
     }
   assert(d->active < 0);
@@ -523,7 +523,11 @@
 {
   struct tx_descriptor *d = thread_descriptor;
   if (d->active < 0)
-    AbortTransaction(-d->active);
+    {
+      int reason = -d->active;
+      d->active = 1;
+      AbortTransaction(reason);
+    }
 }
 
 /************************************************************/
diff --git a/c3/nursery.c b/c3/nursery.c
--- a/c3/nursery.c
+++ b/c3/nursery.c
@@ -634,6 +634,7 @@
            2. it is a stolen object
 
            3. it is not visited because it has already been modified.
+              But this case cannot occur: the object is still protected
         */
         if (obj->h_revision & 1) {
             /* first case: untrack it.  Note that this case can occur
@@ -643,17 +644,29 @@
             /*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;
+            /* second case: 'obj' was stolen.  We check to see if
+               the public version was already outdated.  If not, we
+               replace 'obj' in the list with this public version,
+               which should be identical. */
+            gcptr P = (gcptr)obj->h_revision;
+            assert(dclassify(P) == K_PUBLIC);
+
+            if (P->h_revision & 1) {   /* "is not a pointer" */
+                items[i] = P;
+                /*mark*/
+            }
+            else {
+                /* P has already been changed.  Mark as abort. */
+                AbortTransactionAfterCollect(d, ABRT_COLLECT_MINOR);
+                /*mark*/
+                gcptrlist_clear(&d->list_of_read_objects);
+                break;
+            }
         }
         else {
-            /* third case */
-            abort();//XXX
-            /* ABRT_COLLECT_MINOR ... check
-               for stolen object */
+            /* third case: impossible */
+            assert(!"third case of fix_list_of_read_objects");
+            abort();
         }
     }
     d->num_read_objects_known_old = d->list_of_read_objects.size;
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
@@ -392,6 +392,7 @@
         def cb(c):
             assert c == 0
             p1 = lib.stm_read_barrier(pg)
+            assert lib.in_nursery(p1)
             r.wait_while_in_parallel()
             minor_collect()
         perform_transaction(cb)
@@ -403,3 +404,28 @@
         perform_transaction(cb)
         r.leave_in_parallel()
     run_parallel(f1, f2)
+
+def test_read_from_modified_stolen_object():
+    pg = palloc(HDR + WORD)
+    seen = []
+    def f1(r):
+        lib.setlong(pg, 0, 287221)
+        def cb(c):
+            if c == 0:
+                p1 = lib.stm_read_barrier(pg)
+                assert lib.in_nursery(p1)
+                r.wait_while_in_parallel()
+                seen.append("ok")
+                minor_collect()
+                raise AssertionError("we should not reach this!")
+            else:
+                assert seen == ["ok"]
+        perform_transaction(cb)
+    def f2(r):
+        def cb(c):
+            assert c == 0
+            r.enter_in_parallel()
+            lib.setlong(pg, 0, -66666)     # steal object
+        perform_transaction(cb)
+        r.leave_in_parallel()
+    run_parallel(f1, f2, max_aborts=1)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to