summaryrefslogtreecommitdiff
path: root/rts/eventlog
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-04-11 15:54:17 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-11-24 02:43:20 -0500
commitf88f43398217a5f4c2d326555e21fb1417a21db2 (patch)
treeb9d9e9d3de097959cc2463c2b21f5d3842ff6b86 /rts/eventlog
parent6815603f271484766425ff2e37043b78da2d073c (diff)
downloadhaskell-f88f43398217a5f4c2d326555e21fb1417a21db2.tar.gz
rts: Flush eventlog buffers from flushEventLog
As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043.
Diffstat (limited to 'rts/eventlog')
-rw-r--r--rts/eventlog/EventLog.c43
-rw-r--r--rts/eventlog/EventLog.h7
2 files changed, 46 insertions, 4 deletions
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c
index d093d595c7..824c554dcf 100644
--- a/rts/eventlog/EventLog.c
+++ b/rts/eventlog/EventLog.c
@@ -16,6 +16,7 @@
#include "RtsUtils.h"
#include "Stats.h"
#include "EventLog.h"
+#include "Schedule.h"
#include <string.h>
#include <stdio.h>
@@ -272,8 +273,8 @@ stopEventLogWriter(void)
}
}
-void
-flushEventLog(void)
+static void
+flushEventLogWriter(void)
{
if (event_log_writer != NULL &&
event_log_writer->flushEventLog != NULL) {
@@ -1541,7 +1542,7 @@ void printAndClearEventBuf (EventsBuf *ebuf)
"printAndClearEventLog: could not flush event log\n"
);
resetEventsBuf(ebuf);
- flushEventLog();
+ flushEventLogWriter();
return;
}
@@ -1623,6 +1624,40 @@ void postEventType(EventsBuf *eb, EventType *et)
postInt32(eb, EVENT_ET_END);
}
+void flushLocalEventsBuf(Capability *cap)
+{
+ EventsBuf *eb = &capEventBuf[cap->no];
+ printAndClearEventBuf(eb);
+}
+
+// Flush all capabilities' event buffers when we already hold all capabilities.
+// Used during forkProcess.
+void flushAllCapsEventsBufs()
+{
+ ACQUIRE_LOCK(&eventBufMutex);
+ printAndClearEventBuf(&eventBuf);
+ RELEASE_LOCK(&eventBufMutex);
+
+ for (unsigned int i=0; i < n_capabilities; i++) {
+ flushLocalEventsBuf(capabilities[i]);
+ }
+ flushEventLogWriter();
+}
+
+void flushEventLog(Capability **cap USED_IF_THREADS)
+{
+ ACQUIRE_LOCK(&eventBufMutex);
+ printAndClearEventBuf(&eventBuf);
+ RELEASE_LOCK(&eventBufMutex);
+
+#if defined(THREADED_RTS)
+ Task *task = getMyTask();
+ stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG);
+ releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task);
+#endif
+ flushEventLogWriter();
+}
+
#else
enum EventLogStatus eventLogStatus(void)
@@ -1636,4 +1671,6 @@ bool startEventLogging(const EventLogWriter *writer STG_UNUSED) {
void endEventLogging(void) {}
+void flushEventLog(Capability **cap STG_UNUSED) {}
+
#endif /* TRACING */
diff --git a/rts/eventlog/EventLog.h b/rts/eventlog/EventLog.h
index cf94a25ed6..e78db809c7 100644
--- a/rts/eventlog/EventLog.h
+++ b/rts/eventlog/EventLog.h
@@ -28,8 +28,10 @@ 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
void moreCapEventBufs (uint32_t from, uint32_t to);
+void flushLocalEventsBuf(Capability *cap);
+void flushAllCapsEventsBufs(void);
+void flushAllEventsBufs(Capability *cap);
/*
* Post a scheduler event to the capability's event buffer (an event
@@ -180,6 +182,9 @@ void postTickyCounterSamples(StgEntCounter *p);
#else /* !TRACING */
+INLINE_HEADER void flushLocalEventsBuf(Capability *cap STG_UNUSED)
+{ /* nothing */ }
+
INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED,
EventTypeNum tag STG_UNUSED,
StgThreadID id STG_UNUSED,