diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-09-06 05:28:56 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-11-23 18:54:41 -0500 |
commit | e43e6ece1418f84e50d572772394ab639a083e79 (patch) | |
tree | 0404fb13a6aff166b8f0561b4f40ae980d36f2bc /rts | |
parent | 8a33abfcdf5a3ae9ae1777b92891890d6a045f8b (diff) | |
download | haskell-e43e6ece1418f84e50d572772394ab639a083e79.tar.gz |
rts: Expose interface for configuring EventLogWriters
This exposes a set of interfaces from the GHC API for configuring
EventLogWriters. These can be used by consumers like
[ghc-eventlog-socket](https://github.com/bgamari/ghc-eventlog-socket).
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Trace.c | 29 | ||||
-rw-r--r-- | rts/eventlog/EventLog.c | 100 | ||||
-rw-r--r-- | rts/eventlog/EventLog.h | 6 | ||||
-rw-r--r-- | rts/eventlog/EventLogWriter.c | 1 |
4 files changed, 88 insertions, 48 deletions
diff --git a/rts/Trace.c b/rts/Trace.c index 8e44716eb0..b35be3c1e7 100644 --- a/rts/Trace.c +++ b/rts/Trace.c @@ -40,21 +40,12 @@ int TRACE_cap; static Mutex trace_utx; #endif -static bool eventlog_enabled; - /* --------------------------------------------------------------------------- Starting up / shutting down the tracing facilities --------------------------------------------------------------------------- */ -static const EventLogWriter *getEventLogWriter(void) -{ - return rtsConfig.eventlog_writer; -} - void initTracing (void) { - const EventLogWriter *eventlog_writer = getEventLogWriter(); - #if defined(THREADED_RTS) initMutex(&trace_utx); #endif @@ -95,15 +86,14 @@ void initTracing (void) TRACE_spark_full || TRACE_user; - eventlog_enabled = RtsFlags.TraceFlags.tracing == TRACE_EVENTLOG && - eventlog_writer != NULL; - /* Note: we can have any of the TRACE_* flags turned on even when eventlog_enabled is off. In the DEBUG way we may be tracing to stderr. */ + initEventLogging(); - if (eventlog_enabled) { - initEventLogging(eventlog_writer); + if (RtsFlags.TraceFlags.tracing == TRACE_EVENTLOG + && rtsConfig.eventlog_writer != NULL) { + startEventLogging(rtsConfig.eventlog_writer); } } @@ -121,17 +111,10 @@ void freeTracing (void) } } +// Used to reset tracing in a forked child void resetTracing (void) { - const EventLogWriter *eventlog_writer; - eventlog_writer = getEventLogWriter(); - - if (eventlog_enabled) { - abortEventLogging(); // abort eventlog inherited from parent - if (eventlog_writer != NULL) { - initEventLogging(eventlog_writer); // child starts its own eventlog - } - } + restartEventLogging(); } void flushTrace (void) diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index 5f22af5bfc..e3597cd73c 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -26,7 +26,9 @@ #include <unistd.h> #endif -static const EventLogWriter *event_log_writer; +bool eventlog_enabled; + +static const EventLogWriter *event_log_writer = NULL; #define EVENT_LOG_SIZE 2 * (1024 * 1024) // 2MB @@ -516,16 +518,22 @@ postHeaderEvents(void) postInt32(&eventBuf, EVENT_DATA_BEGIN); } -void -initEventLogging(const EventLogWriter *ev_writer) +static uint32_t +get_n_capabilities(void) { - uint32_t n_caps; +#if defined(THREADED_RTS) + // XXX n_capabilities may not have been initialized yet + return (n_capabilities != 0) ? n_capabilities : RtsFlags.ParFlags.nCapabilities; +#else + return 1; +#endif +} +void +initEventLogging() +{ init_event_types(); - event_log_writer = ev_writer; - initEventLogWriter(); - int num_descs = sizeof(EventDesc) / sizeof(char*); if (num_descs != NUM_GHC_EVENT_TAGS) { barf("EventDesc array has the wrong number of elements (%d, NUM_GHC_EVENT_TAGS=%d)", @@ -542,18 +550,28 @@ initEventLogging(const EventLogWriter *ev_writer) * Use a single buffer to store the header with event types, then flush * the buffer so all buffers are empty for writing events. */ -#if defined(THREADED_RTS) - // XXX n_capabilities hasn't been initialized yet - n_caps = RtsFlags.ParFlags.nCapabilities; -#else - n_caps = 1; -#endif - moreCapEventBufs(0, n_caps); + moreCapEventBufs(0, get_n_capabilities()); initEventsBuf(&eventBuf, EVENT_LOG_SIZE, (EventCapNo)(-1)); #if defined(THREADED_RTS) initMutex(&eventBufMutex); #endif +} + +enum EventLogStatus +eventLogStatus(void) +{ + if (eventlog_enabled) { + return EVENTLOG_RUNNING; + } else { + return EVENTLOG_NOT_CONFIGURED; + } +} + +static bool +startEventLogging_(void) +{ + initEventLogWriter(); postHeaderEvents(); @@ -564,14 +582,42 @@ initEventLogging(const EventLogWriter *ev_writer) */ printAndClearEventBuf(&eventBuf); - for (uint32_t c = 0; c < n_caps; ++c) { + for (uint32_t c = 0; c < get_n_capabilities(); ++c) { postBlockMarker(&capEventBuf[c]); } + return true; +} + +bool +startEventLogging(const EventLogWriter *ev_writer) +{ + if (eventlog_enabled || event_log_writer) { + return false; + } + + eventlog_enabled = true; + event_log_writer = ev_writer; + return startEventLogging_(); +} + +// Called during forkProcess in the child to restart the eventlog writer. +void +restartEventLogging(void) +{ + freeEventLogging(); + stopEventLogWriter(); + initEventLogging(); // allocate new per-capability buffers + if (event_log_writer != NULL) { + startEventLogging_(); // child starts its own eventlog + } } void endEventLogging(void) { + if (!eventlog_enabled) + return; + // Flush all events remaining in the buffers. for (uint32_t c = 0; c < n_capabilities; ++c) { printAndClearEventBuf(&capEventBuf[c]); @@ -586,6 +632,8 @@ endEventLogging(void) printAndClearEventBuf(&eventBuf); stopEventLogWriter(); + event_log_writer = NULL; + eventlog_enabled = false; } void @@ -626,13 +674,6 @@ freeEventLogging(void) } } -void -abortEventLogging(void) -{ - freeEventLogging(); - stopEventLogWriter(); -} - /* * Post an event message to the capability's eventlog buffer. * If the buffer is full, prints out the buffer and clears it. @@ -1440,7 +1481,7 @@ void printAndClearEventBuf (EventsBuf *ebuf) size_t elog_size = ebuf->pos - ebuf->begin; if (!writeEventLog(ebuf->begin, elog_size)) { debugBelch( - "printAndClearEventLog: could not flush event log" + "printAndClearEventLog: could not flush event log\n" ); resetEventsBuf(ebuf); return; @@ -1524,4 +1565,17 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +#else + +enum EventLogStatus eventLogStatus(void) +{ + return EVENTLOG_NOT_SUPPORTED; +} + +bool startEventLogging(const EventLogWriter *writer STG_UNUSED) { + return false; +} + +void endEventLogging(void) {} + #endif /* TRACING */ diff --git a/rts/eventlog/EventLog.h b/rts/eventlog/EventLog.h index 5bd3b5dadb..eca76619cd 100644 --- a/rts/eventlog/EventLog.h +++ b/rts/eventlog/EventLog.h @@ -22,8 +22,10 @@ */ extern char *EventTagDesc[]; -void initEventLogging(const EventLogWriter *writer); -void endEventLogging(void); +extern bool eventlog_enabled; + +void initEventLogging(void); +void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort void flushEventLog(void); // event log inherited from parent diff --git a/rts/eventlog/EventLogWriter.c b/rts/eventlog/EventLogWriter.c index 4b486926a7..b19e617a4c 100644 --- a/rts/eventlog/EventLogWriter.c +++ b/rts/eventlog/EventLogWriter.c @@ -122,6 +122,7 @@ stopEventLogFileWriter(void) { if (event_log_file != NULL) { fclose(event_log_file); + event_log_file = NULL; } } |