include spark counters in the sparks trace class
[ghc.git] / rts / Trace.h
index 6209156..34efdf6 100644 (file)
@@ -31,6 +31,13 @@ void resetTracing (void);
 
 #endif /* TRACING */
 
+typedef StgWord32 CapsetID;
+typedef StgWord16 CapsetType;
+enum CapsetType { CapsetTypeCustom = CAPSET_TYPE_CUSTOM,
+                  CapsetTypeOsProcess = CAPSET_TYPE_OSPROCESS,
+                  CapsetTypeClockdomain = CAPSET_TYPE_CLOCKDOMAIN };
+#define CAPSET_OSPROCESS_DEFAULT 0
+
 // -----------------------------------------------------------------------------
 // Message classes
 // -----------------------------------------------------------------------------
@@ -55,6 +62,7 @@ extern int DEBUG_sparks;
 
 // events
 extern int TRACE_sched;
+extern int TRACE_spark;
 
 // -----------------------------------------------------------------------------
 // Posting events
@@ -86,6 +94,11 @@ void traceEnd (void);
         traceSchedEvent_(cap, tag, tso, info1, info2); \
     }
 
+#define traceSparkEvent(cap, tag, tso, other)   \
+    if (RTS_UNLIKELY(TRACE_spark)) {            \
+        traceSchedEvent_(cap, tag, tso, other, 0); \
+    }
+
 void traceSchedEvent_ (Capability *cap, EventTypeNum tag, 
                        StgTSO *tso, StgWord info1, StgWord info2);
 
@@ -160,16 +173,42 @@ void traceUserMsg(Capability *cap, char *msg);
 
 void traceThreadStatus_ (StgTSO *tso);
 
+void traceEventStartup_ (int n_caps);
+
+/*
+ * Events for describing capability sets in the eventlog
+ *
+ * Note: unlike other events, these are not conditional on TRACE_sched or
+ * similar because they are not "real" events themselves but provide
+ * information and context for other "real" events. Other events depend on
+ * the capset info events so for simplicity, rather than working out if
+ * they're necessary we always emit them. They should be very low volume.
+ */
+void traceCapsetModify_ (EventTypeNum tag,
+                         CapsetID capset,
+                         StgWord32 other);
+
+void traceOSProcessInfo_ (void);
+
+void traceSparkCounters_ (Capability *cap,
+                          SparkCounters counters,
+                          StgWord remaining);
+
 #else /* !TRACING */
 
 #define traceSchedEvent(cap, tag, tso, other) /* nothing */
 #define traceSchedEvent2(cap, tag, tso, other, info) /* nothing */
+#define traceSparkEvent(cap, tag, tso, other) /* nothing */
 #define traceEvent(cap, tag) /* nothing */
 #define traceCap(class, cap, msg, ...) /* nothing */
 #define trace(class, msg, ...) /* nothing */
 #define debugTrace(class, str, ...) /* nothing */
 #define debugTraceCap(class, cap, str, ...) /* nothing */
 #define traceThreadStatus(class, tso) /* nothing */
+INLINE_HEADER void traceEventStartup_ (int n_caps STG_UNUSED) {};
+#define traceCapsetModify_(tag, capset, other) /* nothing */
+#define traceOSProcessInfo_() /* nothing */
+#define traceSparkCounters_(cap, counters, remaining) /* nothing */
 
 #endif /* TRACING */
 
@@ -216,8 +255,9 @@ void dtraceUserMsgWrapper(Capability *cap, char *msg);
     HASKELLEVENT_REQUEST_PAR_GC(cap)
 #define dtraceCreateSparkThread(cap, spark_tid)         \
     HASKELLEVENT_CREATE_SPARK_THREAD(cap, spark_tid)
-#define dtraceStartup(num_caps)                         \
-    HASKELLEVENT_STARTUP(num_caps)
+INLINE_HEADER void dtraceStartup (int num_caps) {
+    HASKELLEVENT_STARTUP(num_caps);
+}
 #define dtraceUserMsg(cap, msg)                         \
     HASKELLEVENT_USER_MSG(cap, msg)
 #define dtraceGcIdle(cap)                               \
