fix #3910
[ghc-hetmet.git] / rts / Trace.c
index 7194651..53fc25a 100644 (file)
@@ -9,22 +9,46 @@
 // external headers
 #include "Rts.h"
 
-#ifdef TRACING
-
 // internal headers
 #include "Trace.h"
+
+#ifdef TRACING
+
 #include "GetTime.h"
 #include "Stats.h"
 #include "eventlog/EventLog.h"
 #include "Threads.h"
 #include "Printer.h"
 
-StgWord32 classes_enabled; // not static due to inline funcs
+#ifdef DEBUG
+// debugging flags, set with +RTS -D<something>
+int DEBUG_sched;
+int DEBUG_interp;
+int DEBUG_weak;
+int DEBUG_gccafs;
+int DEBUG_gc;
+int DEBUG_block_alloc;
+int DEBUG_sanity;
+int DEBUG_stable;
+int DEBUG_stm;
+int DEBUG_prof;
+int DEBUG_gran;
+int DEBUG_par;
+int DEBUG_linker;
+int DEBUG_squeeze;
+int DEBUG_hpc;
+int DEBUG_sparks;
+#endif
+
+// events
+int TRACE_sched;
 
 #ifdef THREADED_RTS
 static Mutex trace_utx;
 #endif
 
+static rtsBool eventlog_enabled;
+
 /* ---------------------------------------------------------------------------
    Starting up / shuttting down the tracing facilities
  --------------------------------------------------------------------------- */
@@ -37,10 +61,9 @@ void initTracing (void)
 
 #ifdef DEBUG
 #define DEBUG_FLAG(name, class) \
-    if (RtsFlags.DebugFlags.name) classes_enabled |= class;
+    class = RtsFlags.DebugFlags.name ? 1 : 0;
 
     DEBUG_FLAG(scheduler,    DEBUG_sched);
-    DEBUG_FLAG(scheduler,    TRACE_sched); // -Ds enabled all sched events
 
     DEBUG_FLAG(interpreter,  DEBUG_interp);
     DEBUG_FLAG(weak,         DEBUG_weak);
@@ -57,22 +80,38 @@ void initTracing (void)
     DEBUG_FLAG(sparks,       DEBUG_sparks);
 #endif
 
-#define TRACE_FLAG(name, class) \
-    if (RtsFlags.TraceFlags.name) classes_enabled |= class;
+    // -Ds turns on scheduler tracing too
+    TRACE_sched =
+        RtsFlags.TraceFlags.scheduler ||
+        RtsFlags.DebugFlags.scheduler;
 
-    TRACE_FLAG(scheduler, TRACE_sched);
+    eventlog_enabled = RtsFlags.TraceFlags.tracing == TRACE_EVENTLOG;
 
