diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2021-03-05 11:20:39 +0000 |
---|---|---|
committer | Matthew Pickering <matthewtpickering@gmail.com> | 2021-03-07 12:09:01 +0000 |
commit | 29c54366989e1e8f1462707e45b7f19d48e4aea1 (patch) | |
tree | b61bd5de33e7a79d33686864870f12bf59fb0a33 /rts/eventlog/EventLog.c | |
parent | cf65cf16c89414273c4f6b2d090d4b2fffb90759 (diff) | |
download | haskell-wip/ghc-eventlog-repost.tar.gz |
eventlog: Repost initialisation events when eventlog restartswip/ghc-eventlog-repost
If startEventlog is called after the program has already started running
then quite a few useful events are missing from the eventlog because
they are only posted when the program starts. This patch adds a
mechanism to declare that an event should be reposted everytime the
startEventlog function is called.
Now in EventLog.c there is a global list of functions called
`eventlog_header_funcs` which stores a list of functions which should be
called everytime the eventlog starts.
When calling `postInitEvent`, the event will not only be immediately
posted to the eventlog but also added to the global list.
When startEventLog is called, the list is traversed and the events
reposted.
Diffstat (limited to 'rts/eventlog/EventLog.c')
-rw-r--r-- | rts/eventlog/EventLog.c | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index 0a1ed09f6f..80ed91960d 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -89,6 +89,10 @@ bool eventlog_enabled; // protected by state_change_mutex to ensure static const EventLogWriter *event_log_writer = NULL; +// List of initialisation functions which are called each time the +// eventlog is restarted +static eventlog_init_func_t *eventlog_header_funcs = NULL; + #define EVENT_LOG_SIZE 2 * (1024 * 1024) // 2MB static int flushCount; @@ -211,6 +215,8 @@ static void closeBlockMarker(EventsBuf *ebuf); static StgBool hasRoomForEvent(EventsBuf *eb, EventTypeNum eNum); static StgBool hasRoomForVariableEvent(EventsBuf *eb, uint32_t payload_bytes); +static void freeEventLoggingBuffer(void); + static void ensureRoomForEvent(EventsBuf *eb, EventTypeNum tag); static int ensureRoomForVariableEvent(EventsBuf *eb, StgWord16 size); @@ -602,6 +608,50 @@ postHeaderEvents(void) postInt32(&eventBuf, EVENT_DATA_BEGIN); } +// These events will be reposted everytime we restart the eventlog +void +postInitEvent(EventlogInitPost post_init){ + ACQUIRE_LOCK(&state_change_mutex); + + // Add the event to the global list of events that will be rerun when + // the eventlog is restarted. + eventlog_init_func_t * new_func; + new_func = stgMallocBytes(sizeof(eventlog_init_func_t),"eventlog_init_func"); + new_func->init_func = post_init; + new_func->next = eventlog_header_funcs; + eventlog_header_funcs = new_func; + + RELEASE_LOCK(&state_change_mutex); + // Actually post it + (*post_init)(); + return; +} + +// Post events again which happened at the start of the eventlog, added by +// postInitEvent. +static void repostInitEvents(void){ + eventlog_init_func_t * current_event = eventlog_header_funcs; + for (; current_event != NULL; current_event = current_event->next) { + (*(current_event->init_func))(); + } + return; +} + +// Clear the eventlog_header_funcs list and free the memory +void resetInitEvents(void){ + eventlog_init_func_t * tmp; + eventlog_init_func_t * current_event = eventlog_header_funcs; + for (; current_event != NULL; ) { + tmp = current_event; + current_event = current_event->next; + stgFree(tmp); + } + eventlog_header_funcs = NULL; + return; + +} + + static uint32_t get_n_capabilities(void) { @@ -689,6 +739,7 @@ startEventLogging(const EventLogWriter *ev_writer) event_log_writer = ev_writer; bool ret = startEventLogging_(); eventlog_enabled = true; + repostInitEvents(); RELEASE_LOCK(&state_change_mutex); return ret; } @@ -697,11 +748,12 @@ startEventLogging(const EventLogWriter *ev_writer) void restartEventLogging(void) { - freeEventLogging(); + freeEventLoggingBuffer(); stopEventLogWriter(); initEventLogging(); // allocate new per-capability buffers if (event_log_writer != NULL) { startEventLogging_(); // child starts its own eventlog + repostInitEvents(); // Repost the initialisation events } } @@ -782,15 +834,21 @@ moreCapEventBufs (uint32_t from, uint32_t to) } } - -void -freeEventLogging(void) +static void +freeEventLoggingBuffer(void) { if (capEventBuf != NULL) { stgFree(capEventBuf); } } +void +freeEventLogging(void) +{ + freeEventLoggingBuffer(); + resetInitEvents(); +} + /* * Post an event message to the capability's eventlog buffer. * If the buffer is full, prints out the buffer and clears it. |