summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/RtsAPI.h5
-rw-r--r--includes/rts/EventLogWriter.h5
-rw-r--r--libraries/base/Debug/Trace.hs9
-rw-r--r--rts/Capability.c5
-rw-r--r--rts/Capability.h4
-rw-r--r--rts/RtsSymbols.c1
-rw-r--r--rts/Schedule.c2
-rw-r--r--rts/Trace.c4
-rw-r--r--rts/Trace.h1
-rw-r--r--rts/eventlog/EventLog.c43
-rw-r--r--rts/eventlog/EventLog.h7
11 files changed, 75 insertions, 11 deletions
diff --git a/includes/RtsAPI.h b/includes/RtsAPI.h
index 36ab4d4b04..f88cd0614c 100644
--- a/includes/RtsAPI.h
+++ b/includes/RtsAPI.h
@@ -18,8 +18,6 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
-#include "rts/EventLogWriter.h"
-
/*
* Running the scheduler
@@ -60,6 +58,9 @@ typedef struct CapabilityPublic_ {
StgRegTable r;
} CapabilityPublic;
+/* N.B. this needs the Capability declaration above. */
+#include "rts/EventLogWriter.h"
+
/* ----------------------------------------------------------------------------
RTS configuration settings, for passing to hs_init_ghc()
------------------------------------------------------------------------- */
diff --git a/includes/rts/EventLogWriter.h b/includes/rts/EventLogWriter.h
index 38a0c06086..73a2aec64c 100644
--- a/includes/rts/EventLogWriter.h
+++ b/includes/rts/EventLogWriter.h
@@ -68,3 +68,8 @@ bool startEventLogging(const EventLogWriter *writer);
* Stop event logging and destroy the current EventLogWriter.
*/
void endEventLogging(void);
+
+/*
+ * Flush the eventlog. cap can be NULL if one is not held.
+ */
+void flushEventLog(Capability **cap);
diff --git a/libraries/base/Debug/Trace.hs b/libraries/base/Debug/Trace.hs
index 453b5141b4..5a8b55126c 100644
--- a/libraries/base/Debug/Trace.hs
+++ b/libraries/base/Debug/Trace.hs
@@ -37,6 +37,7 @@ module Debug.Trace (
-- $eventlog_tracing
traceEvent,
traceEventIO,
+ flushEventLog,
-- * Execution phase markers
-- $markers
@@ -319,3 +320,11 @@ traceMarkerIO :: String -> IO ()
traceMarkerIO msg =
GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
case traceMarker# p s of s' -> (# s', () #)
+
+-- | Immediately flush the event log, if enabled.
+--
+-- @since 4.15.0.0
+flushEventLog :: IO ()
+flushEventLog = c_flushEventLog nullPtr
+
+foreign import ccall "flushEventLog" c_flushEventLog :: Ptr () -> IO ()
diff --git a/rts/Capability.c b/rts/Capability.c
index a655fc7b3f..dd24ce6681 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -23,6 +23,7 @@
#include "Schedule.h"
#include "Sparks.h"
#include "Trace.h"
+#include "eventlog/EventLog.h" // for flushLocalEventsBuf
#include "sm/GC.h" // for gcWorkerThread()
#include "STM.h"
#include "RtsUtils.h"
@@ -982,6 +983,10 @@ yieldCapability
debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks...");
break;
+ case SYNC_FLUSH_EVENT_LOG:
+ flushLocalEventsBuf(cap);
+ break;
+
default:
break;
}
diff --git a/rts/Capability.h b/rts/Capability.h
index 8c5b1e814e..df486829ea 100644
--- a/rts/Capability.h
+++ b/rts/Capability.h
@@ -27,6 +27,7 @@
#include "BeginPrivate.h"
+/* N.B. This must be consistent with CapabilityPublic in RtsAPI.h */
struct Capability_ {
// State required by the STG virtual machine when running Haskell
// code. During STG execution, the BaseReg register always points
@@ -267,7 +268,8 @@ typedef enum {
SYNC_OTHER,
SYNC_GC_SEQ,
SYNC_GC_PAR,
- SYNC_FLUSH_UPD_REM_SET
+ SYNC_FLUSH_UPD_REM_SET,
+ SYNC_FLUSH_EVENT_LOG
} SyncType;
//
diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c
index e433d9d369..7cd62faabe 100644
--- a/rts/RtsSymbols.c
+++ b/rts/RtsSymbols.c
@@ -594,6 +594,7 @@
SymI_HasProto(__word_encodeFloat) \
SymI_HasProto(stg_atomicallyzh) \
SymI_HasProto(barf) \
+ SymI_HasProto(flushEventLog) \
SymI_HasProto(deRefStablePtr) \
SymI_HasProto(debugBelch) \
SymI_HasProto(errorBelch) \
diff --git a/rts/Schedule.c b/rts/Schedule.c
index b7c1e7b0c0..a5bd11bf5e 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -2070,7 +2070,7 @@ forkProcess(HsStablePtr *entry
stopTimer(); // See #4074
#if defined(TRACING)
- flushEventLog(); // so that child won't inherit dirty file buffers
+ flushAllCapsEventsBufs(); // so that child won't inherit dirty file buffers
#endif
pid = fork();
diff --git a/rts/Trace.c b/rts/Trace.c
index 6d77cc1254..2a229b5dc2 100644
--- a/rts/Trace.c
+++ b/rts/Trace.c
@@ -118,10 +118,10 @@ void resetTracing (void)
restartEventLogging();
}
-void flushTrace (void)
+void flushTrace ()
{
if (eventlog_enabled) {
- flushEventLog();
+ flushEventLog(NULL);
}
}
diff --git a/rts/Trace.h b/rts/Trace.h
index 9c905af737..cad83363d3 100644
--- a/rts/Trace.h
+++ b/rts/Trace.h
@@ -319,7 +319,6 @@ void traceConcSweepEnd(void);
void traceConcUpdRemSetFlush(Capability *cap);
void traceNonmovingHeapCensus(uint32_t log_blk_size,
const struct NonmovingAllocCensus *census);
-
void flushTrace(void);
#else /* !TRACING */
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,