summaryrefslogtreecommitdiff
path: root/rts/Capability.c
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2011-06-02 17:28:56 +0100
committerDuncan Coutts <duncan@well-typed.com>2011-07-18 16:31:14 +0100
commitddb47a91da7132da2303c60a5aff4e38fb2dcf1a (patch)
tree0c46f1cc36738bf769005837fd555ad772dd5a95 /rts/Capability.c
parent1be80fdb6a8e993141a3bdd4cb71cd40f693018e (diff)
downloadhaskell-ddb47a91da7132da2303c60a5aff4e38fb2dcf1a.tar.gz
Add assertion of the invariant for the spark counters
The invariant is: created = converted + remaining + gcd + fizzled Since sparks move between capabilities, we have to aggregate the counters over all capabilities. This in turn means we can only check the invariant at stable points where all but one capabilities are stopped. We can do this at shutdown time and before and after a global synchronised GC.
Diffstat (limited to 'rts/Capability.c')
-rw-r--r--rts/Capability.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/rts/Capability.c b/rts/Capability.c
index d93c9c1eda..410d3d0a9c 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -843,6 +843,10 @@ shutdownCapabilities(Task *task, rtsBool safe)
shutdownCapability(&capabilities[i], task, safe);
}
traceCapsetDelete(CAPSET_OSPROCESS_DEFAULT);
+
+#if defined(THREADED_RTS)
+ ASSERT(checkSparkCountInvariant());
+#endif
}
static void
@@ -913,3 +917,34 @@ markCapabilities (evac_fn evac, void *user)
markCapability(evac, user, &capabilities[n], rtsFalse);
}
}
+
+#if defined(THREADED_RTS)
+rtsBool checkSparkCountInvariant (void)
+{
+ SparkCounters sparks = { 0, 0, 0, 0, 0, 0 };
+ StgWord64 remaining = 0;
+ nat i;
+
+ for (i = 0; i < n_capabilities; i++) {
+ sparks.created += capabilities[i].spark_stats.created;
+ sparks.dud += capabilities[i].spark_stats.dud;
+ sparks.overflowed+= capabilities[i].spark_stats.overflowed;
+ sparks.converted += capabilities[i].spark_stats.converted;
+ sparks.gcd += capabilities[i].spark_stats.gcd;
+ sparks.fizzled += capabilities[i].spark_stats.fizzled;
+ remaining += sparkPoolSize(capabilities[i].sparks);
+ }
+
+ /* The invariant is
+ * created = converted + remaining + gcd + fizzled
+ */
+ debugTrace(DEBUG_sparks,"spark invariant: %ld == %ld + %ld + %ld + %ld "
+ "(created == converted + remaining + gcd + fizzled)",
+ sparks.created, sparks.converted, remaining,
+ sparks.gcd, sparks.fizzled);
+
+ return (sparks.created ==
+ sparks.converted + remaining + sparks.gcd + sparks.fizzled);
+
+}
+#endif