Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r101:b853700f30eb
Date: 2013-06-12 21:15 +0200
http://bitbucket.org/pypy/stmgc/changeset/b853700f30eb/

Log:    Still trying to figure out what _stm_nonrecord_barrier() should
        return to make the most sense for the tests, but I think I have it
        now.

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -120,7 +120,7 @@
               /* we update P_prev->h_revision as a shortcut */
               /* XXX check if this really gives a worse performance than only
                  doing this write occasionally based on a counter in d */
-              //P_prev->h_revision = v;  XXX re-enable!
+              P_prev->h_revision = v;
               P = (gcptr)v;
               v = ACCESS_ONCE(P->h_revision);
               if (!(v & 1))  // "is a pointer", i.e. "has a more recent rev"
@@ -229,6 +229,50 @@
     }
 }
 
+static gcptr _match_public_to_private(gcptr P, gcptr pubobj, gcptr privobj)
+{
+  while ((pubobj->h_revision & 3) == 0)
+    {
+      assert(pubobj != P);
+      pubobj = (gcptr)pubobj->h_revision;
+    }
+  if (pubobj == P)
+    {
+      assert(!(privobj->h_tid & GCFLAG_PUBLIC));
+      assert(is_private(privobj));
+      fprintf(stderr, "-public_to_private-> %p private\n", privobj);
+      return privobj;
+    }
+  return NULL;
+}
+
+static gcptr _find_public_to_private(gcptr P)
+{
+  gcptr R;
+  wlog_t *item;
+  struct tx_descriptor *d = thread_descriptor;
+
+  G2L_LOOP_FORWARD(d->public_to_private, item)
+    {
+      R = _match_public_to_private(P, item->addr, item->val);
+      if (R != NULL)
+        return R;
+
+    } G2L_LOOP_END;
+
+  long i, size = d->public_descriptor->stolen_objects.size;
+  gcptr *items = d->public_descriptor->stolen_objects.items;
+
+  for (i = 0; i < size; i += 2)
+    {
+      R = _match_public_to_private(P, items[i], items[i + 1]);
+      if (R != NULL)
+        return R;
+    }
+
+  return NULL;
+}
+
 gcptr _stm_nonrecord_barrier(gcptr P)
 {
   /* follows the logic in stm_DirectReadBarrier() */
@@ -247,6 +291,7 @@
 
   if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
     {
+      /* private too, with a backup copy */
       assert(!(P->h_revision & 1));
       fprintf(stderr, "private_from_protected\n");
       return P;
@@ -254,36 +299,27 @@
 
   if (P->h_tid & GCFLAG_PUBLIC)
     {
-      while (1)
+      fprintf(stderr, "public ");
+
+      while (v = P->h_revision, !(v & 1))
         {
+          if (v & 2)
+            {
+              gcptr L = _find_public_to_private(P);
+              if (L != NULL)
+                return L;
+              goto follow_stub;
+            }
+
+          P = (gcptr)v;
           assert(P->h_tid & GCFLAG_PUBLIC);
-          fprintf(stderr, "public ");
+          fprintf(stderr, "-> %p public ", P);
+        }
 
-          wlog_t *item;
-          gcptr L;
-          G2L_FIND(d->public_to_private, P, item, goto no_private_obj);
+      gcptr L = _find_public_to_private(P);
+      if (L != NULL)
+        return L;
 
-          L = item->val;
-        found_in_stolen_objects:
-          assert(P->h_tid & GCFLAG_PUBLIC_TO_PRIVATE);
-          assert(!(L->h_tid & GCFLAG_PUBLIC));
-          assert(is_private(L));
-          fprintf(stderr, "-public_to_private-> %p private\n", L);
-          return L;
-
-        no_private_obj:;
-          L = _stm_find_stolen_objects(d, P);
-          if (L != NULL)
-            goto found_in_stolen_objects;
-
-          v = ACCESS_ONCE(P->h_revision);
-          if (v & 1)
-            break;
-          if (v & 2)
-            goto follow_stub;
-          P = (gcptr)v;
-          fprintf(stderr, "-> %p ", P);
-        }
       if (UNLIKELY(v > d->start_time))
         {
           fprintf(stderr, "too recent!\n");
@@ -312,6 +348,11 @@
           P = (gcptr)P->h_revision;     /* the backup copy */
           fprintf(stderr, "-backup-> %p ", P);
         }
+      if (!(P->h_tid & GCFLAG_PUBLIC))
+        {
+          fprintf(stderr, "protected by someone else!\n");
+          return (gcptr)-1;
+        }
     }
   goto restart_all;
 }
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -564,3 +564,5 @@
     r = p.h_revision
     assert (r % 4) == 0
     return ffi.cast("gcptr", r)
+
+nrb_protected = ffi.cast("gcptr", -1)
diff --git a/c4/test/test_et.py b/c4/test/test_et.py
--- a/c4/test/test_et.py
+++ b/c4/test/test_et.py
@@ -2,7 +2,7 @@
 from support import *
 
 
-SHORTCUT = False   # XXXXXXXXXXXXXXXXX
+SHORTCUT = True
 
 
 def setup_function(f):
diff --git a/c4/test/test_random.py b/c4/test/test_random.py
--- a/c4/test/test_random.py
+++ b/c4/test/test_random.py
@@ -214,14 +214,17 @@
             ptr = self.nonrecord_barrier(p.ptr)
             has_private_copy = p.obj in self.current_rev.content
             if has_private_copy:
-                assert ptr != ffi.NULL and self.is_private(ptr)
+                assert ptr != ffi.NULL and ptr != nrb_protected
+                assert self.is_private(ptr)
                 content = self.current_rev.content[p.obj]
             else:
                 try:
                     content = self.current_rev._try_read(p.obj)
                 except model.Deleted:
-                    assert ptr == ffi.NULL
+                    assert ptr == ffi.NULL or ptr == nrb_protected
                     continue
+                if ptr == nrb_protected:
+                    continue    # not much we can do
                 assert ptr != ffi.NULL and not self.is_private(ptr)
 
             self.check_not_free(ptr)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to