+ ACQUIRE_LOCK(&trace_utx);
+
+ tracePreface();
+ switch (tag) {
+ case EVENT_CREATE_THREAD: // (cap, thread)
+ debugBelch("cap %d: created thread %lu\n",
+ cap->no, (lnat)tso->id);
+ break;
+ case EVENT_RUN_THREAD: // (cap, thread)
+ debugBelch("cap %d: running thread %lu (%s)\n",
+ cap->no, (lnat)tso->id, what_next_strs[tso->what_next]);
+ break;
+ case EVENT_THREAD_RUNNABLE: // (cap, thread)
+ debugBelch("cap %d: thread %lu appended to run queue\n",
+ cap->no, (lnat)tso->id);
+ break;
+ case EVENT_RUN_SPARK: // (cap, thread)
+ debugBelch("cap %d: thread %lu running a spark\n",
+ cap->no, (lnat)tso->id);
+ break;
+ case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
+ debugBelch("cap %d: creating spark thread %lu\n",
+ cap->no, (long)info1);
+ break;
+ case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
+ debugBelch("cap %d: thread %lu migrating to cap %d\n",
+ cap->no, (lnat)tso->id, (int)info1);
+ break;
+ case EVENT_STEAL_SPARK: // (cap, thread, victim_cap)
+ debugBelch("cap %d: thread %lu stealing a spark from cap %d\n",
+ cap->no, (lnat)tso->id, (int)info1);
+ break;
+ case EVENT_THREAD_WAKEUP: // (cap, thread, info1_cap)
+ debugBelch("cap %d: waking up thread %lu on cap %d\n",
+ cap->no, (lnat)tso->id, (int)info1);
+ break;
+
+ case EVENT_STOP_THREAD: // (cap, thread, status)
+ if (info1 == 6 + BlockedOnBlackHole) {
+ debugBelch("cap %d: thread %lu stopped (blocked on black hole owned by thread %lu)\n",
+ cap->no, (lnat)tso->id, (long)info2);
+ } else {
+ debugBelch("cap %d: thread %lu stopped (%s)\n",
+ cap->no, (lnat)tso->id, thread_stop_reasons[info1]);
+ }
+ break;
+ case EVENT_SHUTDOWN: // (cap)
+ debugBelch("cap %d: shutting down\n", cap->no);
+ break;
+ case EVENT_REQUEST_SEQ_GC: // (cap)
+ debugBelch("cap %d: requesting sequential GC\n", cap->no);
+ break;
+ case EVENT_REQUEST_PAR_GC: // (cap)
+ debugBelch("cap %d: requesting parallel GC\n", cap->no);
+ break;
+ case EVENT_GC_START: // (cap)
+ debugBelch("cap %d: starting GC\n", cap->no);
+ break;
+ 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 %d: thread %lu: event %d\n\n",
+ cap->no, (lnat)tso->id, tag);
+ break;
+ }
+
+ RELEASE_LOCK(&trace_utx);
+}
+#endif
+
+void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
+ StgTSO *tso, StgWord info1, StgWord info2)
+{
+#ifdef DEBUG
+ if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
+ traceSchedEvent_stderr(cap, tag, tso, info1, info2);
+ } else
+#endif
+ {
+ postSchedEvent(cap,tag,tso ? tso->id : 0, info1, info2);
+ }
+}
+
+void traceCapsetModify_ (EventTypeNum tag,
+ CapsetID capset,
+ StgWord32 other)
+{
+#ifdef DEBUG
+ if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
+ ACQUIRE_LOCK(&trace_utx);
+
+ tracePreface();
+ switch (tag) {
+ case EVENT_CAPSET_CREATE: // (capset, capset_type)
+ debugBelch("created capset %lu of type %d\n", (lnat)capset, other);
+ break;
+ case EVENT_CAPSET_DELETE: // (capset)
+ debugBelch("deleted capset %lu\n", (lnat)capset);
+ break;
+ case EVENT_CAPSET_ASSIGN_CAP: // (capset, capno)
+ debugBelch("assigned cap %lu to capset %lu\n",
+ (lnat)other, (lnat)capset);
+ break;
+ case EVENT_CAPSET_REMOVE_CAP: // (capset, capno)
+ debugBelch("removed cap %lu from capset %lu\n",
+ (lnat)other, (lnat)capset);
+ break;
+ }
+ RELEASE_LOCK(&trace_utx);
+ } else
+#endif
+ {
+ if (eventlog_enabled) {
+ postCapsetModifyEvent(tag, capset, other);
+ }
+ }
+}
+
+void traceOSProcessInfo_(void) {
+ if (eventlog_enabled) {
+ postCapsetModifyEvent(EVENT_OSPROCESS_PID,
+ CAPSET_OSPROCESS_DEFAULT,
+ getpid());
+
+#if !defined(cygwin32_HOST_OS) && !defined (mingw32_HOST_OS)
+/* Windows has no strong concept of process heirarchy, so no getppid().
+ * In any case, this trace event is mainly useful for tracing programs
+ * that use 'forkProcess' which Windows doesn't support anyway.
+ */
+ postCapsetModifyEvent(EVENT_OSPROCESS_PPID,
+ CAPSET_OSPROCESS_DEFAULT,
+ getppid());
+#endif
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "GHC-%s %s", ProjectVersion, RtsWay);
+ postCapsetStrEvent(EVENT_RTS_IDENTIFIER,
+ CAPSET_OSPROCESS_DEFAULT,
+ buf);
+ }
+ {
+ int argc = 0; char **argv;
+ getFullProgArgv(&argc, &argv);
+ if (argc != 0) {
+ postCapsetVecEvent(EVENT_PROGRAM_ARGS,
+ CAPSET_OSPROCESS_DEFAULT,
+ argc, argv);
+ }
+ }
+ {
+ int envc = 0; char **envv;
+ getProgEnvv(&envc, &envv);
+ if (envc != 0) {
+ postCapsetVecEvent(EVENT_PROGRAM_ENV,
+ CAPSET_OSPROCESS_DEFAULT,
+ envc, envv);
+ }
+ freeProgEnvv(envc, envv);
+ }
+ }
+}