1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 2006-2009
5 * Debug and performance tracing
7 * ---------------------------------------------------------------------------*/
18 #include "eventlog/EventLog.h"
23 // debugging flags, set with +RTS -D<something>
29 int DEBUG_block_alloc;
46 static Mutex trace_utx;
49 static rtsBool eventlog_enabled;
51 /* ---------------------------------------------------------------------------
52 Starting up / shuttting down the tracing facilities
53 --------------------------------------------------------------------------- */
55 void initTracing (void)
58 initMutex(&trace_utx);
62 #define DEBUG_FLAG(name, class) \
63 class = RtsFlags.DebugFlags.name ? 1 : 0;
65 DEBUG_FLAG(scheduler, DEBUG_sched);
66 DEBUG_FLAG(scheduler, TRACE_sched); // -Ds enabled all sched events
68 DEBUG_FLAG(interpreter, DEBUG_interp);
69 DEBUG_FLAG(weak, DEBUG_weak);
70 DEBUG_FLAG(gccafs, DEBUG_gccafs);
71 DEBUG_FLAG(gc, DEBUG_gc);
72 DEBUG_FLAG(block_alloc, DEBUG_block_alloc);
73 DEBUG_FLAG(sanity, DEBUG_sanity);
74 DEBUG_FLAG(stable, DEBUG_stable);
75 DEBUG_FLAG(stm, DEBUG_stm);
76 DEBUG_FLAG(prof, DEBUG_prof);
77 DEBUG_FLAG(linker, DEBUG_linker);
78 DEBUG_FLAG(squeeze, DEBUG_squeeze);
79 DEBUG_FLAG(hpc, DEBUG_hpc);
80 DEBUG_FLAG(sparks, DEBUG_sparks);
83 #define TRACE_FLAG(name, class) \
84 class = RtsFlags.TraceFlags.name ? 1 : 0;
86 TRACE_FLAG(scheduler, TRACE_sched);
88 eventlog_enabled = !RtsFlags.TraceFlags.trace_stderr && (
107 if (eventlog_enabled) {
112 void endTracing (void)
114 if (eventlog_enabled) {
119 void freeTracing (void)
121 if (eventlog_enabled) {
126 /* ---------------------------------------------------------------------------
127 Emitting trace messages/events
128 --------------------------------------------------------------------------- */
131 static void tracePreface (void)
134 debugBelch("%12lx: ", (unsigned long)osThreadId());
136 if (RtsFlags.TraceFlags.timestamp) {
137 debugBelch("%9" FMT_Word64 ": ", stat_getElapsedTime());
143 static char *thread_stop_reasons[] = {
144 [HeapOverflow] = "heap overflow",
145 [StackOverflow] = "stack overflow",
146 [ThreadYielding] = "yielding",
147 [ThreadBlocked] = "blocked",
148 [ThreadFinished] = "finished",
149 [THREAD_SUSPENDED_FOREIGN_CALL] = "suspended while making a foreign call"
154 static void traceSchedEvent_stderr (Capability *cap, EventTypeNum tag,
156 StgWord64 other STG_UNUSED)
158 ACQUIRE_LOCK(&trace_utx);
162 case EVENT_CREATE_THREAD: // (cap, thread)
163 debugBelch("cap %d: created thread %lu\n",
164 cap->no, (lnat)tso->id);
166 case EVENT_RUN_THREAD: // (cap, thread)
167 debugBelch("cap %d: running thread %lu (%s)\n",
168 cap->no, (lnat)tso->id, what_next_strs[tso->what_next]);
170 case EVENT_THREAD_RUNNABLE: // (cap, thread)
171 debugBelch("cap %d: thread %lu appended to run queue\n",
172 cap->no, (lnat)tso->id);
174 case EVENT_RUN_SPARK: // (cap, thread)
175 debugBelch("cap %d: thread %lu running a spark\n",
176 cap->no, (lnat)tso->id);
178 case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
179 debugBelch("cap %d: creating spark thread %lu\n",
180 cap->no, (long)other);
182 case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
183 debugBelch("cap %d: thread %lu migrating to cap %d\n",
184 cap->no, (lnat)tso->id, (int)other);
186 case EVENT_STEAL_SPARK: // (cap, thread, victim_cap)
187 debugBelch("cap %d: thread %lu stealing a spark from cap %d\n",
188 cap->no, (lnat)tso->id, (int)other);
190 case EVENT_THREAD_WAKEUP: // (cap, thread, other_cap)
191 debugBelch("cap %d: waking up thread %lu on cap %d\n",
192 cap->no, (lnat)tso->id, (int)other);
195 case EVENT_STOP_THREAD: // (cap, thread, status)
196 debugBelch("cap %d: thread %lu stopped (%s)\n",
197 cap->no, (lnat)tso->id, thread_stop_reasons[other]);
199 case EVENT_SHUTDOWN: // (cap)
200 debugBelch("cap %d: shutting down\n", cap->no);
202 case EVENT_REQUEST_SEQ_GC: // (cap)
203 debugBelch("cap %d: requesting sequential GC\n", cap->no);
205 case EVENT_REQUEST_PAR_GC: // (cap)
206 debugBelch("cap %d: requesting parallel GC\n", cap->no);
208 case EVENT_GC_START: // (cap)
209 debugBelch("cap %d: starting GC\n", cap->no);
211 case EVENT_GC_END: // (cap)
212 debugBelch("cap %d: finished GC\n", cap->no);
215 debugBelch("cap %2d: thread %lu: event %d\n\n",
216 cap->no, (lnat)tso->id, tag);
220 RELEASE_LOCK(&trace_utx);
224 void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
225 StgTSO *tso, StgWord64 other)
228 if (RtsFlags.TraceFlags.trace_stderr) {
229 traceSchedEvent_stderr(cap, tag, tso, other);
233 postSchedEvent(cap,tag,tso ? tso->id : 0,other);
238 static void traceCap_stderr(Capability *cap, char *msg, va_list ap)
240 ACQUIRE_LOCK(&trace_utx);
243 debugBelch("cap %2d: ", cap->no);
247 RELEASE_LOCK(&trace_utx);
251 void traceCap_(Capability *cap, char *msg, ...)
257 if (RtsFlags.TraceFlags.trace_stderr) {
258 traceCap_stderr(cap, msg, ap);
262 postCapMsg(cap, msg, ap);
269 static void trace_stderr(char *msg, va_list ap)
271 ACQUIRE_LOCK(&trace_utx);
277 RELEASE_LOCK(&trace_utx);
281 void trace_(char *msg, ...)
287 if (RtsFlags.TraceFlags.trace_stderr) {
288 trace_stderr(msg, ap);
298 void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG)
301 if (RtsFlags.TraceFlags.trace_stderr) {
302 printThreadStatus(tso);
306 /* nothing - no event for this one yet */
312 void traceBegin (const char *str, ...)
317 ACQUIRE_LOCK(&trace_utx);
326 RELEASE_LOCK(&trace_utx);