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/eventlog | |
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/eventlog')
-rw-r--r-- | rts/eventlog/EventLog.c | 100 | ||||
-rw-r--r-- | rts/eventlog/EventLog.h | 6 | ||||
-rw-r--r-- | rts/eventlog/EventLogWriter.c | 1 |
3 files changed, 82 insertions, 25 deletions
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; } } |