From 064562360a310f08592d41e9fceb3404932c4a04 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Sat, 12 Sep 2009 21:35:04 +0000 Subject: [PATCH] Optimise the code generated at trace points --- includes/Rts.h | 6 ++ rts/Trace.c | 39 ++++++++++-- rts/Trace.h | 185 ++++++++++++++++++++------------------------------------ rts/sm/GC.c | 4 +- 4 files changed, 109 insertions(+), 125 deletions(-) diff --git a/includes/Rts.h b/includes/Rts.h index 753a664..1bfb37a 100644 --- a/includes/Rts.h +++ b/includes/Rts.h @@ -65,6 +65,12 @@ extern "C" { #define END_RTS_PRIVATE /* disabled: END_RTS_PRIVATE */ #endif +#if __GNUC__ > 4 +#define RTS_UNLIKELY(p) __builtin_expect((p),0) +#else +#define RTS_UNLIKELY(p) p +#endif + /* Fix for mingw stat problem (done here so it's early enough) */ #ifdef mingw32_HOST_OS #define __MSVCRT__ 1 diff --git a/rts/Trace.c b/rts/Trace.c index 7194651..20debdc 100644 --- a/rts/Trace.c +++ b/rts/Trace.c @@ -19,7 +19,26 @@ #include "Threads.h" #include "Printer.h" -StgWord32 classes_enabled; // not static due to inline funcs +// debugging flags, set with +RTS -D +int DEBUG_sched; +int DEBUG_interp; +int DEBUG_weak; +int DEBUG_gccafs; +int DEBUG_gc; +int DEBUG_block_alloc; +int DEBUG_sanity; +int DEBUG_stable; +int DEBUG_stm; +int DEBUG_prof; +int DEBUG_gran; +int DEBUG_par; +int DEBUG_linker; +int DEBUG_squeeze; +int DEBUG_hpc; +int DEBUG_sparks; + +// events +int TRACE_sched; #ifdef THREADED_RTS static Mutex trace_utx; @@ -37,7 +56,7 @@ void initTracing (void) #ifdef DEBUG #define DEBUG_FLAG(name, class) \ - if (RtsFlags.DebugFlags.name) classes_enabled |= class; + class = RtsFlags.DebugFlags.name ? 1 : 0; DEBUG_FLAG(scheduler, DEBUG_sched); DEBUG_FLAG(scheduler, TRACE_sched); // -Ds enabled all sched events @@ -58,7 +77,7 @@ void initTracing (void) #endif #define TRACE_FLAG(name, class) \ - if (RtsFlags.TraceFlags.name) classes_enabled |= class; + class = RtsFlags.TraceFlags.name ? 1 : 0; TRACE_FLAG(scheduler, TRACE_sched); @@ -200,8 +219,11 @@ static void traceCap_stderr(Capability *cap, char *msg, va_list ap) } #endif -void traceCap_(Capability *cap, char *msg, va_list ap) +void traceCap_(Capability *cap, char *msg, ...) { + va_list ap; + va_start(ap,msg); + #ifdef DEBUG if (RtsFlags.TraceFlags.trace_stderr) { traceCap_stderr(cap, msg, ap); @@ -210,6 +232,8 @@ void traceCap_(Capability *cap, char *msg, va_list ap) { postCapMsg(cap, msg, ap); } + + va_end(ap); } #ifdef DEBUG @@ -225,8 +249,11 @@ static void trace_stderr(char *msg, va_list ap) } #endif -void trace_(char *msg, va_list ap) +void trace_(char *msg, ...) { + va_list ap; + va_start(ap,msg); + #ifdef DEBUG if (RtsFlags.TraceFlags.trace_stderr) { trace_stderr(msg, ap); @@ -235,6 +262,8 @@ void trace_(char *msg, va_list ap) { postMsg(msg, ap); } + + va_end(ap); } void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG) diff --git a/rts/Trace.h b/rts/Trace.h index 702a51e..775f235 100644 --- a/rts/Trace.h +++ b/rts/Trace.h @@ -15,31 +15,6 @@ BEGIN_RTS_PRIVATE // ----------------------------------------------------------------------------- -// Posting events -// ----------------------------------------------------------------------------- - -INLINE_HEADER void trace (StgWord32 class, char *msg, ...); - -#ifdef DEBUG -INLINE_HEADER void debugTrace (StgWord32 class, char *msg, ...); -#endif - -INLINE_HEADER void traceSchedEvent (Capability *cap, EventTypeNum tag, - StgTSO *tso, StgWord64 other); - -INLINE_HEADER void traceCap (StgWord32 class, Capability *cap, - char *msg, ...); - -INLINE_HEADER void traceThreadStatus (StgWord32 class, StgTSO *tso); - -INLINE_HEADER rtsBool traceClass (StgWord32 class); - -#ifdef DEBUG -void traceBegin (const char *str, ...); -void traceEnd (void); -#endif - -// ----------------------------------------------------------------------------- // EventLog API // ----------------------------------------------------------------------------- @@ -52,137 +27,111 @@ void freeTracing (void); #endif /* TRACING */ // ----------------------------------------------------------------------------- -// Message classes, these may be OR-ed together +// Message classes // ----------------------------------------------------------------------------- // debugging flags, set with +RTS -D -#define DEBUG_sched (1<<0) -#define DEBUG_interp (1<<1) -#define DEBUG_weak (1<<2) -#define DEBUG_gccafs (1<<3) -#define DEBUG_gc (1<<4) -#define DEBUG_block_alloc (1<<5) -#define DEBUG_sanity (1<<6) -#define DEBUG_stable (1<<7) -#define DEBUG_stm (1<<8) -#define DEBUG_prof (1<<9) -#define DEBUG_gran (1<<10) -#define DEBUG_par (1<<11) -#define DEBUG_linker (1<<12) -#define DEBUG_squeeze (1<<13) -#define DEBUG_hpc (1<<14) -#define DEBUG_sparks (1<<15) +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 -#define TRACE_sched (1<<16) +extern int TRACE_sched; // ----------------------------------------------------------------------------- -// PRIVATE below here +// 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 TRACING +#ifdef DEBUG +void traceBegin (const char *str, ...); +void traceEnd (void); +#endif -extern StgWord32 classes_enabled; +#ifdef TRACING -INLINE_HEADER rtsBool traceClass (StgWord32 class) -{ return (classes_enabled & class); } +/* + * 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); +// 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). + /* - * Trace an event to the capability's event buffer. + * Emit a trace message on a particular Capability */ -INLINE_HEADER void traceSchedEvent(Capability *cap, EventTypeNum tag, - StgTSO *tso, StgWord64 other) -{ - if (traceClass(TRACE_sched)) { - traceSchedEvent_(cap, tag, tso, other); +#define traceCap(class, cap, msg, ...) \ + if (RTS_UNLIKELY(class)) { \ + traceCap_(cap, msg, ##__VA_ARGS__); \ } -} -void traceCap_(Capability *cap, char *msg, va_list ap); +void traceCap_(Capability *cap, char *msg, ...); /* - * Trace a log message + * Emit a trace message */ -INLINE_HEADER void traceCap (StgWord32 class, Capability *cap, char *msg, ...) -{ - va_list ap; - va_start(ap,msg); - if (traceClass(class)) { - traceCap_(cap, msg, ap); +#define trace(class, msg, ...) \ + if (RTS_UNLIKELY(class)) { \ + trace_(msg, ##__VA_ARGS__); \ } - va_end(ap); -} -void trace_(char *msg, va_list ap); +void trace_(char *msg, ...); /* - * Trace a log message + * Emit a debug message (only when DEBUG is defined) */ -INLINE_HEADER void trace (StgWord32 class, char *msg, ...) -{ - va_list ap; - va_start(ap,msg); - if (traceClass(class)) { - trace_(msg, ap); - } - va_end(ap); -} - #ifdef DEBUG -INLINE_HEADER void debugTrace (StgWord32 class, char *msg, ...) -{ - va_list ap; - va_start(ap,msg); - if (traceClass(class)) { - trace_(msg, ap); +#define debugTrace(class, msg, ...) \ + if (RTS_UNLIKELY(class)) { \ + trace_(msg, ##__VA_ARGS__); \ } - va_end(ap); -} #else - #define debugTrace(class, str, ...) /* nothing */ -// variable arg macros are C99, and supported by gcc. - #endif -void traceThreadStatus_ (StgTSO *tso); - -INLINE_HEADER void traceThreadStatus (StgWord32 class, StgTSO *tso) -{ - if (traceClass(class)) { - traceThreadStatus_(tso); +/* + * Emit a message/event describing the state of a thread + */ +#define traceThreadStatus(class, tso) \ + if (RTS_UNLIKELY(class)) { \ + traceThreadStatus_(tso); \ } -} - -#else /* !TRACING */ -INLINE_HEADER rtsBool traceClass (StgWord32 class STG_UNUSED) -{ return rtsFalse; } - -INLINE_HEADER void traceSchedEvent (Capability *cap STG_UNUSED, - EventTypeNum tag STG_UNUSED, - StgTSO *tso STG_UNUSED, - StgWord64 other STG_UNUSED) -{ /* nothing */ } - -INLINE_HEADER void traceCap (StgWord32 class STG_UNUSED, - Capability *cap STG_UNUSED, - char *msg STG_UNUSED, ...) -{ /* nothing */ } +void traceThreadStatus_ (StgTSO *tso); -INLINE_HEADER void trace (StgWord32 class STG_UNUSED, - char *msg STG_UNUSED, ...) -{ /* nothing */ } +#else /* !TRACING */ +#define traceSchedEvent(cap, tag, tso, other) /* nothing */ +#define traceCap(class, cap, msg, ...) /* nothing */ +#define trace(class, msg, ...) /* nothing */ #define debugTrace(class, str, ...) /* nothing */ -// variable arg macros are C99, and supported by gcc. - -INLINE_HEADER void traceThreadStatus (StgWord32 class STG_UNUSED, - StgTSO *tso STG_UNUSED) -{ /* nothing */ } +#define traceThreadStatus(class, tso) /* nothing */ #endif /* TRACING */ diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 6f15a47..97acc38 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -279,7 +279,7 @@ GarbageCollect (rtsBool force_major_gc, #ifdef DEBUG // check for memory leaks if DEBUG is on - memInventory(traceClass(DEBUG_gc)); + memInventory(DEBUG_gc); #endif // check stack sanity *before* GC @@ -782,7 +782,7 @@ SET_GCT(gc_threads[0]); #ifdef DEBUG // check for memory leaks if DEBUG is on - memInventory(traceClass(DEBUG_gc)); + memInventory(DEBUG_gc); #endif #ifdef RTS_GTK_FRONTPANEL -- 1.7.10.4