@@ -226,6 +266,16 @@ void dtraceUserMsgWrapper(Capability *cap, char *msg);
     HASKELLEVENT_GC_WORK(cap)
 #define dtraceGcDone(cap)                               \
     HASKELLEVENT_GC_DONE(cap)
+#define dtraceCapsetCreate(capset, capset_type)         \
+    HASKELLEVENT_CAPSET_CREATE(capset, capset_type)
+#define dtraceCapsetDelete(capset)                      \
+    HASKELLEVENT_CAPSET_DELETE(capset)
+#define dtraceCapsetAssignCap(capset, capno)            \
+    HASKELLEVENT_CAPSET_ASSIGN_CAP(capset, capno)
+#define dtraceCapsetRemoveCap(capset, capno)            \
+    HASKELLEVENT_CAPSET_REMOVE_CAP(capset, capno)
+#define dtraceSparkCounters(cap, a, b, c, d, e, f, g) \
+    HASKELLEVENT_SPARK_COUNTERS(cap, a, b, c, d, e, f, g)
 
 #else /* !defined(DTRACE) */
 
@@ -243,11 +293,16 @@ void dtraceUserMsgWrapper(Capability *cap, char *msg);
 #define dtraceRequestSeqGc(cap)                         /* nothing */
 #define dtraceRequestParGc(cap)                         /* nothing */
 #define dtraceCreateSparkThread(cap, spark_tid)         /* nothing */
-#define dtraceStartup(num_caps)                         /* nothing */
+INLINE_HEADER void dtraceStartup (int num_caps STG_UNUSED) {};
 #define dtraceUserMsg(cap, msg)                         /* nothing */
 #define dtraceGcIdle(cap)                               /* nothing */
 #define dtraceGcWork(cap)                               /* nothing */
 #define dtraceGcDone(cap)                               /* nothing */
+#define dtraceCapsetCreate(capset, capset_type)         /* nothing */
+#define dtraceCapsetDelete(capset)                      /* nothing */
+#define dtraceCapsetAssignCap(capset, capno)            /* nothing */
+#define dtraceCapsetRemoveCap(capset, capno)            /* nothing */
+#define dtraceSparkCounters(cap, a, b, c, d, e, f, g)   /* nothing */
 
 #endif
 
@@ -312,22 +367,6 @@ INLINE_HEADER void traceEventMigrateThread(Capability *cap     STG_UNUSED,
                         (EventCapNo)new_cap);
 }
 
-INLINE_HEADER void traceEventRunSpark(Capability *cap STG_UNUSED, 
-                                      StgTSO     *tso STG_UNUSED)
-{
-    traceSchedEvent(cap, EVENT_RUN_SPARK, tso, 0);
-    dtraceRunSpark((EventCapNo)cap->no, (EventThreadID)tso->id);
-}
-
-INLINE_HEADER void traceEventStealSpark(Capability *cap        STG_UNUSED, 
-                                        StgTSO     *tso        STG_UNUSED,
-                                        nat         victim_cap STG_UNUSED)
-{
-    traceSchedEvent(cap, EVENT_STEAL_SPARK, tso, victim_cap);
-    dtraceStealSpark((EventCapNo)cap->no, (EventThreadID)tso->id,
-                     (EventCapNo)victim_cap);
-}
-
 INLINE_HEADER void traceEventShutdown(Capability *cap STG_UNUSED)
 {
     traceSchedEvent(cap, EVENT_SHUTDOWN, 0, 0);
@@ -367,24 +406,41 @@ INLINE_HEADER void traceEventRequestParGc(Capability *cap STG_UNUSED)
     dtraceRequestParGc((EventCapNo)cap->no);
 }
 