-    initEventLogging();
+    if (eventlog_enabled) {
+        initEventLogging();
+    }
 }
 
 void endTracing (void)
 {
-    endEventLogging();
+    if (eventlog_enabled) {
+        endEventLogging();
+    }
 }
 
 void freeTracing (void)
 {
-    freeEventLogging();
+    if (eventlog_enabled) {
+        freeEventLogging();
+    }
+}
+
+void resetTracing (void)
+{
+    if (eventlog_enabled) {
+        abortEventLogging(); // abort eventlog inherited from parent
+        initEventLogging(); // child starts its own eventlog
+    }
 }
 
 /* ---------------------------------------------------------------------------
@@ -163,8 +202,17 @@ static void traceSchedEvent_stderr (Capability *cap, EventTypeNum tag,
     case EVENT_GC_END:          // (cap)
         debugBelch("cap %d: finished GC\n", cap->no);
         break;
+    case EVENT_GC_IDLE:        // (cap)
+        debugBelch("cap %d: GC idle\n", cap->no);
+        break;
+    case EVENT_GC_WORK:          // (cap)
+        debugBelch("cap %d: GC working\n", cap->no);
+        break;
+    case EVENT_GC_DONE:          // (cap)
+        debugBelch("cap %d: GC done\n", cap->no);
+        break;
     default:
-        debugBelch("cap %2d: thread %lu: event %d\n\n", 
+        debugBelch("cap %d: thread %lu: event %d\n\n", 
                    cap->no, (lnat)tso->id, tag);
         break;
     }
@@ -177,7 +225,7 @@ void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
                       StgTSO *tso, StgWord64 other)
 {
 #ifdef DEBUG
-    if (RtsFlags.TraceFlags.trace_stderr) {
+    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
         traceSchedEvent_stderr(cap, tag, tso, other);
     } else
 #endif
@@ -186,13 +234,25 @@ void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
     }
 }
 
+void traceEvent_ (Capability *cap, EventTypeNum tag)
+{
+#ifdef DEBUG
+    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
+        traceSchedEvent_stderr(cap, tag, 0, 0);
+    } else
+#endif
+    {
+        postEvent(cap,tag);
+    }
+}
+
 #ifdef DEBUG
 static void traceCap_stderr(Capability *cap, char *msg, va_list ap)
 {
     ACQUIRE_LOCK(&trace_utx);
 
     tracePreface();
-    debugBelch("cap %2d: ", cap->no);
+    debugBelch("cap %d: ", cap->no);
     vdebugBelch(msg,ap);
     debugBelch("\n");
 
@@ -200,16 +260,21 @@ static void traceCap_stderr(Capability *cap, char *msg, va_list ap)
 }
 #endif
 
-void traceCap_(Capability *cap, char *msg, va_list ap)
+void traceCap_(Capability *cap, char *msg, ...)
 {
+    va_list ap;
+    va_start(ap,msg);
+    
 #ifdef DEBUG
-    if (RtsFlags.TraceFlags.trace_stderr) {
+    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
         traceCap_stderr(cap, msg, ap);
     } else
 #endif
     {
         postCapMsg(cap, msg, ap);
     }
+
+    va_end(ap);
 }
 
 #ifdef DEBUG
@@ -225,22 +290,50 @@ static void trace_stderr(char *msg, va_list ap)
 }
 #endif
 
-void trace_(char *msg, va_list ap)
+void trace_(char *msg, ...)
 {
+    va_list ap;
+    va_start(ap,msg);
+
 #ifdef DEBUG
-    if (RtsFlags.TraceFlags.trace_stderr) {
+    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
         trace_stderr(msg, ap);
     } else
 #endif
     {
         postMsg(msg, ap);
     }
+
+    va_end(ap);
+}
+
+static void traceFormatUserMsg(Capability *cap, char *msg, ...)
+{
+    va_list ap;
+    va_start(ap,msg);
+
+#ifdef DEBUG
+    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
+        traceCap_stderr(cap, msg, ap);
+    } else
+#endif
+    {
+        if (eventlog_enabled) {
+            postUserMsg(cap, msg, ap);
+        }
+    }
+    dtraceUserMsg(cap->no, msg);
+}
+
+void traceUserMsg(Capability *cap, char *msg)
+{
+    traceFormatUserMsg(cap, "%s", msg);
 }
 
 void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG)
 {
 #ifdef DEBUG
-    if (RtsFlags.TraceFlags.trace_stderr) {
+    if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
         printThreadStatus(tso);
     } else
 #endif
@@ -270,3 +363,15 @@ void traceEnd (void)
 #endif /* DEBUG */
 
 #endif /* TRACING */
+
+// If DTRACE is enabled, but neither DEBUG nor TRACING, we need a C land
+// wrapper for the user-msg probe (as we can't expand that in PrimOps.cmm)
+//
+#if !defined(DEBUG) && !defined(TRACING) && defined(DTRACE)
+
+void dtraceUserMsgWrapper(Capability *cap, char *msg)
+{
+    dtraceUserMsg(cap->no, msg);
+}
+
+#endif /* !defined(DEBUG) && !defined(TRACING) && defined(DTRACE) */