diff options
author | alexbiehl <alex.biehl@gmail.com> | 2017-01-31 16:06:33 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-01-31 18:50:21 -0500 |
commit | 4dfc6d1c40b298d4b8f136e46420227eda60a03d (patch) | |
tree | fce2d978323653ff0ff989fdb72f3585be5b4de4 /rts/eventlog/EventLog.c | |
parent | 44f079f74869d8cb417e2dcc104517ae7f593e5f (diff) | |
download | haskell-4dfc6d1c40b298d4b8f136e46420227eda60a03d.tar.gz |
Abstract over the way eventlogs are flushed
Currently eventlog data is always written to a file `progname.eventlog`.
This patch introduces the `flushEventLog` field in `RtsConfig` which
allows to customize the writing of eventlog data.
One possible scenario is the ongoing live-profile-monitor effort by
@NCrashed which slurps all eventlog data through `fluchEventLog`.
`flushEventLog` takes a buffer with eventlog data and its size and
returns `false` (0) in case eventlog data could not be procesed.
Reviewers: simonmar, austin, erikd, bgamari
Reviewed By: simonmar, bgamari
Subscribers: qnikst, thomie, NCrashed
Differential Revision: https://phabricator.haskell.org/D2934
Diffstat (limited to 'rts/eventlog/EventLog.c')
-rw-r--r-- | rts/eventlog/EventLog.c | 128 |
1 files changed, 51 insertions, 77 deletions
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index 4e4bdb5191..ce4cb3847a 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -26,13 +26,7 @@ #include <unistd.h> #endif -// PID of the process that writes to event_log_filename (#4512) -static pid_t event_log_pid = -1; - -static char *event_log_filename = NULL; - -// File for logging events -FILE *event_log_file = NULL; +static const EventLogWriter *event_log_writer; #define EVENT_LOG_SIZE 2 * (1024 * 1024) // 2MB @@ -232,55 +226,55 @@ static inline void postInt32(EventsBuf *eb, StgInt32 i) #define EVENT_SIZE_DYNAMIC (-1) -void -initEventLogging(void) +static void +initEventLogWriter(void) { - StgWord8 t, c; - uint32_t n_caps; - char *prog; - - prog = stgMallocBytes(strlen(prog_name) + 1, "initEventLogging"); - strcpy(prog, prog_name); -#ifdef mingw32_HOST_OS - // on Windows, drop the .exe suffix if there is one - { - char *suff; - suff = strrchr(prog,'.'); - if (suff != NULL && !strcmp(suff,".exe")) { - *suff = '\0'; - } + if (event_log_writer != NULL && + event_log_writer->initEventLogWriter != NULL) { + event_log_writer->initEventLogWriter(); } -#endif +} - event_log_filename = stgMallocBytes(strlen(prog) - + 10 /* .%d */ - + 10 /* .eventlog */, - "initEventLogging"); +static bool +writeEventLog(void *eventlog, size_t eventlog_size) +{ + if (event_log_writer != NULL && + event_log_writer->writeEventLog != NULL) { + return event_log_writer->writeEventLog(eventlog, eventlog_size); + } else { + return false; + } +} - if (sizeof(EventDesc) / sizeof(char*) != NUM_GHC_EVENT_TAGS) { - barf("EventDesc array has the wrong number of elements"); +static void +stopEventLogWriter(void) +{ + if (event_log_writer != NULL && + event_log_writer->stopEventLogWriter != NULL) { + event_log_writer->stopEventLogWriter(); } +} - if (event_log_pid == -1) { // #4512 - // Single process - sprintf(event_log_filename, "%s.eventlog", prog); - event_log_pid = getpid(); - } else { - // Forked process, eventlog already started by the parent - // before fork - event_log_pid = getpid(); - // We don't have a FMT* symbol for pid_t, so we go via Word64 - // to be sure of not losing range. It would be nicer to have a - // FMT* symbol or similar, though. - sprintf(event_log_filename, "%s.%" FMT_Word64 ".eventlog", - prog, (StgWord64)event_log_pid); +void +flushEventLog(void) +{ + if (event_log_writer != NULL && + event_log_writer->flushEventLog != NULL) { + event_log_writer->flushEventLog(); } - stgFree(prog); +} + +void +initEventLogging(const EventLogWriter *ev_writer) +{ + StgWord8 t, c; + uint32_t n_caps; + + event_log_writer = ev_writer; + initEventLogWriter(); - /* Open event log file for writing. */ - if ((event_log_file = fopen(event_log_filename, "wb")) == NULL) { - sysErrorBelch("initEventLogging: can't open %s", event_log_filename); - stg_exit(EXIT_FAILURE); + if (sizeof(EventDesc) / sizeof(char*) != NUM_GHC_EVENT_TAGS) { + barf("EventDesc array has the wrong number of elements"); } /* @@ -522,9 +516,7 @@ endEventLogging(void) // Flush the end of data marker. printAndClearEventBuf(&eventBuf); - if (event_log_file != NULL) { - fclose(event_log_file); - } + stopEventLogWriter(); } void @@ -568,26 +560,13 @@ freeEventLogging(void) if (capEventBuf != NULL) { stgFree(capEventBuf); } - if (event_log_filename != NULL) { - stgFree(event_log_filename); - } -} - -void -flushEventLog(void) -{ - if (event_log_file != NULL) { - fflush(event_log_file); - } } void abortEventLogging(void) { freeEventLogging(); - if (event_log_file != NULL) { - fclose(event_log_file); - } + stopEventLogWriter(); } /* @@ -1287,18 +1266,13 @@ void printAndClearEventBuf (EventsBuf *ebuf) if (ebuf->begin != NULL && ebuf->pos != ebuf->begin) { - StgInt8 *begin = ebuf->begin; - while (begin < ebuf->pos) { - StgWord64 remain = ebuf->pos - begin; - StgWord64 written = fwrite(begin, 1, remain, event_log_file); - if (written == 0) { - debugBelch( - "printAndClearEventLog: fwrite() failed to write anything;" - " tried to write numBytes=%" FMT_Word64, remain); - resetEventsBuf(ebuf); - return; - } - begin += written; + size_t elog_size = ebuf->pos - ebuf->begin; + if (!writeEventLog(ebuf->begin, elog_size)) { + debugBelch( + "printAndClearEventLog: could not flush event log" + ); + resetEventsBuf(ebuf); + return; } resetEventsBuf(ebuf); |