+INLINE_HEADER void traceEventRunSpark(Capability *cap STG_UNUSED, 
+                                      StgTSO     *tso STG_UNUSED)
+{
+    traceSparkEvent(cap, EVENT_RUN_SPARK, tso, 0);
+    dtraceRunSpark((EventCapNo)cap->no, (EventThreadID)tso->id);
+}
+
+INLINE_HEADER void traceEventStealSpark(Capability *cap        STG_UNUSED, 
+                                        StgTSO     *tso        STG_UNUSED,
+                                        nat         victim_cap STG_UNUSED)
+{
+    traceSparkEvent(cap, EVENT_STEAL_SPARK, tso, victim_cap);
+    dtraceStealSpark((EventCapNo)cap->no, (EventThreadID)tso->id,
+                     (EventCapNo)victim_cap);
+}
+
 INLINE_HEADER void traceEventCreateSparkThread(Capability  *cap      STG_UNUSED, 
                                                StgThreadID spark_tid STG_UNUSED)
 {
-    traceSchedEvent(cap, EVENT_CREATE_SPARK_THREAD, 0, spark_tid);
+    traceSparkEvent(cap, EVENT_CREATE_SPARK_THREAD, 0, spark_tid);
     dtraceCreateSparkThread((EventCapNo)cap->no, (EventThreadID)spark_tid);
 }
 
-// This applies only to dtrace as EVENT_STARTUP in the logging framework is
-// handled specially in 'EventLog.c'.
-//
-INLINE_HEADER void dtraceEventStartup(void)
+INLINE_HEADER void traceEventStartup(void)
 {
+    int n_caps;
 #ifdef THREADED_RTS
-    // XXX n_capabilities hasn't been initislised yet
-    dtraceStartup(RtsFlags.ParFlags.nNodes);
+    // XXX n_capabilities hasn't been initialised yet
+    n_caps = RtsFlags.ParFlags.nNodes;
 #else
-    dtraceStartup(1);
+    n_caps = 1;
 #endif
+
+    traceEventStartup_(n_caps);
+    dtraceStartup(n_caps);
 }
 
 INLINE_HEADER void traceEventGcIdle(Capability *cap STG_UNUSED)
@@ -405,6 +461,58 @@ INLINE_HEADER void traceEventGcDone(Capability *cap STG_UNUSED)
     dtraceGcDone((EventCapNo)cap->no);
 }
 
+INLINE_HEADER void traceCapsetCreate(CapsetID   capset      STG_UNUSED,
+                                     CapsetType capset_type STG_UNUSED)
+{
+    traceCapsetModify_(EVENT_CAPSET_CREATE, capset, capset_type);
+    dtraceCapsetCreate(capset, capset_type);
+}
+
+INLINE_HEADER void traceCapsetDelete(CapsetID capset STG_UNUSED)
+{
+    traceCapsetModify_(EVENT_CAPSET_DELETE, capset, 0);
+    dtraceCapsetDelete(capset);
+}
+
+INLINE_HEADER void traceCapsetAssignCap(CapsetID capset STG_UNUSED,
+                                        nat      capno  STG_UNUSED)
+{
+    traceCapsetModify_(EVENT_CAPSET_ASSIGN_CAP, capset, capno);
+    dtraceCapsetAssignCap(capset, capno);
+}
+
+INLINE_HEADER void traceCapsetRemoveCap(CapsetID capset STG_UNUSED,
+                                        nat      capno  STG_UNUSED)
+{
+    traceCapsetModify_(EVENT_CAPSET_REMOVE_CAP, capset, capno);
+    dtraceCapsetRemoveCap(capset, capno);
+}
+
+INLINE_HEADER void traceOSProcessInfo(void)
+{
+    traceOSProcessInfo_();
+    /* Note: no DTrace equivalent because all this OS process info
+     * is available to DTrace directly */
+}
+
+INLINE_HEADER void traceSparkCounters(Capability *cap STG_UNUSED)
+{
+#ifdef THREADED_RTS
+    if (RTS_UNLIKELY(TRACE_spark)) {
+        traceSparkCounters_(cap, cap->spark_stats, sparkPoolSize(cap->sparks));
+    }
+#endif
+    dtraceSparkCounters((EventCapNo)cap->no,
+                        cap->spark_stats.created,
+                        cap->spark_stats.dud,
+                        cap->spark_stats.overflowed,
+                        cap->spark_stats.converted,
+                        cap->spark_stats.gcd,
+                        cap->spark_stats.fizzled,
+                        sparkPoolSize(cap->sparks));
+}
+
+
 #include "EndPrivate.h"
 
 #endif /* TRACE_H */