[pypy-commit] stmgc contention-counter: add contention counters on objects for experimentation

Raemi noreply at buildbot.pypy.org
Wed Dec 11 11:11:19 CET 2013


Author: Remi Meier <remi.meier at gmail.com>
Branch: contention-counter
Changeset: r555:83115a1bcd67
Date: 2013-12-11 11:10 +0100
http://bitbucket.org/pypy/stmgc/changeset/83115a1bcd67/

Log:	add contention counters on objects for experimentation

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -94,6 +94,41 @@
   fxcache_clear(&thread_descriptor->recent_reads_cache);
 }
 
+
+/************************************************************/
+/* CONTENTION COUNTER THINGS */
+#define RPY_STM_CONT_RMA_SAMPLES 64
+
+void abort_because_of(gcptr L) 
+{
+  gcptr obj = (gcptr)L->h_original;
+  if (!obj || (L->h_tid & GCFLAG_PREBUILT_ORIGINAL)) {
+    obj = L;
+
+    /* abort-object should never be a priv_from_prot
+       *without* an original */
+    assert(!(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
+  }
+
+  //g->h_contention += (g->h_contention + 1) << 2;
+  revision_t old =  (RPY_STM_CONT_RMA_SAMPLES - 1) * obj->h_contention;
+  old += 1000000;
+  obj->h_contention = old / RPY_STM_CONT_RMA_SAMPLES 
+    + ((old % RPY_STM_CONT_RMA_SAMPLES) != 0);
+}
+
+void commit_object(gcptr L)
+{
+  gcptr obj = L;
+  if (!(L->h_tid & GCFLAG_PREBUILT_ORIGINAL) && L->h_original)
+    obj = (gcptr)L->h_original;
+
+  revision_t old = obj->h_contention;
+  revision_t old_rma = (RPY_STM_CONT_RMA_SAMPLES - 1) * old;
+  old_rma += old >> 2;
+  obj->h_contention = old_rma / RPY_STM_CONT_RMA_SAMPLES;
+}
+
 /************************************************************/
 
 static void ValidateNow(struct tx_descriptor *);
@@ -148,8 +183,10 @@
       /* check P->h_revision->h_revision: if a pointer, then it means
          the backup copy has been stolen into a public object and then
          modified by some other thread.  Abort. */
-      if (IS_POINTER(((gcptr)P->h_revision)->h_revision))
+      if (IS_POINTER(((gcptr)P->h_revision)->h_revision)) {
+        abort_because_of(P);
         AbortTransaction(ABRT_STOLEN_MODIFIED);
+      }
 
       goto add_in_recent_reads_cache;
     }
@@ -830,6 +867,7 @@
             {
               dprintf(("validation failed: "
                        "%p has a more recent revision\n", R));
+              abort_because_of(R);
               return 0;
             }
         }
@@ -865,6 +903,7 @@
                   */
                   dprintf(("validation failed: "
                            "%p is locked by another thread\n", R));
+                  abort_because_of(R);
                   return 0;
                 }
             }
@@ -1157,6 +1196,7 @@
       if (IS_POINTER(v))     /* "has a more recent revision" */
         {
           assert(v != 0);
+          abort_because_of(R);
           AbortTransaction(ABRT_COMMIT);
         }
       if (v >= LOCKED)         // already locked by someone else
@@ -1343,7 +1383,7 @@
           gcptrlist_insert(&stm_prebuilt_gcroots, R);
           pthread_mutex_unlock(&mutex_prebuilt_gcroots);
         }
-
+      commit_object(R);
     } G2L_LOOP_END;
 
   g2l_clear(&d->public_to_private);
@@ -1383,8 +1423,10 @@
           while (1)
             {
               revision_t v = ACCESS_ONCE(B->h_revision);
-              if (IS_POINTER(v))    /* "was modified" */
+              if (IS_POINTER(v)) {   /* "was modified" */
+                abort_because_of(P);
                 AbortTransaction(ABRT_STOLEN_MODIFIED);
+              }
 
               if (bool_cas(&B->h_revision, v, (revision_t)P))
                 break;
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -758,6 +758,7 @@
             /* has a more recent revision.  Oups. */
             dprintf(("ABRT_COLLECT_MAJOR %p: "
                      "%p was read but modified already\n", d, obj));
+            abort_because_of(obj);
             AbortTransactionAfterCollect(d, ABRT_COLLECT_MAJOR);
             /* fix_list_of_read_objects should not run */
             gcptrlist_clear(&d->list_of_read_objects);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -368,6 +368,7 @@
             */
             dprintf(("public_to_young: %p was modified! abort!\n", P));
             item->val = NULL;
+            abort_because_of(P);
             AbortTransactionAfterCollect(d, ABRT_COLLECT_MINOR);
             continue;
         }
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -12,6 +12,7 @@
     revision_t h_tid;
     revision_t h_revision;
     revision_t h_original;
+    revision_t h_contention;
 } *gcptr;
 
 


More information about the pypy-commit mailing list