summaryrefslogtreecommitdiff
path: root/rts/eventlog/EventLog.c
diff options
context:
space:
mode:
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.