Commit 084b64f2 authored by Duncan Coutts's avatar Duncan Coutts

Add new fully-accurate per-spark trace/eventlog events

Replaces the existing EVENT_RUN/STEAL_SPARK events with 7 new events
covering all stages of the spark lifcycle:
  create, dud, overflow, run, steal, fizzle, gc

The sampled spark events are still available. There are now two event
classes for sparks, the sampled and the fully accurate. They can be
enabled/disabled independently. By default +RTS -l includes the sampled
but not full detail spark events. Use +RTS -lf-p to enable the detailed
'f' and disable the sampled 'p' spark.

Includes work by Mikolaj <mikolaj.konarski@gmail.com>
parent 46b70749
......@@ -104,8 +104,7 @@
#define EVENT_STOP_THREAD 2 /* (thread, status, blockinfo) */
#define EVENT_THREAD_RUNNABLE 3 /* (thread) */
#define EVENT_MIGRATE_THREAD 4 /* (thread, new_cap) */
#define EVENT_RUN_SPARK 5 /* (thread) */
#define EVENT_STEAL_SPARK 6 /* (thread, victim_cap) */
/* 5, 6 deprecated */
#define EVENT_SHUTDOWN 7 /* () */
#define EVENT_THREAD_WAKEUP 8 /* (thread, other_cap) */
#define EVENT_GC_START 9 /* () */
......@@ -134,9 +133,16 @@
#define EVENT_OSPROCESS_PID 32 /* (capset, pid) */
#define EVENT_OSPROCESS_PPID 33 /* (capset, parent_pid) */
#define EVENT_SPARK_COUNTERS 34 /* (crt,dud,ovf,cnv,fiz,gcd,rem) */
#define EVENT_SPARK_CREATE 35 /* () */
#define EVENT_SPARK_DUD 36 /* () */
#define EVENT_SPARK_OVERFLOW 37 /* () */
#define EVENT_SPARK_RUN 38 /* () */
#define EVENT_SPARK_STEAL 39 /* (victim_cap) */
#define EVENT_SPARK_FIZZLE 40 /* () */
#define EVENT_SPARK_GC 41 /* () */
/* Range 34 - 59 is available for new events */
/* Range 42 - 59 is available for new events */
/* Range 60 - 80 is used by eden for parallel tracing
* see http://www.mathematik.uni-marburg.de/~eden/
......@@ -147,9 +153,12 @@
* ranges higher than this are reserved but not currently emitted by ghc.
* This must match the size of the EventDesc[] array in EventLog.c
*/
#define NUM_EVENT_TAGS 35
#define NUM_EVENT_TAGS 42
#if 0 /* DEPRECATED EVENTS: */
/* we don't actually need to record the thread, it's implicit */
#define EVENT_RUN_SPARK 5 /* (thread) */
#define EVENT_STEAL_SPARK 6 /* (thread, victim_cap) */
/* ghc changed how it handles sparks so these are no longer applicable */
#define EVENT_CREATE_SPARK 13 /* (cap, thread) */
#define EVENT_SPARK_TO_THREAD 14 /* (cap, thread, spark_thread) */
......
......@@ -129,7 +129,8 @@ struct TRACE_FLAGS {
rtsBool timestamp; /* show timestamp in stderr output */
rtsBool scheduler; /* trace scheduler events */
rtsBool gc; /* trace GC events */
rtsBool sparks; /* trace spark events */
rtsBool sparks_sampled; /* trace spark events by a sampled method */
rtsBool sparks_full; /* trace spark events 100% accurately */
};
struct CONCURRENT_FLAGS {
......
......@@ -95,13 +95,14 @@ findSpark (Capability *cap)
spark = tryStealSpark(cap->sparks);
while (spark != NULL && fizzledSpark(spark)) {
cap->spark_stats.fizzled++;
traceEventSparkFizzle(cap);
spark = tryStealSpark(cap->sparks);
}
if (spark != NULL) {
cap->spark_stats.converted++;
// Post event for running a spark from capability's own pool.
traceEventRunSpark(cap, cap->r.rCurrentTSO);
traceEventSparkRun(cap);
return spark;
}
......@@ -128,6 +129,7 @@ findSpark (Capability *cap)
spark = tryStealSpark(robbed->sparks);
while (spark != NULL && fizzledSpark(spark)) {
cap->spark_stats.fizzled++;
traceEventSparkFizzle(cap);
spark = tryStealSpark(robbed->sparks);
}
if (spark == NULL && !emptySparkPoolCap(robbed)) {
......@@ -138,8 +140,7 @@ findSpark (Capability *cap)
if (spark != NULL) {
cap->spark_stats.converted++;
traceEventStealSpark(cap, cap->r.rCurrentTSO, robbed->no);
traceEventSparkSteal(cap, robbed->no);
return spark;
}
......
......@@ -164,7 +164,8 @@ void initRtsFlagsDefaults(void)
RtsFlags.TraceFlags.timestamp = rtsFalse;
RtsFlags.TraceFlags.scheduler = rtsFalse;
RtsFlags.TraceFlags.gc = rtsFalse;
RtsFlags.TraceFlags.sparks = rtsFalse;
RtsFlags.TraceFlags.sparks_sampled= rtsFalse;
RtsFlags.TraceFlags.sparks_full = rtsFalse;
#endif
RtsFlags.MiscFlags.tickInterval = 20; /* In milliseconds */
......@@ -291,7 +292,8 @@ usage_text[] = {
" where [flags] can contain:",
" s scheduler events",
" g GC events",
" p par spark events",
" p par spark events (sampled)",
" f par spark events (full detail)",
# ifdef DEBUG
" t add time stamps (only useful with -v)",
# endif
......@@ -1449,13 +1451,13 @@ static void read_trace_flags(char *arg)
/* Start by turning on the default tracing flags.
*
* Currently this is all the trace classes, but might not be in
* future, for example we might default to slightly less verbose
* Currently this is all the trace classes, except full-detail sparks.
* Similarly, in future we might default to slightly less verbose
* scheduler or GC tracing.
*/
RtsFlags.TraceFlags.scheduler = rtsTrue;
RtsFlags.TraceFlags.gc = rtsTrue;
RtsFlags.TraceFlags.sparks = rtsTrue;
RtsFlags.TraceFlags.scheduler = rtsTrue;
RtsFlags.TraceFlags.gc = rtsTrue;
RtsFlags.TraceFlags.sparks_sampled = rtsTrue;
for (c = arg; *c != '\0'; c++) {
switch(*c) {
......@@ -1465,9 +1467,10 @@ static void read_trace_flags(char *arg)
enabled = rtsFalse;
break;
case 'a':
RtsFlags.TraceFlags.scheduler = enabled;
RtsFlags.TraceFlags.gc = enabled;
RtsFlags.TraceFlags.sparks = enabled;
RtsFlags.TraceFlags.scheduler = enabled;
RtsFlags.TraceFlags.gc = enabled;
RtsFlags.TraceFlags.sparks_sampled = enabled;
RtsFlags.TraceFlags.sparks_full = enabled;
enabled = rtsTrue;
break;
......@@ -1476,7 +1479,11 @@ static void read_trace_flags(char *arg)
enabled = rtsTrue;
break;
case 'p':
RtsFlags.TraceFlags.sparks = enabled;
RtsFlags.TraceFlags.sparks_sampled = enabled;
enabled = rtsTrue;
break;
case 'f':
RtsFlags.TraceFlags.sparks_full = enabled;
enabled = rtsTrue;
break;
case 't':
......
......@@ -43,8 +43,6 @@ provider HaskellEvent {
probe stop__thread (EventCapNo, EventThreadID, EventThreadStatus, EventThreadID);
probe thread__runnable (EventCapNo, EventThreadID);
probe migrate__thread (EventCapNo, EventThreadID, EventCapNo);
probe run__spark (EventCapNo, EventThreadID);
probe steal__spark (EventCapNo, EventThreadID, EventCapNo);
probe shutdown (EventCapNo);
probe thread_wakeup (EventCapNo, EventThreadID, EventCapNo);
probe gc__start (EventCapNo);
......@@ -71,4 +69,12 @@ provider HaskellEvent {
StgWord, StgWord, StgWord
StgWord, StgWord, StgWord
StgWord);
probe spark__create (EventCapNo);
probe spark__dud (EventCapNo);
probe spark__overflow (EventCapNo);
probe spark__run (EventCapNo);
probe spark__steal (EventCapNo, EventCapNo);
probe spark__fizzle (EventCapNo);
probe spark__gc (EventCapNo);
};
......@@ -61,13 +61,16 @@ newSpark (StgRegTable *reg, StgClosure *p)
if (!fizzledSpark(p)) {
if (pushWSDeque(pool,p)) {
cap->spark_stats.created++;
cap->spark_stats.created++;
traceEventSparkCreate(cap);
} else {
/* overflowing the spark pool */
cap->spark_stats.overflowed++;
traceEventSparkOverflow(cap);
}
} else {
cap->spark_stats.dud++;
traceEventSparkDud(cap);
}
return 1;
......@@ -174,6 +177,7 @@ pruneSparkQueue (Capability *cap)
// robustness.
pruned_sparks++;
cap->spark_stats.fizzled++;
traceEventSparkFizzle(cap);
} else {
info = spark->header.info;
if (IS_FORWARDING_PTR(info)) {
......@@ -186,6 +190,7 @@ pruneSparkQueue (Capability *cap)
} else {
pruned_sparks++; // discard spark
cap->spark_stats.fizzled++;
traceEventSparkFizzle(cap);
}
} else if (HEAP_ALLOCED(spark)) {
if ((Bdescr((P_)spark)->flags & BF_EVACUATED)) {
......@@ -196,10 +201,12 @@ pruneSparkQueue (Capability *cap)
} else {
pruned_sparks++; // discard spark
cap->spark_stats.fizzled++;
traceEventSparkFizzle(cap);
}
} else {
pruned_sparks++; // discard spark
cap->spark_stats.gcd++;
traceEventSparkGC(cap);
}
} else {
if (INFO_PTR_TO_STRUCT(info)->type == THUNK_STATIC) {
......@@ -210,10 +217,12 @@ pruneSparkQueue (Capability *cap)
} else {
pruned_sparks++; // discard spark
cap->spark_stats.gcd++;
traceEventSparkGC(cap);
}
} else {
pruned_sparks++; // discard spark
cap->spark_stats.fizzled++;
traceEventSparkFizzle(cap);
}
}
}
......
......@@ -48,7 +48,8 @@ int DEBUG_sparks;
// events
int TRACE_sched;
int TRACE_gc;
int TRACE_spark;
int TRACE_spark_sampled;
int TRACE_spark_full;
#ifdef THREADED_RTS
static Mutex trace_utx;
......@@ -97,9 +98,12 @@ void initTracing (void)
RtsFlags.TraceFlags.gc ||
RtsFlags.DebugFlags.gc;
// -Dr turns on spark tracing
TRACE_spark =
RtsFlags.TraceFlags.sparks ||
TRACE_spark_sampled =
RtsFlags.TraceFlags.sparks_sampled;
// -Dr turns on full spark tracing
TRACE_spark_full =
RtsFlags.TraceFlags.sparks_full ||
RtsFlags.DebugFlags.sparks;
eventlog_enabled = RtsFlags.TraceFlags.tracing == TRACE_EVENTLOG;
......@@ -195,22 +199,10 @@ static void traceSchedEvent_stderr (Capability *cap, EventTypeNum tag,
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);
......@@ -380,6 +372,68 @@ void traceOSProcessInfo_(void) {
}
}
#ifdef DEBUG
static void traceSparkEvent_stderr (Capability *cap, EventTypeNum tag,
StgWord info1)
{
ACQUIRE_LOCK(&trace_utx);
tracePreface();
switch (tag) {
case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
debugBelch("cap %d: creating spark thread %lu\n",
cap->no, (long)info1);
break;
case EVENT_SPARK_CREATE: // (cap)
debugBelch("cap %d: added spark to pool\n",
cap->no);
break;
case EVENT_SPARK_DUD: // (cap)
debugBelch("cap %d: discarded dud spark\n",
cap->no);
break;
case EVENT_SPARK_OVERFLOW: // (cap)
debugBelch("cap %d: discarded overflowed spark\n",
cap->no);
break;
case EVENT_SPARK_RUN: // (cap)
debugBelch("cap %d: running a spark\n",
cap->no);
break;
case EVENT_SPARK_STEAL: // (cap, victim_cap)
debugBelch("cap %d: stealing a spark from cap %d\n",
cap->no, (int)info1);
break;
case EVENT_SPARK_FIZZLE: // (cap)
debugBelch("cap %d: fizzled spark removed from pool\n",
cap->no);
break;
case EVENT_SPARK_GC: // (cap)
debugBelch("cap %d: GCd spark removed from pool\n",
cap->no);
break;
default:
barf("traceSparkEvent: unknown event tag %d", tag);
break;
}
RELEASE_LOCK(&trace_utx);
}
#endif
void traceSparkEvent_ (Capability *cap, EventTypeNum tag, StgWord info1)
{
#ifdef DEBUG
if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
traceSparkEvent_stderr(cap, tag, info1);
} else
#endif
{
postSparkEvent(cap,tag,info1);
}
}
void traceSparkCounters_ (Capability *cap,
SparkCounters counters,
StgWord remaining)
......
......@@ -63,7 +63,8 @@ extern int DEBUG_sparks;
// events
extern int TRACE_sched;
extern int TRACE_gc;
extern int TRACE_spark;
extern int TRACE_spark_sampled;
extern int TRACE_spark_full;
// -----------------------------------------------------------------------------
// Posting events
......@@ -95,11 +96,6 @@ void traceEnd (void);
traceSchedEvent_(cap, tag, tso, info1, info2); \
}
#define traceSparkEvent(cap, tag, tso, other) \
if (RTS_UNLIKELY(TRACE_spark)) { \
traceSchedEvent_(cap, tag, tso, other, 0); \
}
void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
StgTSO *tso, StgWord info1, StgWord info2);
......@@ -113,6 +109,21 @@ void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
void traceGcEvent_ (Capability *cap, EventTypeNum tag);
/*
* Record a spark event
*/
#define traceSparkEvent(cap, tag) \
if (RTS_UNLIKELY(TRACE_spark_full)) { \
traceSparkEvent_(cap, tag, 0); \
}
#define traceSparkEvent2(cap, tag, other) \
if (RTS_UNLIKELY(TRACE_spark_full)) { \
traceSparkEvent_(cap, tag, other); \
}
void traceSparkEvent_ (Capability *cap, EventTypeNum tag, StgWord info1);
// 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).
......@@ -199,7 +210,8 @@ void traceSparkCounters_ (Capability *cap,
#define traceSchedEvent(cap, tag, tso, other) /* nothing */
#define traceSchedEvent2(cap, tag, tso, other, info) /* nothing */
#define traceGcEvent(cap, tag) /* nothing */
#define traceSparkEvent(cap, tag, tso, other) /* nothing */
#define traceSparkEvent(cap, tag) /* nothing */
#define traceSparkEvent2(cap, tag, other) /* nothing */
#define traceCap(class, cap, msg, ...) /* nothing */
#define trace(class, msg, ...) /* nothing */
#define debugTrace(class, str, ...) /* nothing */
......@@ -237,10 +249,6 @@ void dtraceUserMsgWrapper(Capability *cap, char *msg);
HASKELLEVENT_THREAD_RUNNABLE(cap, tid)
#define dtraceMigrateThread(cap, tid, new_cap) \
HASKELLEVENT_MIGRATE_THREAD(cap, tid, new_cap)
#define dtraceRunSpark(cap, tid) \
HASKELLEVENT_RUN_SPARK(cap, tid)
#define dtraceStealSpark(cap, tid, victim_cap) \
HASKELLEVENT_STEAL_SPARK(cap, tid, victim_cap)
#define dtraceShutdown(cap) \
HASKELLEVENT_SHUTDOWN(cap)
#define dtraceThreadWakeup(cap, tid, other_cap) \
......@@ -276,6 +284,20 @@ INLINE_HEADER void dtraceStartup (int num_caps) {
HASKELLEVENT_CAPSET_REMOVE_CAP(capset, capno)
#define dtraceSparkCounters(cap, a, b, c, d, e, f, g) \
HASKELLEVENT_SPARK_COUNTERS(cap, a, b, c, d, e, f, g)
#define dtraceSparkCreate(cap) \
HASKELLEVENT_SPARK_CREATE(cap)
#define dtraceSparkDud(cap) \
HASKELLEVENT_SPARK_DUD(cap)
#define dtraceSparkOverflow(cap) \
HASKELLEVENT_SPARK_OVERFLOW(cap)
#define dtraceSparkRun(cap) \
HASKELLEVENT_SPARK_RUN(cap)
#define dtraceSparkSteal(cap, victim_cap) \
HASKELLEVENT_SPARK_STEAL(cap, victim_cap)
#define dtraceSparkFizzle(cap) \
HASKELLEVENT_SPARK_FIZZLE(cap)
#define dtraceSparkGc(cap) \
HASKELLEVENT_SPARK_GC(cap)
#else /* !defined(DTRACE) */
......@@ -284,8 +306,6 @@ INLINE_HEADER void dtraceStartup (int num_caps) {
#define dtraceStopThread(cap, tid, status, info) /* nothing */
#define dtraceThreadRunnable(cap, tid) /* nothing */
#define dtraceMigrateThread(cap, tid, new_cap) /* nothing */
#define dtraceRunSpark(cap, tid) /* nothing */
#define dtraceStealSpark(cap, tid, victim_cap) /* nothing */
#define dtraceShutdown(cap) /* nothing */
#define dtraceThreadWakeup(cap, tid, other_cap) /* nothing */
#define dtraceGcStart(cap) /* nothing */
......@@ -303,6 +323,13 @@ INLINE_HEADER void dtraceStartup (int num_caps STG_UNUSED) {};
#define dtraceCapsetAssignCap(capset, capno) /* nothing */
#define dtraceCapsetRemoveCap(capset, capno) /* nothing */
#define dtraceSparkCounters(cap, a, b, c, d, e, f, g) /* nothing */
#define dtraceSparkCreate(cap) /* nothing */
#define dtraceSparkDud(cap) /* nothing */
#define dtraceSparkOverflow(cap) /* nothing */
#define dtraceSparkRun(cap) /* nothing */
#define dtraceSparkSteal(cap, victim_cap) /* nothing */
#define dtraceSparkFizzle(cap) /* nothing */
#define dtraceSparkGc(cap) /* nothing */
#endif
......@@ -424,30 +451,6 @@ INLINE_HEADER void traceEventGcDone(Capability *cap STG_UNUSED)
dtraceGcDone((EventCapNo)cap->no);
}
INLINE_HEADER void traceEventRunSpark(Capability *cap STG_UNUSED,
StgTSO *tso STG_UNUSED)
{
traceSparkEvent(cap, EVENT_RUN_SPARK, tso, 0);
dtraceRunSpark((EventCapNo)cap->no, (EventThreadID)tso->id);
}
INLINE_HEADER void traceEventStealSpark(Capability *cap STG_UNUSED,
StgTSO *tso STG_UNUSED,
nat victim_cap STG_UNUSED)
{
traceSparkEvent(cap, EVENT_STEAL_SPARK, tso, victim_cap);
dtraceStealSpark((EventCapNo)cap->no, (EventThreadID)tso->id,
(EventCapNo)victim_cap);
}
INLINE_HEADER void traceEventCreateSparkThread(Capability *cap STG_UNUSED,
StgThreadID spark_tid STG_UNUSED)
{
traceSparkEvent(cap, EVENT_CREATE_SPARK_THREAD, 0, spark_tid);
dtraceCreateSparkThread((EventCapNo)cap->no, (EventThreadID)spark_tid);
}
INLINE_HEADER void traceEventStartup(void)
{
int n_caps;
......@@ -496,10 +499,17 @@ INLINE_HEADER void traceOSProcessInfo(void)
* is available to DTrace directly */
}
INLINE_HEADER void traceEventCreateSparkThread(Capability *cap STG_UNUSED,
StgThreadID spark_tid STG_UNUSED)
{
traceSparkEvent2(cap, EVENT_CREATE_SPARK_THREAD, spark_tid);
dtraceCreateSparkThread((EventCapNo)cap->no, (EventThreadID)spark_tid);
}
INLINE_HEADER void traceSparkCounters(Capability *cap STG_UNUSED)
{
#ifdef THREADED_RTS
if (RTS_UNLIKELY(TRACE_spark)) {
if (RTS_UNLIKELY(TRACE_spark_sampled)) {
traceSparkCounters_(cap, cap->spark_stats, sparkPoolSize(cap->sparks));
}
#endif
......@@ -513,6 +523,48 @@ INLINE_HEADER void traceSparkCounters(Capability *cap STG_UNUSED)
sparkPoolSize(cap->sparks));
}
INLINE_HEADER void traceEventSparkCreate(Capability *cap STG_UNUSED)
{
traceSparkEvent(cap, EVENT_SPARK_CREATE);
dtraceSparkCreate((EventCapNo)cap->no);
}
INLINE_HEADER void traceEventSparkDud(Capability *cap STG_UNUSED)
{
traceSparkEvent(cap, EVENT_SPARK_DUD);
dtraceSparkDud((EventCapNo)cap->no);
}
INLINE_HEADER void traceEventSparkOverflow(Capability *cap STG_UNUSED)
{
traceSparkEvent(cap, EVENT_SPARK_OVERFLOW);
dtraceSparkOverflow((EventCapNo)cap->no);
}
INLINE_HEADER void traceEventSparkRun(Capability *cap STG_UNUSED)
{
traceSparkEvent(cap, EVENT_SPARK_RUN);
dtraceSparkRun((EventCapNo)cap->no);
}
INLINE_HEADER void traceEventSparkSteal(Capability *cap STG_UNUSED,
nat victim_cap STG_UNUSED)
{
traceSparkEvent2(cap, EVENT_SPARK_STEAL, victim_cap);
dtraceSparkSteal((EventCapNo)cap->no, (EventCapNo)victim_cap);
}
INLINE_HEADER void traceEventSparkFizzle(Capability *cap STG_UNUSED)
{
traceSparkEvent(cap, EVENT_SPARK_FIZZLE);
dtraceSparkFizzle((EventCapNo)cap->no);
}
INLINE_HEADER void traceEventSparkGC(Capability *cap STG_UNUSED)
{
traceSparkEvent(cap, EVENT_SPARK_GC);
dtraceSparkGc((EventCapNo)cap->no);
}
#include "EndPrivate.h"
......
......@@ -60,8 +60,6 @@ char *EventDesc[] = {
[EVENT_STOP_THREAD] = "Stop thread",
[EVENT_THREAD_RUNNABLE] = "Thread runnable",
[EVENT_MIGRATE_THREAD] = "Migrate thread",
[EVENT_RUN_SPARK] = "Run spark",
[EVENT_STEAL_SPARK] = "Steal spark",
[EVENT_SHUTDOWN] = "Shutdown",
[EVENT_THREAD_WAKEUP] = "Wakeup thread",
[EVENT_GC_START] = "Starting GC",
......@@ -85,7 +83,14 @@ char *EventDesc[] = {
[EVENT_PROGRAM_ENV] = "Program environment variables",
[EVENT_OSPROCESS_PID] = "Process ID",
[EVENT_OSPROCESS_PPID] = "Parent process ID",
[EVENT_SPARK_COUNTERS] = "Spark counters"
[EVENT_SPARK_COUNTERS] = "Spark counters",
[EVENT_SPARK_CREATE] = "Spark create",
[EVENT_SPARK_DUD] = "Spark dud",
[EVENT_SPARK_OVERFLOW] = "Spark overflow",
[EVENT_SPARK_RUN] = "Spark run",
[EVENT_SPARK_STEAL] = "Spark steal",
[EVENT_SPARK_FIZZLE] = "Spark fizzle",
[EVENT_SPARK_GC] = "Spark GC",
};
// Event type.
......@@ -254,13 +259,11 @@ initEventLogging(void)
case EVENT_CREATE_THREAD: // (cap, thread)
case EVENT_RUN_THREAD: // (cap, thread)
case EVENT_THREAD_RUNNABLE: // (cap, thread)
case EVENT_RUN_SPARK: // (cap, thread)
case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
eventTypes[t].size = sizeof(EventThreadID);
break;
case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
case EVENT_STEAL_SPARK: // (cap, thread, victim_cap)
case EVENT_THREAD_WAKEUP: // (cap, thread, other_cap)
eventTypes[t].size =
sizeof(EventThreadID) + sizeof(EventCapNo);
......@@ -296,6 +299,11 @@ initEventLogging(void)
sizeof(EventCapsetID) + sizeof(StgWord32);
break;
case EVENT_SPARK_STEAL: // (cap, victim_cap)
eventTypes[t].size =
sizeof(EventCapNo);
break;
case EVENT_SHUTDOWN: // (cap)
case EVENT_REQUEST_SEQ_GC: // (cap)
case EVENT_REQUEST_PAR_GC: // (cap)
......@@ -304,6 +312,12 @@ initEventLogging(void)
case EVENT_GC_IDLE:
case EVENT_GC_WORK:
case EVENT_GC_DONE:
case EVENT_SPARK_CREATE: // (cap)
case EVENT_SPARK_DUD: // (cap)
case EVENT_SPARK_OVERFLOW: // (cap)
case EVENT_SPARK_RUN: // (cap)
case EVENT_SPARK_FIZZLE: // (cap)
case EVENT_SPARK_GC: // (cap)
eventTypes[t].size = 0;
break;
......@@ -440,7 +454,6 @@ postSchedEvent (Capability *cap,
case EVENT_CREATE_THREAD: // (cap, thread)
case EVENT_RUN_THREAD: // (cap, thread)
case EVENT_THREAD_RUNNABLE: // (cap, thread)
case EVENT_RUN_SPARK: // (cap, thread)
{
postThreadID(eb,thread);
break;
......@@ -453,7 +466,6 @@ postSchedEvent (Capability *cap,
}
case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
case EVENT_STEAL_SPARK: // (cap, thread, victim_cap)
case EVENT_THREAD_WAKEUP: // (cap, thread, other_cap)
{
postThreadID(eb,thread);
......@@ -479,6 +491,50 @@ postSchedEvent (Capability *cap,
}
}
void
postSparkEvent (Capability *cap,
EventTypeNum tag,
StgWord info1)