[pypy-commit] stmgc default: progress in stealing

arigo noreply at buildbot.pypy.org
Sat Jun 8 22:57:49 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r81:77e624bcbfd2
Date: 2013-06-08 22:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/77e624bcbfd2/

Log:	progress in stealing

diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -45,13 +45,23 @@
 
 void stm_steal_stub(gcptr P)
 {
-    abort();
-  struct tx_public_descriptor *foreign_pd;
-  revision_t target_descriptor_index;
-  revision_t v = ACCESS_ONCE(P->h_revision);
-  if ((v & 3) != 2)
-    return;
-  target_descriptor_index = *(revision_t *)(v & ~(STUB_BLOCK_SIZE-1));
-  foreign_pd = stm_descriptor_array[target_descriptor_index];
-  abort();
+    struct tx_public_descriptor *foreign_pd = STUB_THREAD(P);
+
+    spinlock_acquire(foreign_pd->collection_lock, 'S');   /*stealing*/
+
+    if (!(P->h_tid & GCFLAG_STUB))
+        goto done;     /* un-stubbed while we waited for the lock */
+
+    /* XXX check for now that P is a regular protected object */
+    gcptr L = (gcptr)P->h_revision;
+    gcptr Q = stmgc_duplicate(L);
+    Q->h_tid |= GCFLAG_PUBLIC;
+
+    smp_wmb();
+
+    P->h_revision = (revision_t)Q;
+    P->h_tid &= ~GCFLAG_STUB;
+
+ done:
+    spinlock_release(foreign_pd->collection_lock);
 }
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
@@ -251,6 +251,7 @@
         r.wait(2)
         p2 = lib.stm_read_barrier(p)    # steals
         assert lib.rawgetlong(p2, 0) == 2782172
+        assert p2 == lib.stm_read_barrier(p)    # short-circuit h_revision
         assert p.h_revision == int(ffi.cast("revision_t", p2))
         assert p2 == lib.stm_read_barrier(p)
         assert p2 not in plist


More information about the pypy-commit mailing list