diff options
author | Duncan Coutts <duncan@well-typed.com> | 2012-07-03 19:28:40 +0100 |
---|---|---|
committer | Mikolaj Konarski <mikolaj@well-typed.com> | 2012-07-10 17:53:34 +0200 |
commit | 54c98b687a5e23f3371604dc4918dfb3106a74f8 (patch) | |
tree | 6f35fbe69fec9f26d14da6f0a146aef5a4a925f1 /rts/eventlog/EventLog.c | |
parent | 647ae1cfbb5ea3e2d3b1541c2bc12ea5db321134 (diff) | |
download | haskell-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/EventLog.c')
-rw-r--r-- | rts/eventlog/EventLog.c | 84 |
1 files changed, 83 insertions, 1 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) { |