[pypy-commit] stmgc default: Read barriers through handle objects.

arigo noreply at buildbot.pypy.org
Wed Jun 5 21:03:22 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r76:69fa4d0304c6
Date: 2013-06-05 21:03 +0200
http://bitbucket.org/pypy/stmgc/changeset/69fa4d0304c6/

Log:	Read barriers through handle objects.

diff --git a/c3/et.c b/c3/et.c
--- a/c3/et.c
+++ b/c3/et.c
@@ -89,22 +89,18 @@
 {
   struct tx_descriptor *d = thread_descriptor;
   gcptr P = G;
+  revision_t v;
 
   if (P->h_tid & GCFLAG_PUBLIC)
     {
       /* follow the chained list of h_revision's as long as they are
          regular pointers */
-      revision_t v;
-
     retry:
       v = ACCESS_ONCE(P->h_revision);
       if (!(v & 1))  // "is a pointer", i.e.
         {            //      "has a more recent revision"
           if (v & 2)
-            {
-            old_to_young:
-              abort();
-            }
+            goto old_to_young;
           assert(P->h_tid & GCFLAG_PUBLIC);
 
           gcptr P_prev = P;
@@ -162,9 +158,42 @@
     {
       fprintf(stderr, "read_barrier: %p -> %p protected\n", G, P);
     }
+
+ register_in_list_of_read_objects:
   fxcache_add(&d->recent_reads_cache, P);
   gcptrlist_insert(&d->list_of_read_objects, P);
   return P;
+
+ old_to_young:;
+  revision_t target_lock;
+  target_lock = *(revision_t *)(v & ~(HANDLE_BLOCK_SIZE-1));
+  if (target_lock == d->my_lock)
+    {
+      P = (gcptr)(*(revision_t *)(v - 2));
+      assert(!(P->h_tid & GCFLAG_PUBLIC));
+      if (P->h_revision == stm_private_rev_num)
+        {
+          fprintf(stderr, "read_barrier: %p -> %p handle "
+                  "private\n", G, P);
+          return P;
+        }
+      else if (FXCACHE_AT(P) == P)
+        {
+          fprintf(stderr, "read_barrier: %p -> %p handle "
+                  "protected fxcache\n", G, P);
+          return P;
+        }
+      else
+        {
+          fprintf(stderr, "read_barrier: %p -> %p handle "
+                  "protected\n", G, P);
+          goto register_in_list_of_read_objects;
+        }
+    }
+  else
+    {
+      abort();   // stealing
+    }
 }
 
 static gcptr _latest_gcptr(gcptr R)
diff --git a/c3/test/test_et.py b/c3/test/test_et.py
--- a/c3/test/test_et.py
+++ b/c3/test/test_et.py
@@ -191,3 +191,35 @@
     p3 = lib.stm_read_barrier(p)
     assert p3 == p2
     assert list_of_read_objects() == [p]
+
+def test_read_barrier_handle_protected():
+    p = palloc(HDR)
+    p2 = lib.stm_write_barrier(p)
+    lib.stm_commit_transaction()
+    lib.stm_begin_inevitable_transaction()
+    assert classify(p) == "public"
+    assert classify(p2) == "protected"
+    assert list_of_read_objects() == []
+    p3 = lib.stm_read_barrier(p)
+    assert p3 == p2
+    assert list_of_read_objects() == [p2]
+    p4 = lib.stm_read_barrier(p)
+    assert p4 == p2
+    assert list_of_read_objects() == [p2]
+
+def test_read_barrier_handle_private():
+    p = palloc(HDR)
+    p2 = lib.stm_write_barrier(p)
+    lib.stm_commit_transaction()
+    lib.stm_begin_inevitable_transaction()
+    p2b = lib.stm_write_barrier(p)
+    assert p2b == p2
+    assert classify(p) == "public"
+    assert classify(p2) == "private"
+    assert list_of_read_objects() == [p2]
+    p3 = lib.stm_read_barrier(p)
+    assert p3 == p2
+    assert list_of_read_objects() == [p2]
+    p4 = lib.stm_read_barrier(p)
+    assert p4 == p2
+    assert list_of_read_objects() == [p2]


More information about the pypy-commit mailing list