/* ----------------------------------------------------------------------------- * * (c) The GHC Team, 2008-2009 * * Support for fast binary event logging. * * ---------------------------------------------------------------------------*/ #ifndef TRACE_H #define TRACE_H #include "rts/EventLogFormat.h" #include "Capability.h" #if defined(PARALLEL_RTS) #include "Rts.h" #endif //PARALLEL_RTS BEGIN_RTS_PRIVATE // ----------------------------------------------------------------------------- // EventLog API // ----------------------------------------------------------------------------- #if defined(TRACING) void initTracing (void); void endTracing (void); void freeTracing (void); #endif /* TRACING */ // ----------------------------------------------------------------------------- // Message classes // ----------------------------------------------------------------------------- // debugging flags, set with +RTS -D extern int DEBUG_sched; extern int DEBUG_interp; extern int DEBUG_weak; extern int DEBUG_gccafs; extern int DEBUG_gc; extern int DEBUG_block_alloc; extern int DEBUG_sanity; extern int DEBUG_stable; extern int DEBUG_stm; extern int DEBUG_prof; extern int DEBUG_gran; extern int DEBUG_par; extern int DEBUG_linker; extern int DEBUG_squeeze; extern int DEBUG_hpc; extern int DEBUG_sparks; // events extern int TRACE_sched; // ----------------------------------------------------------------------------- // Posting events // // We use macros rather than inline functions deliberately. We want // the not-taken case to be as efficient as possible, a simple // test-and-jump, and with inline functions gcc seemed to move some of // the instructions from the branch up before the test. // // ----------------------------------------------------------------------------- #ifdef DEBUG void traceBegin (const char *str, ...); void traceEnd (void); #endif #ifdef TRACING /* * Record a scheduler event */ #define traceSchedEvent(cap, tag, tso, other) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceSchedEvent_(cap, tag, tso, other); \ } void traceSchedEvent_ (Capability *cap, EventTypeNum tag, StgTSO *tso, StgWord64 other); /* * Record a nullary event */ #define traceEvent(cap, tag) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceEvent_(cap, tag); \ } void traceEvent_ (Capability *cap, EventTypeNum tag); // variadic macros are C99, and supported by gcc. However, the // ##__VA_ARGS syntax is a gcc extension, which allows the variable // argument list to be empty (see gcc docs for details). /* * Emit a trace message on a particular Capability */ #define traceCap(class, cap, msg, ...) \ if (RTS_UNLIKELY(class)) { \ traceCap_(cap, msg, ##__VA_ARGS__); \ } void traceCap_(Capability *cap, char *msg, ...); /* * Emit a trace message */ #define trace(class, msg, ...) \ if (RTS_UNLIKELY(class)) { \ trace_(msg, ##__VA_ARGS__); \ } void trace_(char *msg, ...); /* * A message or event emitted by the program */ void traceUserMsg(Capability *cap, char *msg); /* * Emit a debug message (only when DEBUG is defined) */ #ifdef DEBUG #define debugTrace(class, msg, ...) \ if (RTS_UNLIKELY(class)) { \ trace_(msg, ##__VA_ARGS__); \ } #else #define debugTrace(class, str, ...) /* nothing */ #endif #ifdef DEBUG #define debugTraceCap(class, cap, msg, ...) \ if (RTS_UNLIKELY(class)) { \ traceCap_(cap, msg, ##__VA_ARGS__); \ } #else #define debugTraceCap(class, cap, str, ...) /* nothing */ #endif /* * Emit a message/event describing the state of a thread */ #define traceThreadStatus(class, tso) \ if (RTS_UNLIKELY(class)) { \ traceThreadStatus_(tso); \ } void traceThreadStatus_ (StgTSO *tso); #define traceVersion(version) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceVersion_(version); \ } void traceVersion_(char *version); #define traceProgramInvocation(commandline) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceProgramInvocation_(commandline); \ } void traceProgramInvocation_(char *commandline); #if defined(PARALLEL_RTS) /* * Record a EdenEventStartReceive event */ //TODO introduce Message Flag!!! #define traceEdenEventStartReceive(cap) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceEdenEventStartReceive_(cap); \ } void traceEdenEventStartReceive_(Capability *cap); /* * Record EdenEventEndReceive event */ //TODO introduce Message Flag!!! #define traceEdenEventEndReceive(cap) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceEdenEventEndReceive_(cap); \ } void traceEdenEventEndReceive_(Capability *cap); /* * Record a CreateProcess event */ #define traceCreateProcess(pid) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceCreateProcess_(pid); \ } void traceCreateProcess_(StgWord pid); /* * Record a KillProcess event */ #define traceKillProcess(pid) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceKillProcess_( pid); \ } void traceKillProcess_(StgWord pid); #define traceAssignThreadToProcessEvent(cap, tid, pid) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceAssignThreadToProcessEvent_(cap, tid, pid); \ } void traceAssignThreadToProcessEvent_(Capability *cap, nat tid, StgWord pid); #define traceCreateMachine(pe, time, ticks) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceCreateMachine_(pe, time, ticks); \ } void traceCreateMachine_ (nat pe, StgWord64 time, StgWord64 ticks); #define traceKillMachine(pe) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceKillMachine_(pe); \ } void traceKillMachine_(nat pe); #define traceSendMessageEvent(mstag, buf) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceSendMessageEvent_(mstag, buf); \ } void traceSendMessageEvent_(OpCode msgtag, rtsPackBuffer *buf); #define traceReceiveMessageEvent(cap, mstag, buf) \ if (RTS_UNLIKELY(TRACE_sched)) { \ traceReceiveMessageEvent_(cap, mstag, buf); \ } void traceReceiveMessageEvent_(Capability *cap, OpCode msgtag, rtsPackBuffer *buf); #endif // PARALLEL_RTS #else /* !TRACING */ #define traceSchedEvent(cap, tag, tso, other) /* nothing */ #define traceEvent(cap, tag) /* nothing */ #define traceCap(class, cap, msg, ...) /* nothing */ #define trace(class, msg, ...) /* nothing */ #define debugTrace(class, str, ...) /* nothing */ #define debugTraceCap(class, cap, str, ...) /* nothing */ #define traceThreadStatus(class, tso) /* nothing */ #define traceVersion(version) /* nothing */ #define traceProgramInvocation(commandline) /* nothing */ #if defined(PARALLEL_RTS) #define traceEdenEventStartReceive(cap) /* nothing */ #define traceEdenEventEndReceive(cap) /* nothing */ #define traceCreateProcess(pid) /* nothing */ #define traceKillProcess(pid) /* nothing */ #define traceAssignThreadToProcessEvent(cap, tid, pid) /* nothing */ #define traceCreateMachine(pe, time, ticks) /* nothing */ #define traceKillMachine(pe) /* nothing */ #define traceSendMessageEvent(mstag, buf) /* nothing */ #define traceReceiveMessageEvent(cap, mstag, buf) /* nothing */ #endif // PARALLEL_RTS #endif /* TRACING */ END_RTS_PRIVATE #endif /* TRACE_H */