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 %lu\n",
116 cap->no, (lnat)tso->id);
118 case EVENT_RUN_THREAD: // (cap, thread)
119 debugBelch("cap %d: running thread %lu (%s)\n",
120 cap->no, (lnat)tso->id, what_next_strs[tso->what_next]);
122 case EVENT_THREAD_RUNNABLE: // (cap, thread)
123 debugBelch("cap %d: thread %lu appended to run queue\n",
124 cap->no, (lnat)tso->id);
126 case EVENT_RUN_SPARK: // (cap, thread)
127 debugBelch("cap %d: thread %lu running a spark\n",
128 cap->no, (lnat)tso->id);
130 case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
131 debugBelch("cap %d: creating spark thread %lu\n",
132 cap->no, (long)other);
134 case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
135 debugBelch("cap %d: thread %lu migrating to cap %d\n",
136 cap->no, (lnat)tso->id, (int)other);
138 case EVENT_STEAL_SPARK: // (cap, thread, victim_cap)
139 debugBelch("cap %d: thread %lu stealing a spark from cap %d\n",
140 cap->no, (lnat)tso->id, (int)other);
142 case EVENT_THREAD_WAKEUP: // (cap, thread, other_cap)
143 debugBelch("cap %d: waking up thread %lu on cap %d\n",
144 cap->no, (lnat)tso->id, (int)other);
147 case EVENT_STOP_THREAD: // (cap, thread, status)
148 debugBelch("cap %d: thread %lu stopped (%s)\n",
149 cap->no, (lnat)tso->id, thread_stop_reasons[other]);
151 case EVENT_SHUTDOWN: // (cap)
152 debugBelch("cap %d: shutting down\n", cap->no);
154 case EVENT_REQUEST_SEQ_GC: // (cap)
155 debugBelch("cap %d: requesting sequential GC\n", cap->no);
157 case EVENT_REQUEST_PAR_GC: // (cap)
158 debugBelch("cap %d: requesting parallel GC\n", cap->no);
160 case EVENT_GC_START: // (cap)
161 debugBelch("cap %d: starting GC\n", cap->no);
163 case EVENT_GC_END: // (cap)
164 debugBelch("cap %d: finished GC\n", cap->no);
167 debugBelch("cap %2d: thread %lu: event %d\n\n",
168 cap->no, (lnat)tso->id, tag);
172 RELEASE_LOCK(&trace_utx);
176 void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
177 StgTSO *tso, StgWord64 other)
180 if (RtsFlags.TraceFlags.trace_stderr) {
181 traceSchedEvent_stderr(cap, tag, tso, other);
185 postSchedEvent(cap,tag,tso ? tso->id : 0,other);
190 static void traceCap_stderr(Capability *cap, char *msg, va_list ap)
192 ACQUIRE_LOCK(&trace_utx);
195 debugBelch("cap %2d: ", cap->no);
199 RELEASE_LOCK(&trace_utx);
203 void traceCap_(Capability *cap, char *msg, va_list ap)
206 if (RtsFlags.TraceFlags.trace_stderr) {
207 traceCap_stderr(cap, msg, ap);
211 postCapMsg(cap, msg, ap);
216 static void trace_stderr(char *msg, va_list ap)
218 ACQUIRE_LOCK(&trace_utx);
224 RELEASE_LOCK(&trace_utx);
228 void trace_(char *msg, va_list ap)
231 if (RtsFlags.TraceFlags.trace_stderr) {
232 trace_stderr(msg, ap);
240 void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG)
243 if (RtsFlags.TraceFlags.trace_stderr) {
244 printThreadStatus(tso);
248 /* nothing - no event for this one yet */
254 void traceBegin (const char *str, ...)
259 ACQUIRE_LOCK(&trace_utx);
268 RELEASE_LOCK(&trace_utx);