diff options
Diffstat (limited to 'rts/eventlog/EventLog.c')
-rw-r--r-- | rts/eventlog/EventLog.c | 212 |
1 files changed, 144 insertions, 68 deletions
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index bd887afa8e..448611675a 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -6,16 +6,17 @@ * * ---------------------------------------------------------------------------*/ -#ifdef EVENTLOG - #include "PosixSource.h" #include "Rts.h" -#include "EventLog.h" +#ifdef TRACING + +#include "Trace.h" #include "Capability.h" #include "Trace.h" #include "RtsUtils.h" #include "Stats.h" +#include "EventLog.h" #include <string.h> #include <stdio.h> @@ -36,7 +37,12 @@ typedef struct _EventsBuf { StgWord64 size; } EventsBuf; -EventsBuf *eventsBuf; +EventsBuf *capEventBuf; // one EventsBuf for each Capability + +EventsBuf eventBuf; // an EventsBuf not associated with any Capability +#ifdef THREADED_RTS +Mutex eventBufMutex; // protected by this mutex +#endif char *EventDesc[] = { [EVENT_CREATE_THREAD] = "Create thread", @@ -52,9 +58,10 @@ char *EventDesc[] = { [EVENT_GC_END] = "Finished GC", [EVENT_REQUEST_SEQ_GC] = "Request sequential GC", [EVENT_REQUEST_PAR_GC] = "Request parallel GC", - [EVENT_CREATE_SPARK] = "Create spark", - [EVENT_SPARK_TO_THREAD] = "Spark to thread", /* DEPRECATED! */ - [EVENT_CREATE_SPARK_THREAD] = "Create spark thread" + [EVENT_CREATE_SPARK_THREAD] = "Create spark thread", + [EVENT_LOG_CAP_MSG] = "Log Capability message", + [EVENT_LOG_MSG] = "Log message", + [EVENT_STARTUP] = "Startup" }; // Event type. @@ -83,6 +90,7 @@ static void endEventTypes(EventsBuf *eb); static void postEventType(EventsBuf *eb, EventType *et); static StgBool hasRoomForEvent(EventsBuf *eb, EventTypeNum eNum); +static StgBool hasRoomForVariableEvent(EventsBuf *eb, nat payload_bytes); static inline void postWord8(EventsBuf *eb, StgWord8 i) { @@ -107,6 +115,12 @@ static inline void postWord64(EventsBuf *eb, StgWord64 i) postWord32(eb, (StgWord32)i); } +static inline void postBuf(EventsBuf *eb, StgWord8 *buf, nat size) +{ + memcpy(eb->pos, buf, size); + eb->pos += size; +} + static inline void postEventTypeNum(EventsBuf *eb, EventTypeNum etNum) { postWord16(eb, etNum); } @@ -119,6 +133,9 @@ static inline void postThreadID(EventsBuf *eb, EventThreadID id) static inline void postCapNo(EventsBuf *eb, EventCapNo no) { postWord16(eb,no); } +static inline void postPayloadSize(EventsBuf *eb, EventPayloadSize size) +{ postWord16(eb,size); } + static inline void postInt8(EventsBuf *eb, StgInt8 i) { postWord8(eb, (StgWord8)i); } @@ -136,8 +153,7 @@ void initEventLogging(void) { StgWord8 t, c; - - debugTrace(DEBUG_eventlog, "intiEventLog: start"); + nat n_caps; event_log_filename = stgMallocBytes(strlen(prog_name) + 10, "initEventLogging"); @@ -164,18 +180,25 @@ initEventLogging(void) * Use a single buffer to store the header with event types, then flush * the buffer so all buffers are empty for writing events. */ - eventsBuf = stgMallocBytes(n_capabilities * sizeof(EventsBuf),"initEventLogging"); - - for (c = 0; c < n_capabilities; ++c) { +#ifdef THREADED_RTS + // XXX n_capabilities hasn't been initislised yet + n_caps = RtsFlags.ParFlags.nNodes; +#else + n_caps = 1; +#endif + capEventBuf = stgMallocBytes(n_caps * sizeof(EventsBuf),"initEventLogging"); + + for (c = 0; c < n_caps; ++c) { // Init buffer for events. - initEventsBuf(&eventsBuf[c], EVENT_LOG_SIZE); + initEventsBuf(&capEventBuf[c], EVENT_LOG_SIZE); } + initEventsBuf(&eventBuf, EVENT_LOG_SIZE); // Write in buffer: the header begin marker. - beginHeader(&eventsBuf[0]); + beginHeader(&eventBuf); // Mark beginning of event types in the header. - beginEventTypes(&eventsBuf[0]); + beginEventTypes(&eventBuf); for (t = 0; t < NUM_EVENT_TAGS; ++t) { eventTypes[t].etNum = t; @@ -185,7 +208,6 @@ initEventLogging(void) case EVENT_CREATE_THREAD: // (cap, thread) case EVENT_RUN_THREAD: // (cap, thread) case EVENT_THREAD_RUNNABLE: // (cap, thread) - case EVENT_CREATE_SPARK: // (cap, thread) case EVENT_RUN_SPARK: // (cap, thread) case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread) eventTypes[t].size = sizeof(EventCapNo) + sizeof(EventThreadID); @@ -210,29 +232,35 @@ initEventLogging(void) case EVENT_GC_END: // (cap) eventTypes[t].size = sizeof(EventCapNo); break; + + case EVENT_LOG_MSG: // (msg) + case EVENT_LOG_CAP_MSG: // (cap,msg) + eventTypes[t].size = 0xffff; + break; + + default: + continue; /* ignore deprecated events */ } // Write in buffer: the start event type. - postEventType(&eventsBuf[0], &eventTypes[t]); + postEventType(&eventBuf, &eventTypes[t]); } // Mark end of event types in the header. - endEventTypes(&eventsBuf[0]); + endEventTypes(&eventBuf); // Write in buffer: the header end marker. - endHeader(&eventsBuf[0]); + endHeader(&eventBuf); // Prepare event buffer for events (data). - beginData(&eventsBuf[0]); + beginData(&eventBuf); - // Flush eventsBuf with header. + // Flush capEventBuf with header. /* * Flush header and data begin marker to the file, thus preparing the * file to have events written to it. */ - printAndClearEventBuf(&eventsBuf[0]); - - debugTrace(DEBUG_eventlog, "initEventLog: finish"); + printAndClearEventBuf(&eventBuf); } void @@ -240,46 +268,39 @@ endEventLogging(void) { nat c; - debugTrace(DEBUG_eventlog,"endEventLog: start"); - // Flush all events remaining in the buffers. for (c = 0; c < n_capabilities; ++c) { - printAndClearEventBuf(&eventsBuf[c]); + printAndClearEventBuf(&capEventBuf[c]); } + printAndClearEventBuf(&eventBuf); // Mark end of events (data). - endData(&eventsBuf[0]); + endData(&eventBuf); // Flush the end of data marker. - printAndClearEventBuf(&eventsBuf[0]); + printAndClearEventBuf(&eventBuf); if (event_log_file != NULL) { fclose(event_log_file); } - - debugTrace(DEBUG_eventlog,"endEventLog: finish"); } void freeEventLogging(void) { StgWord8 c; - - debugTrace(DEBUG_eventlog,"freeEventLog: start"); // Free events buffer. for (c = 0; c < n_capabilities; ++c) { - if (eventsBuf[c].begin != NULL) - stgFree(eventsBuf[c].begin); + if (capEventBuf[c].begin != NULL) + stgFree(capEventBuf[c].begin); } - if (eventsBuf != NULL) { - stgFree(eventsBuf); + if (capEventBuf != NULL) { + stgFree(capEventBuf); } if (event_log_filename != NULL) { stgFree(event_log_filename); } - - debugTrace(DEBUG_eventlog,"freeEventLog: finish"); } /* @@ -287,13 +308,14 @@ freeEventLogging(void) * If the buffer is full, prints out the buffer and clears it. */ void -postEvent_(Capability *cap, EventTypeNum tag, StgThreadID thread, StgWord64 other) +postSchedEvent (Capability *cap, + EventTypeNum tag, + StgThreadID thread, + StgWord64 other) { EventsBuf *eb; - debugTrace(DEBUG_eventlog,"postEvent: start"); - - eb = &eventsBuf[cap->no]; + eb = &capEventBuf[cap->no]; if (!hasRoomForEvent(eb, tag)) { // Flush event buffer to make room for new event. @@ -308,7 +330,6 @@ postEvent_(Capability *cap, EventTypeNum tag, StgThreadID thread, StgWord64 othe case EVENT_CREATE_THREAD: // (cap, thread) case EVENT_RUN_THREAD: // (cap, thread) case EVENT_THREAD_RUNNABLE: // (cap, thread) - case EVENT_CREATE_SPARK: // (cap, thread) case EVENT_RUN_SPARK: // (cap, thread) { postThreadID(eb,thread); @@ -328,7 +349,7 @@ postEvent_(Capability *cap, EventTypeNum tag, StgThreadID thread, StgWord64 othe postThreadID(eb,thread); postCapNo(eb,other /* new_cap | victim_cap | other_cap */); break; - } + } case EVENT_STOP_THREAD: // (cap, thread, status) { @@ -349,24 +370,73 @@ postEvent_(Capability *cap, EventTypeNum tag, StgThreadID thread, StgWord64 othe default: barf("postEvent: unknown event tag %d", tag); } +} + +#define BUF 512 + +void postMsg(char *msg, va_list ap) +{ + EventsBuf *eb; + char buf[BUF]; + nat size; + + size = vsnprintf(buf,BUF,msg,ap); + if (size > BUF) { + buf[BUF-1] = '\0'; + size = BUF; + } + + ACQUIRE_LOCK(&eventBufMutex); + eb = &eventBuf; + + if (!hasRoomForVariableEvent(eb, size)) { + // Flush event buffer to make room for new event. + printAndClearEventBuf(eb); + } + + postEventTypeNum(eb, EVENT_LOG_MSG); + postTimestamp(eb, stat_getElapsedTime() * (1000000000LL/TICKS_PER_SECOND)); + postPayloadSize(eb, size); + postBuf(eb,(StgWord8*)buf,size); + + RELEASE_LOCK(&eventBufMutex); +} + +void postCapMsg(Capability *cap, char *msg, va_list ap) +{ + EventsBuf *eb; + char buf[BUF]; + nat size; + + size = vsnprintf(buf,BUF,msg,ap); + if (size > BUF) { + buf[BUF-1] = '\0'; + size = BUF; + } + + eb = &capEventBuf[cap->no]; + + if (!hasRoomForVariableEvent(eb, size)) { + // Flush event buffer to make room for new event. + printAndClearEventBuf(eb); + } - debugTrace(DEBUG_eventlog,"postEvent: finish"); + postEventTypeNum(eb, EVENT_LOG_MSG); + postTimestamp(eb, stat_getElapsedTime() * (1000000000LL/TICKS_PER_SECOND)); + postPayloadSize(eb, size + sizeof(EventCapNo)); + postCapNo(eb, cap->no); + postBuf(eb,(StgWord8*)buf,size); } -static void printAndClearEventBuf (EventsBuf *eventsBuf) +static void printAndClearEventBuf (EventsBuf *ebuf) { StgWord64 numBytes = 0, written = 0; - if (eventsBuf->begin != NULL && eventsBuf->pos != eventsBuf->begin) + if (ebuf->begin != NULL && ebuf->pos != ebuf->begin) { - numBytes = eventsBuf->pos - eventsBuf->begin; - - debugTrace(DEBUG_eventlog, - "printAndEventLog: numbytes %" FMT_Word64 - " bytes to fwrite()", - numBytes); + numBytes = ebuf->pos - ebuf->begin; - written = fwrite(eventsBuf->begin, 1, numBytes, event_log_file); + written = fwrite(ebuf->begin, 1, numBytes, event_log_file); if (written != numBytes) { debugBelch( "printAndClearEventLog: fwrite() failed, written=%" FMT_Word64 @@ -374,11 +444,7 @@ static void printAndClearEventBuf (EventsBuf *eventsBuf) return; } - debugTrace(DEBUG_eventlog, - "printAndClearEventLog: fwrite(): %" FMT_Word64 - " bytes written", written); - - resetEventsBuf(eventsBuf); + resetEventsBuf(ebuf); flushCount++; } } @@ -386,11 +452,7 @@ static void printAndClearEventBuf (EventsBuf *eventsBuf) void printAndClearEventLog(Capability *cap) { - debugTrace(DEBUG_eventlog,"printAndClearEventLog: start"); - - printAndClearEventBuf(&eventsBuf[cap->no]); - - debugTrace(DEBUG_eventlog,"printAndClearEventLog: finish"); + printAndClearEventBuf(&capEventBuf[cap->no]); } /* ----------------------------------------------------------------------------- @@ -442,9 +504,9 @@ void endEventTypes(EventsBuf *eb) StgBool hasRoomForEvent(EventsBuf *eb, EventTypeNum eNum) { - nat size = 0; + nat size; - size += sizeof(EventTypeNum) + sizeof(EventTimestamp) + eventTypes[eNum].size; + size = sizeof(EventTypeNum) + sizeof(EventTimestamp) + eventTypes[eNum].size; if (eb->pos + size > eb->begin + eb->size) { return 0; // Not enough space. @@ -453,6 +515,20 @@ StgBool hasRoomForEvent(EventsBuf *eb, EventTypeNum eNum) } } +StgBool hasRoomForVariableEvent(EventsBuf *eb, nat payload_bytes) +{ + nat size; + + size = sizeof(EventTypeNum) + sizeof(EventTimestamp) + + sizeof(EventPayloadSize) + payload_bytes; + + if (eb->pos + size > eb->begin + eb->size) { + return 0; // Not enough space. + } else { + return 1; // Buf has enough space for the event. + } +} + static void postEventType(EventsBuf *eb, EventType *et) { StgWord8 d; @@ -470,4 +546,4 @@ static void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } -#endif /* EVENTLOG */ +#endif /* TRACING */ |