1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 2006-2009
5 * Debug and performance tracing
7 * ---------------------------------------------------------------------------*/
18 #include "eventlog/EventLog.h"
22 StgWord32 classes_enabled; // not static due to inline funcs
25 static Mutex trace_utx;
28 /* ---------------------------------------------------------------------------
29 Starting up / shuttting down the tracing facilities
30 --------------------------------------------------------------------------- */
32 void initTracing (void)
35 initMutex(&trace_utx);
39 #define DEBUG_FLAG(name, class) \
40 if (RtsFlags.DebugFlags.name) classes_enabled |= class;
42 DEBUG_FLAG(scheduler, DEBUG_sched);
43 DEBUG_FLAG(scheduler, TRACE_sched); // -Ds enabled all sched events
45 DEBUG_FLAG(interpreter, DEBUG_interp);
46 DEBUG_FLAG(weak, DEBUG_weak);
47 DEBUG_FLAG(gccafs, DEBUG_gccafs);
48 DEBUG_FLAG(gc, DEBUG_gc);
49 DEBUG_FLAG(block_alloc, DEBUG_block_alloc);
50 DEBUG_FLAG(sanity, DEBUG_sanity);
51 DEBUG_FLAG(stable, DEBUG_stable);
52 DEBUG_FLAG(stm, DEBUG_stm);
53 DEBUG_FLAG(prof, DEBUG_prof);
54 DEBUG_FLAG(linker, DEBUG_linker);
55 DEBUG_FLAG(squeeze, DEBUG_squeeze);
56 DEBUG_FLAG(hpc, DEBUG_hpc);
57 DEBUG_FLAG(sparks, DEBUG_sparks);
60 #define TRACE_FLAG(name, class) \
61 if (RtsFlags.TraceFlags.name) classes_enabled |= class;
63 TRACE_FLAG(scheduler, TRACE_sched);
68 void endTracing (void)
73 void freeTracing (void)
78 /* ---------------------------------------------------------------------------
79 Emitting trace messages/events
80 --------------------------------------------------------------------------- */
83 static void tracePreface (void)
86 debugBelch("%12lx: ", (unsigned long)osThreadId());
88 if (RtsFlags.TraceFlags.timestamp) {
89 debugBelch("%9" FMT_Word64 ": ", stat_getElapsedTime());
95 static char *thread_stop_reasons[] = {
96 [HeapOverflow] = "heap overflow",
97 [StackOverflow] = "stack overflow",
98 [ThreadYielding] = "yielding",
99 [ThreadBlocked] = "blocked",
100 [ThreadFinished] = "finished",
101 [THREAD_SUSPENDED_FOREIGN_CALL] = "suspended while making a foreign call"
106 static void traceSchedEvent_stderr (Capability *cap, EventTypeNum tag,
108 StgWord64 other STG_UNUSED)
110 ACQUIRE_LOCK(&trace_utx);
114 case EVENT_CREATE_THREAD: // (cap, thread)
115 debugBelch("cap %d: created thread %ld\n", cap->no, tso->id);
117 case EVENT_RUN_THREAD: // (cap, thread)
118 debugBelch("cap %d: running thread %ld (%s)\n", cap->no,
119 tso->id, what_next_strs[tso->what_next]);
121 case EVENT_THREAD_RUNNABLE: // (cap, thread)
122 debugBelch("cap %d: thread %ld appended to run queue\n",
125 case EVENT_RUN_SPARK: // (cap, thread)
126 debugBelch("cap %d: thread %ld running a spark\n",
129 case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
130 debugBelch("cap %d: creating spark thread %ld\n",
131 cap->no, (long)other);
133 case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
134 debugBelch("cap %d: thread %ld migrating to cap %d\n",
135 cap->no, tso->id, (int)other);
137 case EVENT_STEAL_SPARK: // (cap, thread, victim_cap)
138 debugBelch("cap %d: thread %ld stealing a spark from cap %d\n",
139 cap->no, tso->id, (int)other);
141 case EVENT_THREAD_WAKEUP: // (cap, thread, other_cap)
142 debugBelch("cap %d: waking up thread %ld on cap %d\n",
143 cap->no, tso->id, (int)other);
146 case EVENT_STOP_THREAD: // (cap, thread, status)
147 debugBelch("cap %d: thread %ld stopped (%s)\n",
148 cap->no, tso->id, thread_stop_reasons[other]);
150 case EVENT_SHUTDOWN: // (cap)
151 debugBelch("cap %d: shutting down\n", cap->no);
153 case EVENT_REQUEST_SEQ_GC: // (cap)
154 debugBelch("cap %d: requesting sequential GC\n", cap->no);
156 case EVENT_REQUEST_PAR_GC: // (cap)
157 debugBelch("cap %d: requesting parallel GC\n", cap->no);
159 case EVENT_GC_START: // (cap)
160 debugBelch("cap %d: starting GC\n", cap->no);
162 case EVENT_GC_END: // (cap)
163 debugBelch("cap %d: finished GC\n", cap->no);
166 debugBelch("cap %2d: thread %ld: event %d\n\n", cap->no, tso->id, tag);
170 RELEASE_LOCK(&trace_utx);
174 void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
175 StgTSO *tso, StgWord64 other)
178 if (RtsFlags.TraceFlags.trace_stderr) {
179 traceSchedEvent_stderr(cap, tag, tso, other);
183 postSchedEvent(cap,tag,tso ? tso->id : 0,other);
188 static void traceCap_stderr(Capability *cap, char *msg, va_list ap)
190 ACQUIRE_LOCK(&trace_utx);
193 debugBelch("cap %2d: ", cap->no);
197 RELEASE_LOCK(&trace_utx);
201 void traceCap_(Capability *cap, char *msg, va_list ap)
204 if (RtsFlags.TraceFlags.trace_stderr) {
205 traceCap_stderr(cap, msg, ap);
209 postCapMsg(cap, msg, ap);
214 static void trace_stderr(char *msg, va_list ap)
216 ACQUIRE_LOCK(&trace_utx);
222 RELEASE_LOCK(&trace_utx);
226 void trace_(char *msg, va_list ap)
229 if (RtsFlags.TraceFlags.trace_stderr) {
230 trace_stderr(msg, ap);
238 void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG)
241 if (RtsFlags.TraceFlags.trace_stderr) {
242 printThreadStatus(tso);
246 /* nothing - no event for this one yet */
252 void traceBegin (const char *str, ...)
257 ACQUIRE_LOCK(&trace_utx);
266 RELEASE_LOCK(&trace_utx);