Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r89:b63ed074b565
Date: 2013-06-10 09:26 +0200
http://bitbucket.org/pypy/stmgc/changeset/b63ed074b565/

Log:    Getting somewhere

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -129,14 +129,16 @@
 
           P = item->val;
           assert(!(P->h_tid & GCFLAG_PUBLIC));
-          assert(P->h_revision == stm_private_rev_num);
+          assert(is_private(P));
           fprintf(stderr, "read_barrier: %p -> %p public_to_private\n", G, P);
           return P;
 
         no_private_obj:
           if (d->public_descriptor->stolen_objects.size > 0)
             {
+              spinlock_acquire(d->public_descriptor->collection_lock, 'N');
               stm_normalize_stolen_objects(d);
+              spinlock_release(d->public_descriptor->collection_lock);
               goto retry_public_to_private;
             }
         }
@@ -433,11 +435,6 @@
   long i, size = d->list_of_read_objects.size;
   gcptr *items = d->list_of_read_objects.items;
 
-  if (size == 0)
-    return 1;
-  abort();
-
-#if 0
   for (i=0; i<size; i++)
     {
       gcptr R = items[i];
@@ -446,18 +443,7 @@
       v = ACCESS_ONCE(R->h_revision);
       if (!(v & 1))               // "is a pointer", i.e.
         {                         //   "has a more recent revision"
-          /* ... unless it's a protected-to-private link */
-          if (((gcptr)v)->h_revision == stm_local_revision)
-            continue;
-          /* ... or unless it is a GCFLAG_STOLEN object */
-          if (R->h_tid & GCFLAG_STOLEN)
-            {
-              assert(is_young(R));
-              assert(!is_young((gcptr)v));
-              R = (gcptr)v;
-              goto retry;
-            }
-          return 0;               // really has a more recent revision
+          return 0;
         }
       if (v >= LOCKED)            // locked
         {
@@ -475,7 +461,6 @@
         }
     }
   return 1;
-#endif
 }
 
 static void ValidateNow(struct tx_descriptor *d)
@@ -703,8 +688,11 @@
         goto retry;
 
       gcptr L = item->val;
-      assert(L->h_revision == stm_private_rev_num);
+      assert(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED ?
+             L->h_revision == (revision_t)R :
+             L->h_revision == stm_private_rev_num);
       assert(v != stm_private_rev_num);
+      assert(v & 1);
       L->h_revision = v;   /* store temporarily this value here */
 
     } G2L_LOOP_END;
@@ -712,8 +700,6 @@
 
 static void CancelLocks(struct tx_descriptor *d)
 {
-  abort();
-#if 0
   revision_t my_lock = d->my_lock;
   wlog_t *item;
 
@@ -724,13 +710,20 @@
     {
       gcptr R = item->addr;
       gcptr L = item->val;
-      revision_t v = L->h_revision;
-      if (v == stm_local_revision)
+      revision_t expected, v = L->h_revision;
+
+      if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
+        expected = (revision_t)R;
+      else
+        expected = stm_private_rev_num;
+
+      if (v == expected)
         {
           assert(R->h_revision != my_lock);
           break;    /* done */
         }
-      L->h_revision = stm_local_revision;
+
+      L->h_revision = expected;
 
 #ifdef DUMP_EXTRA
       fprintf(stderr, "%p->h_revision = %p (CancelLocks)\n", R, (gcptr)v);
@@ -739,7 +732,6 @@
       ACCESS_ONCE(R->h_revision) = v;
 
     } G2L_LOOP_END;
-#endif
 }
 
 //static pthread_mutex_t mutex_prebuilt_gcroots = PTHREAD_MUTEX_INITIALIZER;
@@ -812,27 +804,6 @@
   g2l_clear(&d->public_to_private);
 }
 
