summaryrefslogtreecommitdiff
path: root/rts/eventlog/EventLog.c
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2021-03-05 11:20:39 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2021-03-07 12:09:01 +0000
commit29c54366989e1e8f1462707e45b7f19d48e4aea1 (patch)
treeb61bd5de33e7a79d33686864870f12bf59fb0a33 /rts/eventlog/EventLog.c
parentcf65cf16c89414273c4f6b2d090d4b2fffb90759 (diff)
downloadhaskell-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.c66
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.