[pypy-commit] stmgc default: Fix: dont call stmgc_duplicate() when we hold the collection_lock.

arigo noreply at buildbot.pypy.org
Sat Jun 15 22:46:43 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r139:cb8059368058
Date: 2013-06-15 22:46 +0200
http://bitbucket.org/pypy/stmgc/changeset/cb8059368058/

Log:	Fix: dont call stmgc_duplicate() when we hold the collection_lock.

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -414,7 +414,7 @@
   return P;   /* always returns its arg: the object is converted in-place */
 }
 
-static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R)
+static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R, gcptr L)
 {
   assert(R->h_tid & GCFLAG_PUBLIC);
 
@@ -427,7 +427,6 @@
 
   R->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE;
 
-  gcptr L = stmgc_duplicate(R);
   assert(!(L->h_tid & GCFLAG_BACKUP_COPY));
   assert(!(L->h_tid & GCFLAG_STUB));
   assert(!(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
@@ -472,7 +471,7 @@
       return P;
     }
 
-  gcptr R, W;
+  gcptr R, L, W;
   R = stm_read_barrier(P);
 
   if (is_private(R))
@@ -484,6 +483,13 @@
   struct tx_descriptor *d = thread_descriptor;
   assert(d->active >= 1);
 
+  L = NULL;
+  if (R->h_tid & GCFLAG_PUBLIC)
+    {
+    retry:
+      L = stmgc_duplicate(R);
+    }
+
   /* We need the collection_lock for the sequel; this is required notably
      because we're about to edit flags on a protected object.
   */
@@ -493,12 +499,19 @@
 
   if (R->h_tid & GCFLAG_PUBLIC)
     {
+      if (L == NULL)
+        {
+          /* Oups, the flags on R changed while we where waiting for
+             the collection_lock. */
+          spinlock_release(d->public_descriptor->collection_lock);
+          goto retry;
+        }
       /* Make and return a new (young) private copy of the public R.
          Add R into the list 'public_with_young_copy'.
       */
       assert(R->h_tid & GCFLAG_OLD);
       gcptrlist_insert(&d->public_with_young_copy, R);
-      W = LocalizePublic(d, R);
+      W = LocalizePublic(d, R, L);
       assert(is_private(W));
     }
   else


More information about the pypy-commit mailing list