[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