summaryrefslogtreecommitdiff
path: root/rts/eventlog
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2012-07-03 19:28:40 +0100
committerMikolaj Konarski <mikolaj@well-typed.com>2012-07-10 17:53:34 +0200
commit54c98b687a5e23f3371604dc4918dfb3106a74f8 (patch)
tree6f35fbe69fec9f26d14da6f0a146aef5a4a925f1 /rts/eventlog
parent647ae1cfbb5ea3e2d3b1541c2bc12ea5db321134 (diff)
downloadhaskell-54c98b687a5e23f3371604dc4918dfb3106a74f8.tar.gz
Define the task-tracking events
Based on initial patches by Mikolaj Konarski <mikolaj@well-typed.com> These new eventlog events are to let profiling tools keep track of all the OS threads that belong to an RTS capability at any moment in time. In the RTS, OS threads correspond to the Task abstraction, so that is what we track. There are events for tasks being created, migrated between capabilities and deleted. In particular the task creation event also records the kernel thread id which lets us match up the OS thread with data collected by others tools (in the initial use case with Linux's perf tool, but in principle also with DTrace).
Diffstat (limited to 'rts/eventlog')
-rw-r--r--rts/eventlog/EventLog.c84
-rw-r--r--rts/eventlog/EventLog.h26
2 files changed, 101 insertions, 9 deletions
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c
index 66b589e282..b6614b940c 100644
--- a/rts/eventlog/EventLog.c
+++ b/rts/eventlog/EventLog.c
@@ -102,6 +102,9 @@ char *EventDesc[] = {
[EVENT_SPARK_STEAL] = "Spark steal",
[EVENT_SPARK_FIZZLE] = "Spark fizzle",
[EVENT_SPARK_GC] = "Spark GC",
+ [EVENT_TASK_CREATE] = "Task create",
+ [EVENT_TASK_MIGRATE] = "Task migrate",
+ [EVENT_TASK_DELETE] = "Task delete",
};
// Event type.
@@ -178,6 +181,15 @@ static inline void postCapsetID(EventsBuf *eb, EventCapsetID id)
static inline void postCapsetType(EventsBuf *eb, EventCapsetType type)
{ postWord16(eb,type); }
+static inline void postOSProcessId(EventsBuf *eb, pid_t pid)
+{ postWord32(eb, pid); }
+
+static inline void postKernelThreadId(EventsBuf *eb, EventKernelThreadId tid)
+{ postWord64(eb, tid); }
+
+static inline void postTaskId(EventsBuf *eb, EventTaskId tUniq)
+{ postWord64(eb, tUniq); }
+
static inline void postPayloadSize(EventsBuf *eb, EventPayloadSize size)
{ postWord16(eb,size); }
@@ -393,6 +405,20 @@ initEventLogging(void)
+ sizeof(StgWord64) * 2;
break;
+ case EVENT_TASK_CREATE: // (taskId, cap, tid)
+ eventTypes[t].size =
+ sizeof(EventTaskId) + sizeof(EventCapNo) + sizeof(EventKernelThreadId);
+ break;
+
+ case EVENT_TASK_MIGRATE: // (taskId, cap, new_cap)
+ eventTypes[t].size =
+ sizeof(EventTaskId) + sizeof(EventCapNo) + sizeof(EventCapNo);
+ break;
+
+ case EVENT_TASK_DELETE: // (taskId)
+ eventTypes[t].size = sizeof(EventTaskId);
+ break;
+
case EVENT_BLOCK_MARKER:
eventTypes[t].size = sizeof(StgWord32) + sizeof(EventTimestamp) +
sizeof(EventCapNo);
@@ -699,7 +725,7 @@ void postCapsetEvent (EventTypeNum tag,
case EVENT_OSPROCESS_PID: // (capset, pid)
case EVENT_OSPROCESS_PPID: // (capset, parent_pid)
{
- postWord32(&eventBuf, info);
+ postOSProcessId(&eventBuf, info);
break;
}
default:
@@ -914,6 +940,62 @@ void postEventGcStats (Capability *cap,
postWord64(eb, par_tot_copied);
}
+void postTaskCreateEvent (EventTaskId taskId,
+ EventCapNo capno,
+ EventKernelThreadId tid)
+{
+ ACQUIRE_LOCK(&eventBufMutex);
+
+ if (!hasRoomForEvent(&eventBuf, EVENT_TASK_CREATE)) {
+ // Flush event buffer to make room for new event.
+ printAndClearEventBuf(&eventBuf);
+ }
+
+ postEventHeader(&eventBuf, EVENT_TASK_CREATE);
+ /* EVENT_TASK_CREATE (taskID, cap, tid) */
+ postTaskId(&eventBuf, taskId);
+ postCapNo(&eventBuf, capno);
+ postKernelThreadId(&eventBuf, tid);
+
+ RELEASE_LOCK(&eventBufMutex);
+}
+
+void postTaskMigrateEvent (EventTaskId taskId,
+ EventCapNo capno,
+ EventCapNo new_capno)
+{
+ ACQUIRE_LOCK(&eventBufMutex);
+
+ if (!hasRoomForEvent(&eventBuf, EVENT_TASK_MIGRATE)) {
+ // Flush event buffer to make room for new event.
+ printAndClearEventBuf(&eventBuf);
+ }
+
+ postEventHeader(&eventBuf, EVENT_TASK_MIGRATE);
+ /* EVENT_TASK_MIGRATE (taskID, cap, new_cap) */
+ postTaskId(&eventBuf, taskId);
+ postCapNo(&eventBuf, capno);
+ postCapNo(&eventBuf, new_capno);
+
+ RELEASE_LOCK(&eventBufMutex);
+}
+
+void postTaskDeleteEvent (EventTaskId taskId)
+{
+ ACQUIRE_LOCK(&eventBufMutex);
+
+ if (!hasRoomForEvent(&eventBuf, EVENT_TASK_DELETE)) {
+ // Flush event buffer to make room for new event.
+ printAndClearEventBuf(&eventBuf);
+ }
+
+ postEventHeader(&eventBuf, EVENT_TASK_DELETE);
+ /* EVENT_TASK_DELETE (taskID) */
+ postTaskId(&eventBuf, taskId);
+
+ RELEASE_LOCK(&eventBufMutex);
+}
+
void
postEvent (Capability *cap, EventTypeNum tag)
{
diff --git a/rts/eventlog/EventLog.h b/rts/eventlog/EventLog.h
index b8ee56aa3b..93dd9a8144 100644
--- a/rts/eventlog/EventLog.h
+++ b/rts/eventlog/EventLog.h
@@ -28,11 +28,11 @@ void abortEventLogging(void); // #4512 - after fork child needs to abort
void flushEventLog(void); // event log inherited from parent
void moreCapEventBufs (nat from, nat to);
-/*
+/*
* Post a scheduler event to the capability's event buffer (an event
* that has an associated thread).
*/
-void postSchedEvent(Capability *cap, EventTypeNum tag,
+void postSchedEvent(Capability *cap, EventTypeNum tag,
StgThreadID id, StgWord info1, StgWord info2);
/*
@@ -40,7 +40,7 @@ void postSchedEvent(Capability *cap, EventTypeNum tag,
*/
void postEvent(Capability *cap, EventTypeNum tag);
-void postEventAtTimestamp (Capability *cap, EventTimestamp ts,
+void postEventAtTimestamp (Capability *cap, EventTimestamp ts,
EventTypeNum tag);
void postMsg(char *msg, va_list ap);
@@ -81,7 +81,7 @@ void postCapsetVecEvent (EventTypeNum tag,
void postWallClockTime (EventCapsetID capset);
-/*
+/*
* Post a `par` spark event
*/
void postSparkEvent(Capability *cap, EventTypeNum tag, StgWord info1);
@@ -89,7 +89,7 @@ void postSparkEvent(Capability *cap, EventTypeNum tag, StgWord info1);
/*
* Post an event with several counters relating to `par` sparks.
*/
-void postSparkCountersEvent (Capability *cap,
+void postSparkCountersEvent (Capability *cap,
SparkCounters counters,
StgWord remaining);
@@ -125,6 +125,16 @@ void postEventGcStats (Capability *cap,
lnat par_max_copied,
lnat par_tot_copied);
+void postTaskCreateEvent (EventTaskId taskId,
+ EventCapNo cap,
+ EventKernelThreadId tid);
+
+void postTaskMigrateEvent (EventTaskId taskId,
+ EventCapNo capno,
+ EventCapNo new_capno);
+
+void postTaskDeleteEvent (EventTaskId taskId);
+
#else /* !TRACING */
INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED,
@@ -138,12 +148,12 @@ INLINE_HEADER void postEvent (Capability *cap STG_UNUSED,
EventTypeNum tag STG_UNUSED)
{ /* nothing */ }
-INLINE_HEADER void postMsg (char *msg STG_UNUSED,
+INLINE_HEADER void postMsg (char *msg STG_UNUSED,
va_list ap STG_UNUSED)
{ /* nothing */ }
INLINE_HEADER void postCapMsg (Capability *cap STG_UNUSED,
- char *msg STG_UNUSED,
+ char *msg STG_UNUSED,
va_list ap STG_UNUSED)
{ /* nothing */ }
@@ -152,7 +162,7 @@ INLINE_HEADER void postThreadLabel(Capability *cap STG_UNUSED,
EventThreadID id STG_UNUSED,
char *label STG_UNUSED)
{ /* nothing */ }
-
+
#endif
#include "EndPrivate.h"