-#if 0
-void UpdateProtectedChainHeads(struct tx_descriptor *d, revision_t cur_time,
-                               revision_t localrev)
-{
-  revision_t new_revision = cur_time + 1;     // make an odd number
-  assert(new_revision & 1);
-
-  long i, size = d->protected_with_private_copy.size;
-  gcptr *items = d->protected_with_private_copy.items;
-  for (i = 0; i < size; i++)
-    {
-      gcptr R = items[i];
-      if (R->h_tid & GCFLAG_STOLEN)       /* ignore stolen objects */
-        continue;
-      gcptr L = (gcptr)R->h_revision;
-      assert(L->h_revision == localrev);
-      L->h_revision = new_revision;
-    }
-}
-#endif
-
 void CommitPrivateFromProtected(struct tx_descriptor *d, revision_t cur_time)
 {
   long i, size = d->private_from_protected.size;
@@ -841,12 +812,19 @@
   for (i = 0; i < size; i++)
     {
       gcptr P = items[i];
-
-      assert(!(P->h_revision & 1));   // "is a pointer"
-      gcptr B = (gcptr)P->h_revision;
-
       assert(P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
       P->h_tid &= ~GCFLAG_PRIVATE_FROM_PROTECTED;
+
+      if (P->h_revision & 1)   // "is not a pointer"
+        {
+          /* This case occurs when a GCFLAG_PRIVATE_FROM_PROTECTED object
+             is stolen: it ends up as a value in 'public_to_private'.
+             Its h_revision is then mangled by AcquireLocks(). */
+          assert(P->h_revision != stm_private_rev_num);
+          continue;
+        }
+
+      gcptr B = (gcptr)P->h_revision;
       P->h_revision = cur_time;
 
       if (B->h_tid & GCFLAG_PUBLIC)
@@ -876,10 +854,10 @@
   struct tx_descriptor *d = thread_descriptor;
   assert(d->active >= 1);
 
+  spinlock_acquire(d->public_descriptor->collection_lock, 'C');  /*committing*/
   if (d->public_descriptor->stolen_objects.size != 0)
     stm_normalize_stolen_objects(d);
 
-  spinlock_acquire(d->public_descriptor->collection_lock, 'C');  /*committing*/
   AcquireLocks(d);
 
   if (is_inevitable(d))
@@ -1219,7 +1197,7 @@
                      d->num_spinloops[i]);
 
     p += sprintf(p, "]\n");
-    fwrite(line, 1, p - line, stderr);
+    fprintf(stderr, "%s", line);
 
     stm_free(d, sizeof(struct tx_descriptor));
 }
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -58,13 +58,14 @@
     if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
         gcptr B = (gcptr)L->h_revision;     /* the backup copy */
         B->h_tid &= ~GCFLAG_BACKUP_COPY;
-        L->h_revision = *foreign_pd->descriptor->private_revision_ref;
 
         /* add {B: L} in 'public_to_private', but lazily, because we don't
            want to walk over the feet of the foreign thread */
         B->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE;
         gcptrlist_insert2(&foreign_pd->stolen_objects, B, L);
 
+        fprintf(stderr, "stolen: %p -> %p - - -> %p\n", P, B, L);
+
         L = B;
     }
 
@@ -83,17 +84,15 @@
 
 void stm_normalize_stolen_objects(struct tx_descriptor *d)
 {
-    spinlock_acquire(d->public_descriptor->collection_lock, 'N');
-
     long i, size = d->public_descriptor->stolen_objects.size;
     gcptr *items = d->public_descriptor->stolen_objects.items;
 
     for (i = 0; i < size; i += 2) {
         gcptr B = items[i];
         gcptr L = items[i + 1];
+
+        assert(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
         g2l_insert(&d->public_to_private, B, L);
     }
     gcptrlist_clear(&d->public_descriptor->stolen_objects);
-
-    spinlock_release(d->public_descriptor->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
@@ -236,6 +236,7 @@
         assert classify(p) == "public"
         assert classify(p1) == "private"
         lib.rawsetlong(p1, 0, 2782172)
+        pback_ = []
 
         def cb(c):
             assert c == 0
@@ -246,6 +247,7 @@
             assert p2 == p1
             lib.rawsetlong(p2, 0, -451112)
             pback = follow_revision(p1)
+            pback_.append(pback)
             assert classify(p1) == "private"
             assert classify(pback) == "backup"
             assert lib.stm_read_barrier(p) == p1
@@ -263,11 +265,12 @@
 
         lib.stm_commit_transaction()
         lib.stm_begin_inevitable_transaction()
+        [pback] = pback_
         assert classify(p1) == "protected"
         assert classify(pback) == "public"
         assert classify(follow_revision(pback)) == "stub"
         assert follow_revision(pback).h_revision == (
-            ffi.cast("revision_t", p1) | 2)
+            int(ffi.cast("revision_t", p1)) | 2)
 
     def f2(r):
         def cb(c):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to