diff options
author | Duncan Coutts <duncan@well-typed.com> | 2012-02-06 12:22:18 +0000 |
---|---|---|
committer | Duncan Coutts <duncan@well-typed.com> | 2012-04-04 19:10:44 +0100 |
commit | 65aaa9b2715c5245838123f3a0fa5d92e0a66bce (patch) | |
tree | c590a78588274f19285965d7b5cbd3b051a9329a /rts/eventlog | |
parent | cd930da1145a0d6094e5b5380034e80d002d5b9a (diff) | |
download | haskell-65aaa9b2715c5245838123f3a0fa5d92e0a66bce.tar.gz |
Add new eventlog events for various heap and GC statistics
They cover much the same info as is available via the GHC.Stats module
or via the '+RTS -s' textual output, but via the eventlog and with a
better sampling frequency.
We have three new generic heap info events and two very GHC-specific
ones. (The hope is the general ones are usable by other implementations
that use the same eventlog system, or indeed not so sensitive to changes
in GHC itself.)
The general ones are:
* total heap mem allocated since prog start, on a per-HEC basis
* current size of the heap (MBlocks reserved from OS for the heap)
* current size of live data in the heap
Currently these are all emitted by GHC at GC time (live data only at
major GC).
The GHC specific ones are:
* an event giving various static heap paramaters:
* number of generations (usually 2)
* max size if any
* nursary size
* MBlock and block sizes
* a event emitted on each GC containing:
* GC generation (usually just 0,1)
* total bytes copied
* bytes lost to heap slop and fragmentation
* the number of threads in the parallel GC (1 for serial)
* the maximum number of bytes copied by any par GC thread
* the total number of bytes copied by all par GC threads
(these last three can be used to calculate an estimate of the
work balance in parallel GCs)
Diffstat (limited to 'rts/eventlog')
-rw-r--r-- | rts/eventlog/EventLog.c | 125 | ||||
-rw-r--r-- | rts/eventlog/EventLog.h | 25 |
2 files changed, 150 insertions, 0 deletions
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index 8009a38938..a43ebf789a 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -71,6 +71,11 @@ char *EventDesc[] = { [EVENT_GC_END] = "Finished GC", [EVENT_REQUEST_SEQ_GC] = "Request sequential GC", [EVENT_REQUEST_PAR_GC] = "Request parallel GC", + [EVENT_GC_STATS_GHC] = "GC statistics", + [EVENT_HEAP_INFO_GHC] = "Heap static parameters", + [EVENT_HEAP_ALLOCATED] = "Total heap mem ever allocated", + [EVENT_HEAP_SIZE] = "Current heap size", + [EVENT_HEAP_LIVE] = "Current heap live data", [EVENT_CREATE_SPARK_THREAD] = "Create spark thread", [EVENT_LOG_MSG] = "Log message", [EVENT_USER_MSG] = "User message", @@ -358,6 +363,31 @@ initEventLogging(void) eventTypes[t].size = 7 * sizeof(StgWord64); break; + case EVENT_HEAP_ALLOCATED: // (heap_capset, alloc_bytes) + case EVENT_HEAP_SIZE: // (heap_capset, size_bytes) + case EVENT_HEAP_LIVE: // (heap_capset, live_bytes) + eventTypes[t].size = sizeof(EventCapsetID) + sizeof(StgWord64); + break; + + case EVENT_HEAP_INFO_GHC: // (heap_capset, n_generations, + // max_heap_size, alloc_area_size, + // mblock_size, block_size) + eventTypes[t].size = sizeof(EventCapsetID) + + sizeof(StgWord16) + + sizeof(StgWord64) * 4; + break; + + case EVENT_GC_STATS_GHC: // (heap_capset, generation, + // copied_bytes, slop_bytes, frag_bytes, + // par_n_threads, + // par_max_copied, par_tot_copied) + eventTypes[t].size = sizeof(EventCapsetID) + + sizeof(StgWord16) + + sizeof(StgWord64) * 3 + + sizeof(StgWord32) + + sizeof(StgWord64) * 2; + break; + case EVENT_BLOCK_MARKER: eventTypes[t].size = sizeof(StgWord32) + sizeof(EventTimestamp) + sizeof(EventCapNo); @@ -783,6 +813,101 @@ void postWallClockTime (EventCapsetID capset) RELEASE_LOCK(&eventBufMutex); } +/* + * Various GC and heap events + */ +void postHeapEvent (Capability *cap, + EventTypeNum tag, + EventCapsetID heap_capset, + lnat info1) +{ + EventsBuf *eb; + + eb = &capEventBuf[cap->no]; + + if (!hasRoomForEvent(eb, tag)) { + // Flush event buffer to make room for new event. + printAndClearEventBuf(eb); + } + + postEventHeader(eb, tag); + + switch (tag) { + case EVENT_HEAP_ALLOCATED: // (heap_capset, alloc_bytes) + case EVENT_HEAP_SIZE: // (heap_capset, size_bytes) + case EVENT_HEAP_LIVE: // (heap_capset, live_bytes) + { + postCapsetID(eb, heap_capset); + postWord64(eb,info1 /* alloc/size/live_bytes */); + break; + } + + default: + barf("postHeapEvent: unknown event tag %d", tag); + } +} + +void postEventHeapInfo (EventCapsetID heap_capset, + nat gens, + lnat maxHeapSize, + lnat allocAreaSize, + lnat mblockSize, + lnat blockSize) +{ + ACQUIRE_LOCK(&eventBufMutex); + + if (!hasRoomForEvent(&eventBuf, EVENT_HEAP_INFO_GHC)) { + // Flush event buffer to make room for new event. + printAndClearEventBuf(&eventBuf); + } + + postEventHeader(&eventBuf, EVENT_HEAP_INFO_GHC); + /* EVENT_HEAP_INFO_GHC (heap_capset, n_generations, + max_heap_size, alloc_area_size, + mblock_size, block_size) */ + postCapsetID(&eventBuf, heap_capset); + postWord16(&eventBuf, gens); + postWord64(&eventBuf, maxHeapSize); + postWord64(&eventBuf, allocAreaSize); + postWord64(&eventBuf, mblockSize); + postWord64(&eventBuf, blockSize); + + RELEASE_LOCK(&eventBufMutex); +} + +void postEventGcStats (Capability *cap, + EventCapsetID heap_capset, + nat gen, + lnat copied, + lnat slop, + lnat fragmentation, + nat par_n_threads, + lnat par_max_copied, + lnat par_tot_copied) +{ + EventsBuf *eb; + + eb = &capEventBuf[cap->no]; + + if (!hasRoomForEvent(eb, EVENT_GC_STATS_GHC)) { + // Flush event buffer to make room for new event. + printAndClearEventBuf(eb); + } + + postEventHeader(eb, EVENT_GC_STATS_GHC); + /* EVENT_GC_STATS_GHC (heap_capset, generation, + copied_bytes, slop_bytes, frag_bytes, + par_n_threads, par_max_copied, par_tot_copied) */ + postCapsetID(eb, heap_capset); + postWord16(eb, gen); + postWord64(eb, copied); + postWord64(eb, slop); + postWord64(eb, fragmentation); + postWord32(eb, par_n_threads); + postWord64(eb, par_max_copied); + postWord64(eb, par_tot_copied); +} + void postEvent (Capability *cap, EventTypeNum tag) { diff --git a/rts/eventlog/EventLog.h b/rts/eventlog/EventLog.h index 6a3b32dad3..dadc6fa6d9 100644 --- a/rts/eventlog/EventLog.h +++ b/rts/eventlog/EventLog.h @@ -97,6 +97,31 @@ void postThreadLabel(Capability *cap, EventThreadID id, char *label); +/* + * Various GC and heap events + */ +void postHeapEvent (Capability *cap, + EventTypeNum tag, + EventCapsetID heap_capset, + StgWord info1); + +void postEventHeapInfo (EventCapsetID heap_capset, + nat gens, + lnat maxHeapSize, + lnat allocAreaSize, + lnat mblockSize, + lnat blockSize); + +void postEventGcStats (Capability *cap, + EventCapsetID heap_capset, + nat gen, + lnat copied, + lnat slop, + lnat fragmentation, + nat par_n_threads, + lnat par_max_copied, + lnat par_tot_copied); + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, |