-- the wrapper had type () -> (), and hence the wrapper de-constructed the (), the worker re-constructed
-- a new (), with the result that the code ended up with "case () of (a,b) -> ...".
+primop TraceEventOp "traceEvent#" GenPrimOp
+ Addr# -> State# s -> State# s
+ { Emits an event via the RTS tracing framework. The contents
+ of the event is the zero-terminated byte string passed as the first
+ argument. The event will be emitted either to the .eventlog file,
+ or to stderr, depending on the runtime RTS flags. }
+ with
+ has_side_effects = True
+ out_of_line = True
+
------------------------------------------------------------------------
--- ---
------------------------------------------------------------------------
#define EVENT_LOG_MSG 16 /* (message ...) */
#define EVENT_STARTUP 17 /* (num_capabilities) */
#define EVENT_BLOCK_MARKER 18 /* (size, end_time, capability) */
+#define EVENT_USER_MSG 19 /* (message ...) */
-#define NUM_EVENT_TAGS 19
+#define NUM_EVENT_TAGS 20
#if 0 /* DEPRECATED EVENTS: */
#define EVENT_CREATE_SPARK 13 /* (cap, thread) */
};
+#define TRACE_NONE 0
+#define TRACE_EVENTLOG 1
+#define TRACE_STDERR 2
+
struct TRACE_FLAGS {
- rtsBool trace_stderr;
+ int tracing;
rtsBool timestamp; /* show timestamp in stderr output */
rtsBool scheduler; /* trace scheduler events */
RTS_FUN(stg_noDuplicatezh);
RTS_FUN(stg_traceCcszh);
+RTS_FUN(stg_traceEventzh);
/* Other misc stuff */
// See wiki:Commentary/Compiler/Backends/PprC#Prototypes
SymI_HasProto(stopTimer) \
SymI_HasProto(n_capabilities) \
SymI_HasProto(stg_traceCcszh) \
+ SymI_HasProto(stg_traceEventzh) \
RTS_USER_SIGNALS_SYMBOLS
}
#endif
}
+
+stg_traceEventzh
+{
+ W_ msg;
+ msg = R1;
+#if defined(TRACING) || defined(DEBUG)
+ foreign "C" traceUserMsg(MyCapability() "ptr", msg "ptr") [];
+#endif
+ jump %ENTRY_CODE(Sp(0));
+}
#endif
#ifdef TRACING
- RtsFlags.TraceFlags.trace_stderr = rtsFalse;
+ RtsFlags.TraceFlags.tracing = TRACE_NONE;
RtsFlags.TraceFlags.timestamp = rtsFalse;
RtsFlags.TraceFlags.scheduler = rtsFalse;
#endif
}
// -Dx also turns on -v. Use -l to direct trace
// events to the .eventlog file instead.
- RtsFlags.TraceFlags.trace_stderr = rtsTrue;
+ RtsFlags.TraceFlags.tracing = TRACE_STDERR;
break;
}
#endif
#ifdef TRACING
switch(rts_argv[arg][2]) {
case '\0':
- RtsFlags.TraceFlags.trace_stderr = rtsFalse;
- break;
+ RtsFlags.TraceFlags.tracing = TRACE_EVENTLOG;
+ break;
case 's':
- RtsFlags.TraceFlags.scheduler = rtsTrue;
- break;
+ RtsFlags.TraceFlags.tracing = TRACE_EVENTLOG;
+ RtsFlags.TraceFlags.scheduler = rtsTrue;
+ break;
default:
errorBelch("unknown RTS option: %s",rts_argv[arg]);
error = rtsTrue;
break;
}
#else
- errorBelch("not built for: -eventlog");
+ errorBelch("not built for: -eventlog");
#endif
- break;
+ break;
case 'P': /* detailed cost centre profiling (time/alloc) */
case 'p': /* cost centre profiling (time/alloc) */
switch(rts_argv[arg][2]) {
#ifdef TRACING
case '\0':
- RtsFlags.TraceFlags.trace_stderr = rtsTrue;
+ RtsFlags.TraceFlags.tracing = TRACE_STDERR;
break;
case 't':
RtsFlags.TraceFlags.timestamp = rtsTrue;
DEBUG_FLAG(sparks, DEBUG_sparks);
#endif
- eventlog_enabled = !RtsFlags.TraceFlags.trace_stderr && (
- TRACE_sched
-#ifdef DEBUG
- | DEBUG_sched
- | DEBUG_interp
- | DEBUG_weak
- | DEBUG_gccafs
- | DEBUG_gc
- | DEBUG_block_alloc
- | DEBUG_sanity
- | DEBUG_stable
- | DEBUG_stm
- | DEBUG_prof
- | DEBUG_linker
- | DEBUG_squeeze
- | DEBUG_hpc
-#endif
- );
+ eventlog_enabled = RtsFlags.TraceFlags.tracing == TRACE_EVENTLOG;
if (eventlog_enabled) {
initEventLogging();
StgTSO *tso, StgWord64 other)
{
#ifdef DEBUG
- if (RtsFlags.TraceFlags.trace_stderr) {
+ if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
traceSchedEvent_stderr(cap, tag, tso, other);
} else
#endif
va_start(ap,msg);
#ifdef DEBUG
- if (RtsFlags.TraceFlags.trace_stderr) {
+ if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
traceCap_stderr(cap, msg, ap);
} else
#endif
va_start(ap,msg);
#ifdef DEBUG
- if (RtsFlags.TraceFlags.trace_stderr) {
+ if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
trace_stderr(msg, ap);
} else
#endif
va_end(ap);
}
+void traceUserMsg(Capability *cap, char *msg)
+{
+#ifdef DEBUG
+ if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
+ traceCap_stderr(cap, msg, NULL);
+ } else
+#endif
+ {
+ if (eventlog_enabled) {
+ postUserMsg(cap, msg);
+ }
+ }
+}
+
void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG)
{
#ifdef DEBUG
- if (RtsFlags.TraceFlags.trace_stderr) {
+ if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
printThreadStatus(tso);
} else
#endif
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
[EVENT_REQUEST_PAR_GC] = "Request parallel GC",
[EVENT_CREATE_SPARK_THREAD] = "Create spark thread",
[EVENT_LOG_MSG] = "Log message",
+ [EVENT_USER_MSG] = "User message",
[EVENT_STARTUP] = "Startup",
[EVENT_BLOCK_MARKER] = "Block marker"
};
static void postEventType(EventsBuf *eb, EventType *et);
-static void postLogMsg(EventsBuf *eb, char *msg, va_list ap);
+static void postLogMsg(EventsBuf *eb, EventTypeNum type, char *msg, va_list ap);
static void postBlockMarker(EventsBuf *eb);
static void closeBlockMarker(EventsBuf *ebuf);
break;
case EVENT_LOG_MSG: // (msg)
+ case EVENT_USER_MSG: // (msg)
eventTypes[t].size = 0xffff;
break;
#define BUF 512
-void postLogMsg(EventsBuf *eb, char *msg, va_list ap)
+void postLogMsg(EventsBuf *eb, EventTypeNum type, char *msg, va_list ap)
{
char buf[BUF];
nat size;
printAndClearEventBuf(eb);
}
- postEventHeader(eb, EVENT_LOG_MSG);
+ postEventHeader(eb, type);
postPayloadSize(eb, size);
postBuf(eb,(StgWord8*)buf,size);
}
void postMsg(char *msg, va_list ap)
{
ACQUIRE_LOCK(&eventBufMutex);
- postLogMsg(&eventBuf, msg, ap);
+ postLogMsg(&eventBuf, EVENT_LOG_MSG, msg, ap);
RELEASE_LOCK(&eventBufMutex);
}
void postCapMsg(Capability *cap, char *msg, va_list ap)
{
- postLogMsg(&capEventBuf[cap->no], msg, ap);
+ postLogMsg(&capEventBuf[cap->no], EVENT_LOG_MSG, msg, ap);
}
+void postUserMsg(Capability *cap, char *msg)
+{
+ postLogMsg(&capEventBuf[cap->no], EVENT_USER_MSG, msg, NULL);
+}
+
void closeBlockMarker (EventsBuf *ebuf)
{
StgInt8* save_pos;
void postMsg(char *msg, va_list ap);
+void postUserMsg(Capability *cap, char *msg);
+
void postCapMsg(Capability *cap, char *msg, va_list ap);
#else /* !TRACING */