summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-11-18 20:15:07 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-01-29 02:40:45 -0500
commit2e29edb7421c21902b47d130d45f60d3f584a0de (patch)
tree1b07c17f1c3a07fd84f6f421c836e29435e2bb15 /rts
parent6b0cea298f7ad222879fafd2905293ab939ff8b3 (diff)
downloadhaskell-2e29edb7421c21902b47d130d45f60d3f584a0de.tar.gz
rts: Refactor event types
Previously we would build the eventTypes array at runtime during RTS initialization. However, this is completely unnecessary; it is completely static data.
Diffstat (limited to 'rts')
-rw-r--r--rts/eventlog/EventLog.c326
-rw-r--r--rts/eventlog/EventLog.h5
-rwxr-xr-xrts/gen_event_types.py214
-rw-r--r--rts/include/ghc.mk14
-rw-r--r--rts/include/rts/EventLogFormat.h109
-rw-r--r--rts/rts.cabal.in2
6 files changed, 236 insertions, 434 deletions
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c
index 5785b3b62b..85fd555439 100644
--- a/rts/eventlog/EventLog.c
+++ b/rts/eventlog/EventLog.c
@@ -115,93 +115,14 @@ static EventsBuf eventBuf; // an EventsBuf not associated with any Capability
static Mutex eventBufMutex; // protected by this mutex
#endif
-char *EventDesc[] = {
- [EVENT_CREATE_THREAD] = "Create thread",
- [EVENT_RUN_THREAD] = "Run thread",
- [EVENT_STOP_THREAD] = "Stop thread",
- [EVENT_THREAD_RUNNABLE] = "Thread runnable",
- [EVENT_MIGRATE_THREAD] = "Migrate thread",
- [EVENT_THREAD_WAKEUP] = "Wakeup thread",
- [EVENT_THREAD_LABEL] = "Thread label",
- [EVENT_CAP_CREATE] = "Create capability",
- [EVENT_CAP_DELETE] = "Delete capability",
- [EVENT_CAP_DISABLE] = "Disable capability",
- [EVENT_CAP_ENABLE] = "Enable capability",
- [EVENT_GC_START] = "Starting GC",
- [EVENT_GC_END] = "Finished GC",
- [EVENT_REQUEST_SEQ_GC] = "Request sequential GC",
- [EVENT_REQUEST_PAR_GC] = "Request parallel GC",
- [EVENT_GC_GLOBAL_SYNC] = "Synchronise stop-the-world GC",
- [EVENT_GC_STATS_GHC] = "GC statistics",
- [EVENT_MEM_RETURN] = "Memory return statistics",
- [EVENT_HEAP_INFO_GHC] = "Heap static parameters",
- [EVENT_HEAP_ALLOCATED] = "Total heap mem ever allocated",
- [EVENT_HEAP_SIZE] = "Current heap size (size of allocated mblocks)",
- [EVENT_BLOCKS_SIZE] = "Current heap size (size of allocated blocks)",
- [EVENT_HEAP_LIVE] = "Current heap live data",
- [EVENT_CREATE_SPARK_THREAD] = "Create spark thread",
- [EVENT_LOG_MSG] = "Log message",
- [EVENT_USER_MSG] = "User message",
- [EVENT_USER_MARKER] = "User marker",
- [EVENT_GC_IDLE] = "GC idle",
- [EVENT_GC_WORK] = "GC working",
- [EVENT_GC_DONE] = "GC done",
- [EVENT_BLOCK_MARKER] = "Block marker",
- [EVENT_CAPSET_CREATE] = "Create capability set",
- [EVENT_CAPSET_DELETE] = "Delete capability set",
- [EVENT_CAPSET_ASSIGN_CAP] = "Add capability to capability set",
- [EVENT_CAPSET_REMOVE_CAP] = "Remove capability from capability set",
- [EVENT_RTS_IDENTIFIER] = "RTS name and version",
- [EVENT_PROGRAM_ARGS] = "Program arguments",
- [EVENT_PROGRAM_ENV] = "Program environment variables",
- [EVENT_OSPROCESS_PID] = "Process ID",
- [EVENT_OSPROCESS_PPID] = "Parent process ID",
- [EVENT_WALL_CLOCK_TIME] = "Wall clock time",
- [EVENT_SPARK_COUNTERS] = "Spark counters",
- [EVENT_SPARK_CREATE] = "Spark create",
- [EVENT_SPARK_DUD] = "Spark dud",
- [EVENT_SPARK_OVERFLOW] = "Spark overflow",
- [EVENT_SPARK_RUN] = "Spark run",
- [EVENT_SPARK_STEAL] = "Spark steal",
- [EVENT_SPARK_FIZZLE] = "Spark fizzle",
- [EVENT_SPARK_GC] = "Spark GC",
- [EVENT_TASK_CREATE] = "Task create",
- [EVENT_TASK_MIGRATE] = "Task migrate",
- [EVENT_TASK_DELETE] = "Task delete",
- [EVENT_HACK_BUG_T9003] = "Empty event for bug #9003",
- [EVENT_HEAP_PROF_BEGIN] = "Start of heap profile",
- [EVENT_HEAP_PROF_COST_CENTRE] = "Cost center definition",
- [EVENT_IPE] = "Info Table Source Position",
- [EVENT_HEAP_PROF_SAMPLE_BEGIN] = "Start of heap profile sample",
- [EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN] = "Start of heap profile (biographical) sample",
- [EVENT_HEAP_PROF_SAMPLE_END] = "End of heap profile sample",
- [EVENT_HEAP_PROF_SAMPLE_STRING] = "Heap profile string sample",
- [EVENT_HEAP_PROF_SAMPLE_COST_CENTRE] = "Heap profile cost-centre sample",
- [EVENT_PROF_SAMPLE_COST_CENTRE] = "Time profile cost-centre stack",
- [EVENT_PROF_BEGIN] = "Start of a time profile",
- [EVENT_USER_BINARY_MSG] = "User binary message",
- [EVENT_CONC_MARK_BEGIN] = "Begin concurrent mark phase",
- [EVENT_CONC_MARK_END] = "End concurrent mark phase",
- [EVENT_CONC_SYNC_BEGIN] = "Begin concurrent GC synchronisation",
- [EVENT_CONC_SYNC_END] = "End concurrent GC synchronisation",
- [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep",
- [EVENT_CONC_SWEEP_END] = "End concurrent sweep",
- [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed",
- [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census",
- [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky entry counter definition",
- [EVENT_TICKY_COUNTER_BEGIN_SAMPLE] = "Ticky-ticky entry counter begin sample",
- [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky entry counter sample",
-};
-
-// Event type.
-
+// Event type
typedef struct _EventType {
EventTypeNum etNum; // Event Type number.
uint32_t size; // size of the payload in bytes
char *desc; // Description
} EventType;
-EventType eventTypes[NUM_GHC_EVENT_TAGS];
+#include "rts/EventTypes.h"
static void initEventsBuf(EventsBuf* eb, StgWord64 size, EventCapNo capno);
static void resetEventsBuf(EventsBuf* eb);
@@ -353,241 +274,6 @@ flushEventLogWriter(void)
}
static void
-init_event_types(void)
-{
- for (int t = 0; t < NUM_GHC_EVENT_TAGS; ++t) {
- eventTypes[t].etNum = t;
- eventTypes[t].desc = EventDesc[t];
-
- switch (t) {
- case EVENT_CREATE_THREAD: // (cap, thread)
- case EVENT_RUN_THREAD: // (cap, thread)
- case EVENT_THREAD_RUNNABLE: // (cap, thread)
- case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
- eventTypes[t].size = sizeof(EventThreadID);
- break;
-
- case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
- case EVENT_THREAD_WAKEUP: // (cap, thread, other_cap)
- eventTypes[t].size =
- sizeof(EventThreadID) + sizeof(EventCapNo);
- break;
-
- case EVENT_STOP_THREAD: // (cap, thread, status)
- eventTypes[t].size = sizeof(EventThreadID)
- + sizeof(StgWord16)
- + sizeof(EventThreadID);
- break;
-
- case EVENT_CAP_CREATE: // (cap)
- case EVENT_CAP_DELETE: // (cap)
- case EVENT_CAP_ENABLE: // (cap)
- case EVENT_CAP_DISABLE: // (cap)
- eventTypes[t].size = sizeof(EventCapNo);
- break;
-
- case EVENT_CAPSET_CREATE: // (capset, capset_type)
- eventTypes[t].size =
- sizeof(EventCapsetID) + sizeof(EventCapsetType);
- break;
-
- case EVENT_CAPSET_DELETE: // (capset)
- eventTypes[t].size = sizeof(EventCapsetID);
- break;
-
- case EVENT_CAPSET_ASSIGN_CAP: // (capset, cap)
- case EVENT_CAPSET_REMOVE_CAP:
- eventTypes[t].size =
- sizeof(EventCapsetID) + sizeof(EventCapNo);
- break;
-
- case EVENT_OSPROCESS_PID: // (cap, pid)
- case EVENT_OSPROCESS_PPID:
- eventTypes[t].size =
- sizeof(EventCapsetID) + sizeof(StgWord32);
- break;
-
- case EVENT_WALL_CLOCK_TIME: // (capset, unix_epoch_seconds, nanoseconds)
- eventTypes[t].size =
- sizeof(EventCapsetID) + sizeof(StgWord64) + sizeof(StgWord32);
- break;
-
- case EVENT_SPARK_STEAL: // (cap, victim_cap)
- eventTypes[t].size =
- sizeof(EventCapNo);
- break;
-
- case EVENT_REQUEST_SEQ_GC: // (cap)
- case EVENT_REQUEST_PAR_GC: // (cap)
- case EVENT_GC_START: // (cap)
- case EVENT_GC_END: // (cap)
- case EVENT_GC_IDLE:
- case EVENT_GC_WORK:
- case EVENT_GC_DONE:
- case EVENT_GC_GLOBAL_SYNC: // (cap)
- case EVENT_SPARK_CREATE: // (cap)
- case EVENT_SPARK_DUD: // (cap)
- case EVENT_SPARK_OVERFLOW: // (cap)
- case EVENT_SPARK_RUN: // (cap)
- case EVENT_SPARK_FIZZLE: // (cap)
- case EVENT_SPARK_GC: // (cap)
- eventTypes[t].size = 0;
- break;
-
- case EVENT_LOG_MSG: // (msg)
- case EVENT_USER_MSG: // (msg)
- case EVENT_USER_MARKER: // (markername)
- case EVENT_RTS_IDENTIFIER: // (capset, str)
- case EVENT_PROGRAM_ARGS: // (capset, strvec)
- case EVENT_PROGRAM_ENV: // (capset, strvec)
- case EVENT_THREAD_LABEL: // (thread, str)
- eventTypes[t].size = 0xffff;
- break;
-
- case EVENT_SPARK_COUNTERS: // (cap, 7*counter)
- eventTypes[t].size = 7 * sizeof(StgWord64);
- break;
-
- case EVENT_HEAP_ALLOCATED: // (heap_capset, alloc_bytes)
- case EVENT_HEAP_SIZE: // (heap_capset, size_bytes)
- case EVENT_BLOCKS_SIZE: // (heap_capset, size_bytes)
- case EVENT_HEAP_LIVE: // (heap_capset, live_bytes)
- eventTypes[t].size = sizeof(EventCapsetID) + sizeof(StgWord64);
- break;
-
- case EVENT_HEAP_INFO_GHC: // (heap_capset, n_generations,
- // max_heap_size, alloc_area_size,
- // mblock_size, block_size)
- eventTypes[t].size = sizeof(EventCapsetID)
- + sizeof(StgWord16)
- + sizeof(StgWord64) * 4;
- break;
-
- case EVENT_GC_STATS_GHC: // (heap_capset, generation,
- // copied_bytes, slop_bytes, frag_bytes,
- // par_n_threads,
- // par_max_copied, par_tot_copied,
- // par_balanced_copied
- // )
- eventTypes[t].size = sizeof(EventCapsetID)
- + sizeof(StgWord16)
- + sizeof(StgWord64) * 3
- + sizeof(StgWord32)
- + sizeof(StgWord64) * 3;
- break;
- case EVENT_MEM_RETURN: // (heap_capset, current_mblocks
- // , needed_mblocks, returned_mblocks)
- eventTypes[t].size = sizeof(EventCapsetID)
- + sizeof(StgWord32) * 3;
- break;
-
- case EVENT_TASK_CREATE: // (taskId, cap, tid)
- eventTypes[t].size = sizeof(EventTaskId)
- + sizeof(EventCapNo)
- + sizeof(EventKernelThreadId);
- break;
-
- case EVENT_TASK_MIGRATE: // (taskId, cap, new_cap)
- eventTypes[t].size =
- sizeof(EventTaskId) + sizeof(EventCapNo) + sizeof(EventCapNo);
- break;
-
- case EVENT_TASK_DELETE: // (taskId)
- eventTypes[t].size = sizeof(EventTaskId);
- break;
-
- case EVENT_BLOCK_MARKER:
- eventTypes[t].size = sizeof(StgWord32) + sizeof(EventTimestamp) +
- sizeof(EventCapNo);
- break;
-
- case EVENT_HACK_BUG_T9003:
- eventTypes[t].size = 0;
- break;
-
- case EVENT_HEAP_PROF_BEGIN:
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
-
- case EVENT_HEAP_PROF_COST_CENTRE:
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
- case EVENT_IPE:
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
-
- case EVENT_HEAP_PROF_SAMPLE_BEGIN:
- eventTypes[t].size = 8;
- break;
-
- case EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN:
- eventTypes[t].size = 16;
- break;
-
- case EVENT_HEAP_PROF_SAMPLE_END:
- eventTypes[t].size = 8;
- break;
-
- case EVENT_HEAP_PROF_SAMPLE_STRING:
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
-
- case EVENT_HEAP_PROF_SAMPLE_COST_CENTRE:
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
-
- case EVENT_PROF_SAMPLE_COST_CENTRE:
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
-
- case EVENT_PROF_BEGIN:
- eventTypes[t].size = 8;
- break;
-
- case EVENT_USER_BINARY_MSG:
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
-
- case EVENT_CONC_MARK_BEGIN:
- case EVENT_CONC_SYNC_BEGIN:
- case EVENT_CONC_SYNC_END:
- case EVENT_CONC_SWEEP_BEGIN:
- case EVENT_CONC_SWEEP_END:
- eventTypes[t].size = 0;
- break;
-
- case EVENT_CONC_MARK_END:
- eventTypes[t].size = 4;
- break;
-
- case EVENT_CONC_UPD_REM_SET_FLUSH: // (cap)
- eventTypes[t].size =
- sizeof(EventCapNo);
- break;
-
- case EVENT_NONMOVING_HEAP_CENSUS: // (cap, blk_size, active_segs, filled_segs, live_blks)
- eventTypes[t].size = 13;
- break;
-
- case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name)
- eventTypes[t].size = EVENT_SIZE_DYNAMIC;
- break;
-
- case EVENT_TICKY_COUNTER_BEGIN_SAMPLE:
- eventTypes[t].size = 0;
- break;
-
- case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd)
- eventTypes[t].size = 8*4;
- break;
-
- default:
- continue; /* ignore deprecated events */
- }
- }
-}
-
-static void
postHeaderEvents(void)
{
// The header must appear first in the output stream, without the
@@ -674,14 +360,6 @@ get_n_capabilities(void)
void
initEventLogging()
{
- init_event_types();
-
- int num_descs = sizeof(EventDesc) / sizeof(char*);
- if (num_descs != NUM_GHC_EVENT_TAGS) {
- barf("EventDesc array has the wrong number of elements (%d, NUM_GHC_EVENT_TAGS=%d)",
- num_descs, NUM_GHC_EVENT_TAGS);
- }
-
/*
* Allocate buffer(s) to store events.
* Create buffer large enough for the header begin marker, all event
diff --git a/rts/eventlog/EventLog.h b/rts/eventlog/EventLog.h
index 9c1201928b..1c9744a501 100644
--- a/rts/eventlog/EventLog.h
+++ b/rts/eventlog/EventLog.h
@@ -17,11 +17,6 @@
#if defined(TRACING)
-/*
- * Descriptions of EventTags for events.
- */
-extern char *EventTagDesc[];
-
extern bool eventlog_enabled;
void initEventLogging(void);
diff --git a/rts/gen_event_types.py b/rts/gen_event_types.py
new file mode 100755
index 0000000000..b0878ef2ab
--- /dev/null
+++ b/rts/gen_event_types.py
@@ -0,0 +1,214 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from typing import List, Union, Dict
+from collections import namedtuple
+
+class FieldType:
+ def __init__(self, c_type: str):
+ self.c_type = c_type
+
+VariableLength = None
+ThreadId = FieldType('EventThreadID')
+CapNo = FieldType('EventCapNo')
+CapsetType = FieldType('EventCapsetType')
+Timestamp = FieldType('EventTimestamp')
+CapsetId = FieldType('EventCapsetID')
+TaskId = FieldType('EventTaskId')
+
+Word8 = FieldType('StgWord8')
+Word16 = FieldType('StgWord16')
+Word32 = FieldType('StgWord32')
+Word64 = FieldType('StgWord64')
+
+class EventType:
+ def __init__(self,
+ n: int,
+ name: str,
+ fields: Union[VariableLength, List[FieldType]],
+ description: str):
+ self.n = n
+ self.name = name
+ self.fields = fields
+ self.description = description
+
+ def __str__(self):
+ return '(n={n}, name={name})'.format(n=self.n, name=self.name)
+
+# N.B. all events include an implicit initial CapNo field.
+#
+# When adding a new event type used by GHC you should also update
+# NUM_GHC_EVENT_TAGS in rts/include/rts/EventLogFormat.h.
+event_types = [
+ EventType( 0, 'CREATE_THREAD', [ThreadId], 'Create thread'),
+ EventType( 1, 'RUN_THREAD', [ThreadId], 'Run thread'),
+ EventType( 2, 'STOP_THREAD', [ThreadId, Word16, ThreadId], 'Stop thread'),
+ EventType( 3, 'THREAD_RUNNABLE', [ThreadId], 'Thread runnable'),
+ EventType( 4, 'MIGRATE_THREAD', [ThreadId, CapNo], 'Migrate thread'),
+ # 5, 6, 7 deprecated
+ EventType( 8, 'THREAD_WAKEUP', [ThreadId, CapNo], 'Wakeup thread'),
+ EventType( 9, 'GC_START', [], 'Starting GC'),
+ EventType(10, 'GC_END', [], 'Finished GC'),
+ EventType(11, 'REQUEST_SEQ_GC', [], 'Request sequential GC'),
+ EventType(12, 'REQUEST_PAR_GC', [], 'Request parallel GC'),
+ # 13, 14 deprecated
+ EventType(15, 'CREATE_SPARK_THREAD', [ThreadId], 'Create spark thread'),
+ EventType(16, 'LOG_MSG', VariableLength, 'Log message'),
+ # 17 deprecated
+ EventType(18, 'BLOCK_MARKER', [Word32, Timestamp, CapNo], 'Block marker'),
+ EventType(19, 'USER_MSG', VariableLength, 'User message'),
+ EventType(20, 'GC_IDLE', [], 'GC idle'),
+ EventType(21, 'GC_WORK', [], 'GC working'),
+ EventType(22, 'GC_DONE', [], 'GC done'),
+ # 23, 24 used by eden
+ EventType(25, 'CAPSET_CREATE', [CapsetId, CapsetType], 'Create capability set'),
+ EventType(26, 'CAPSET_DELETE', [CapsetId], 'Delete capability set'),
+ EventType(27, 'CAPSET_ASSIGN_CAP',[CapsetId, CapNo], 'Add capability to capability set'),
+ EventType(28, 'CAPSET_REMOVE_CAP',[CapsetId, CapNo], 'Remove capability from capability set'),
+ EventType(29, 'RTS_IDENTIFIER', VariableLength, 'RTS name and version'),
+ EventType(30, 'PROGRAM_ARGS', VariableLength, 'Program arguments'),
+ EventType(31, 'PROGRAM_ENV', VariableLength, 'Program environment variables'),
+ EventType(32, 'OSPROCESS_PID', [CapsetId, Word32], 'Process ID'),
+ EventType(33, 'OSPROCESS_PPID', [CapsetId, Word32], 'Parent process ID'),
+ EventType(34, 'SPARK_COUNTERS', 7*[Word64], 'Spark counters'),
+ EventType(35, 'SPARK_CREATE', [], 'Spark create'),
+ EventType(36, 'SPARK_DUD', [], 'Spark dud'),
+ EventType(37, 'SPARK_OVERFLOW', [], 'Spark overflow'),
+ EventType(38, 'SPARK_RUN', [], 'Spark run'),
+ EventType(39, 'SPARK_STEAL', [CapNo], 'Spark steal'),
+ EventType(40, 'SPARK_FIZZLE', [], 'Spark fizzle'),
+ EventType(41, 'SPARK_GC', [], 'Spark GC'),
+ EventType(42, 'INTERN_STRING', VariableLength, 'Intern string'),
+ EventType(43, 'WALL_CLOCK_TIME', [CapsetId, Word64, Word32], 'Wall clock time'),
+ EventType(44, 'THREAD_LABEL', VariableLength, 'Thread label'),
+ EventType(45, 'CAP_CREATE', [CapNo], 'Create capability'),
+ EventType(46, 'CAP_DELETE', [CapNo], 'Delete capability'),
+ EventType(47, 'CAP_DISABLE', [CapNo], 'Disable capability'),
+ EventType(48, 'CAP_ENABLE', [CapNo], 'Enable capability'),
+ EventType(49, 'HEAP_ALLOCATED', [CapsetId, Word64], 'Total heap memory ever allocated'),
+ EventType(50, 'HEAP_SIZE', [CapsetId, Word64], 'Current heap size'),
+ EventType(51, 'HEAP_LIVE', [CapsetId, Word64], 'Current heap live data'),
+ EventType(52, 'HEAP_INFO_GHC', [CapsetId, Word16] + 4*[Word64], 'Heap static parameters'),
+ EventType(53, 'GC_STATS_GHC', [CapsetId, Word16] + 3*[Word64] + [Word32] + 3*[Word64], 'GC statistics'),
+ EventType(54, 'GC_GLOBAL_SYNC', [], 'Synchronise stop-the-world GC'),
+ EventType(55, 'TASK_CREATE', [TaskId, CapNo, ThreadId], 'Task create'),
+ EventType(56, 'TASK_MIGRATE', [TaskId, CapNo, CapNo], 'Task migrate'),
+ EventType(57, 'TASK_DELETE', [TaskId], 'Task delete'),
+ EventType(58, 'USER_MARKER', VariableLength, 'User marker'),
+ EventType(59, 'HACK_BUG_T9003', [], 'Empty event for bug #9003'),
+
+ # Range 60 - 80 is used by eden for parallel tracing.
+ # See http://www.mathematik.uni-marburg.de/~eden/
+
+ EventType(90, 'MEM_RETURN', [CapNo, Word64, Word64, Word64], 'The RTS attempted to return heap memory to the OS'),
+ EventType(91, 'BLOCKS_SIZE', [CapsetId, Word64], 'Report the size of the heap in blocks'),
+
+ # Range 100 - 139 is reserved for Mercury.
+
+ # Range 140 - 159 is reserved for Perf events.
+
+ # Range 160 - 180 is reserved for cost-centre heap profiling events.
+
+ # Cost-centre profiler
+ EventType(160, 'HEAP_PROF_BEGIN', VariableLength, 'Start of heap profile'),
+ EventType(161, 'HEAP_PROF_COST_CENTRE', VariableLength, 'Cost-centre definition'),
+ EventType(162, 'HEAP_PROF_SAMPLE_BEGIN', [Word64], 'Start of heap profile sample'),
+ EventType(163, 'HEAP_PROF_SAMPLE_COST_CENTRE', VariableLength, 'Heap profile cost-centre sample'),
+ EventType(164, 'HEAP_PROF_SAMPLE_STRING', VariableLength, 'Heap profile string sample'),
+ EventType(165, 'HEAP_PROF_SAMPLE_END', [Word64], 'End of heap profile sample'),
+ EventType(166, 'HEAP_BIO_PROF_SAMPLE_BEGIN', [Word64, Word64], 'Start of heap profile (biographical) sample'),
+
+ EventType(167, 'PROF_SAMPLE_COST_CENTRE', VariableLength, 'Time profile cost-centre stack'),
+ EventType(168, 'PROF_BEGIN', [Word64], 'Start of a time profile'),
+ EventType(169, 'IPE', [Word64], 'Start of a time profile'),
+
+ EventType(181, 'USER_BINARY_MSG', VariableLength, 'User binary message'),
+
+ # Non-moving GC
+ EventType(200, 'CONC_MARK_BEGIN', [], 'Begin concurrent mark phase'),
+ EventType(201, 'CONC_MARK_END', [], 'End concurrent mark phase'),
+ EventType(202, 'CONC_SYNC_BEGIN', [], 'Begin concurrent GC synchronisation'),
+ EventType(203, 'CONC_SYNC_END', [], 'End concurrent mark synchronisation'),
+ EventType(204, 'CONC_SWEEP_BEGIN', [], 'Begin concurrent sweep phase'),
+ EventType(205, 'CONC_SWEEP_END', [], 'End concurrent sweep phase'),
+ EventType(206, 'CONC_UPD_REM_SET_FLUSH', [CapNo], 'Update remembered set flushed'),
+ EventType(207, 'NONMOVING_HEAP_CENSUS', [Word8, Word32, Word32, Word32], 'Nonmoving heap census'),
+
+ # Ticky-ticky profiling
+ EventType(210, 'TICKY_COUNTER_DEF', VariableLength, 'Ticky-ticky entry counter definition'),
+ EventType(211, 'TICKY_COUNTER_SAMPLE', 4*[Word64], 'Ticky-ticky entry counter sample'),
+ EventType(212, 'TICKY_COUNTER_BEGIN_SAMPLE', 4*[Word64], 'Ticky-ticky entry counter sample'),
+]
+
+def check_events() -> Dict[int, EventType]:
+ seen_ids = {}
+ for ty in event_types:
+ if ty.n in seen_ids:
+ print('Duplicate event type {n}:'.format(n=ty.n))
+ print(' {name}'.format(name=ty.name))
+ print(' {seen}'.format(seen=seen_ids[ty.n].name))
+ assert False
+
+ seen_ids[ty.n] = ty
+
+ return seen_ids
+
+def generate_event_types_array() -> str:
+ x = []
+ pr = lambda s: x.append(s)
+
+ pr('/*')
+ pr(' * Do not edit: This file is generated by event_types.py')
+ pr(' */')
+ pr('')
+ pr('EventType eventTypes[] = {')
+ for ty in event_types:
+ if ty.fields is VariableLength:
+ length = '0xffff'
+ elif len(ty.fields) == 0:
+ length = '0'
+ else:
+ length = ' + '.join('sizeof({c_type})'.format(c_type=field.c_type)
+ for field in ty.fields)
+
+ pr(' [EVENT_{}] = {{'.format(ty.name))
+ pr(' .etNum = {},'.format(ty.n))
+ pr(' .size = {},'.format(length))
+ pr(' .desc = "{}"'.format(ty.description))
+ pr(' },')
+
+ pr('};')
+ return '\n'.join(x)
+
+def generate_event_types_defines() -> str:
+ x = []
+ pr = lambda s: x.append(s)
+
+ pr('/*')
+ pr(' * Do not edit: This file is generated by event_types.py')
+ pr(' */')
+ pr('')
+ pr('#pragma once')
+ pr('')
+ for ty in event_types:
+ pr('#define EVENT_{name} {n}'.format(name=ty.name, n=ty.n))
+
+ return '\n'.join(x)
+
+def main() -> None:
+ import argparse
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--event-types-array', type=argparse.FileType('w'), metavar='FILE')
+ parser.add_argument('--event-types-defines', type=argparse.FileType('w'), metavar='FILE')
+ args = parser.parse_args()
+
+ check_events()
+
+ if args.event_types_array:
+ args.event_types_array.write(generate_event_types_array())
+
+ if args.event_types_defines:
+ args.event_types_defines.write(generate_event_types_defines())
+
+if __name__ == '__main__':
+ main()
diff --git a/rts/include/ghc.mk b/rts/include/ghc.mk
index cfedf62ea8..2fc14d5bef 100644
--- a/rts/include/ghc.mk
+++ b/rts/include/ghc.mk
@@ -249,6 +249,8 @@ $(includes_SETTINGS) : rts/include/Makefile | $$(dir $$@)/.
# Make DerivedConstants.h for the compiler
includes_DERIVEDCONSTANTS = rts/dist-install/build/include/DerivedConstants.h
+includes_EVENTLOG_CONSTANTS = rts/dist-install/build/include/rts/EventLogConstants.h
+includes_EVENT_TYPES = rts/dist-install/build/include/rts/EventTypes.h
DERIVE_CONSTANTS_FLAGS_FOR_HEADER += --gcc-program "$(CC)"
DERIVE_CONSTANTS_FLAGS_FOR_HEADER += $(addprefix --gcc-flag$(space),$(includes_CC_OPTS) -fcommon)
@@ -263,9 +265,21 @@ $(includes_DERIVEDCONSTANTS): $$(includes_H_FILES) $$(rts_H_FILES)
$(includes_DERIVEDCONSTANTS): $(deriveConstants_INPLACE) $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) | $$(dir $$@)/.
$< --gen-header -o $@ --tmpdir $(dir $@) $(DERIVE_CONSTANTS_FLAGS_FOR_HEADER)
+
+$(includes_EVENTLOG_CONSTANTS): rts/gen_event_types.py
+ mkdir -p $(dir $@)
+ ${PYTHON} $< --event-types-defines=$@
+
+$(includes_EVENT_TYPES): rts/gen_event_types.py
+ mkdir -p $(dir $@)
+ ${PYTHON} $< --event-types-array=$@
+
+includes/EventLog.h : $(includes_EVENTLOG_CONSTANTS) $(includes_EVENT_TYPES)
endif
includes_dist-install_H_FILES_GENERATED += $(includes_DERIVEDCONSTANTS)
+includes_dist-install_H_FILES_GENERATED += $(includes_EVENTLOG_CONSTANTS)
+includes_dist-install_H_FILES_GENERATED += $(includes_EVENT_TYPES)
# ---------------------------------------------------------------------------
# Install all header files
diff --git a/rts/include/rts/EventLogFormat.h b/rts/include/rts/EventLogFormat.h
index 4a2b339a9e..2eaeb0b582 100644
--- a/rts/include/rts/EventLogFormat.h
+++ b/rts/include/rts/EventLogFormat.h
@@ -56,116 +56,15 @@
#define EVENT_ET_END 0x65746500 /* 'e' 't' 'e' 0 */
/*
- * Types of event
- */
-#define EVENT_CREATE_THREAD 0 /* (thread) */
-#define EVENT_RUN_THREAD 1 /* (thread) */
-#define EVENT_STOP_THREAD 2 /* (thread, status, blockinfo) */
-#define EVENT_THREAD_RUNNABLE 3 /* (thread) */
-#define EVENT_MIGRATE_THREAD 4 /* (thread, new_cap) */
-/* 5, 6, 7 deprecated */
-#define EVENT_THREAD_WAKEUP 8 /* (thread, other_cap) */
-#define EVENT_GC_START 9 /* () */
-#define EVENT_GC_END 10 /* () */
-#define EVENT_REQUEST_SEQ_GC 11 /* () */
-#define EVENT_REQUEST_PAR_GC 12 /* () */
-/* 13, 14 deprecated */
-#define EVENT_CREATE_SPARK_THREAD 15 /* (spark_thread) */
-#define EVENT_LOG_MSG 16 /* (message ...) */
-/* 17 deprecated */
-#define EVENT_BLOCK_MARKER 18 /* (size, end_time, capability) */
-#define EVENT_USER_MSG 19 /* (message ...) */
-#define EVENT_GC_IDLE 20 /* () */
-#define EVENT_GC_WORK 21 /* () */
-#define EVENT_GC_DONE 22 /* () */
-/* 23, 24 used by eden */
-#define EVENT_CAPSET_CREATE 25 /* (capset, capset_type) */
-#define EVENT_CAPSET_DELETE 26 /* (capset) */
-#define EVENT_CAPSET_ASSIGN_CAP 27 /* (capset, cap) */
-#define EVENT_CAPSET_REMOVE_CAP 28 /* (capset, cap) */
-/* the RTS identifier is in the form of "GHC-version rts_way" */
-#define EVENT_RTS_IDENTIFIER 29 /* (capset, name_version_string) */
-/* the vectors in these events are null separated strings */
-#define EVENT_PROGRAM_ARGS 30 /* (capset, commandline_vector) */
-#define EVENT_PROGRAM_ENV 31 /* (capset, environment_vector) */
-#define EVENT_OSPROCESS_PID 32 /* (capset, pid) */
-#define EVENT_OSPROCESS_PPID 33 /* (capset, parent_pid) */
-#define EVENT_SPARK_COUNTERS 34 /* (crt,dud,ovf,cnv,gcd,fiz,rem) */
-#define EVENT_SPARK_CREATE 35 /* () */
-#define EVENT_SPARK_DUD 36 /* () */
-#define EVENT_SPARK_OVERFLOW 37 /* () */
-#define EVENT_SPARK_RUN 38 /* () */
-#define EVENT_SPARK_STEAL 39 /* (victim_cap) */
-#define EVENT_SPARK_FIZZLE 40 /* () */
-#define EVENT_SPARK_GC 41 /* () */
-#define EVENT_INTERN_STRING 42 /* (string, id) {not used by ghc} */
-#define EVENT_WALL_CLOCK_TIME 43 /* (capset, unix_epoch_seconds, nanoseconds) */
-#define EVENT_THREAD_LABEL 44 /* (thread, name_string) */
-#define EVENT_CAP_CREATE 45 /* (cap) */
-#define EVENT_CAP_DELETE 46 /* (cap) */
-#define EVENT_CAP_DISABLE 47 /* (cap) */
-#define EVENT_CAP_ENABLE 48 /* (cap) */
-#define EVENT_HEAP_ALLOCATED 49 /* (heap_capset, alloc_bytes) */
-#define EVENT_HEAP_SIZE 50 /* (heap_capset, size_bytes) */
-#define EVENT_HEAP_LIVE 51 /* (heap_capset, live_bytes) */
-#define EVENT_HEAP_INFO_GHC 52 /* (heap_capset, n_generations,
- max_heap_size, alloc_area_size,
- mblock_size, block_size) */
-#define EVENT_GC_STATS_GHC 53 /* (heap_capset, generation,
- copied_bytes, slop_bytes, frag_bytes,
- par_n_threads,
- par_max_copied,
- par_tot_copied, par_balanced_copied) */
-#define EVENT_GC_GLOBAL_SYNC 54 /* () */
-#define EVENT_TASK_CREATE 55 /* (taskID, cap, tid) */
-#define EVENT_TASK_MIGRATE 56 /* (taskID, cap, new_cap) */
-#define EVENT_TASK_DELETE 57 /* (taskID) */
-#define EVENT_USER_MARKER 58 /* (marker_name) */
-#define EVENT_HACK_BUG_T9003 59 /* Hack: see trac #9003 */
-
-/* Range 60 - 80 is used by eden for parallel tracing
- * see http://www.mathematik.uni-marburg.de/~eden/
+ * Types of events
+ *
+ * These are defined by gen_event_types.py.
*/
-
-#define EVENT_MEM_RETURN 90 /* (cap, current_mblocks, needed_mblocks, returned_mblocks) */
-#define EVENT_BLOCKS_SIZE 91 /* (heapcapset, size_bytes) */
-
-/* Range 100 - 139 is reserved for Mercury. */
-
-/* Range 140 - 159 is reserved for Perf events. */
-
-/* Range 160 - 180 is reserved for cost-centre heap profiling events. */
-
-#define EVENT_HEAP_PROF_BEGIN 160
-#define EVENT_HEAP_PROF_COST_CENTRE 161
-#define EVENT_HEAP_PROF_SAMPLE_BEGIN 162
-#define EVENT_HEAP_PROF_SAMPLE_COST_CENTRE 163
-#define EVENT_HEAP_PROF_SAMPLE_STRING 164
-#define EVENT_HEAP_PROF_SAMPLE_END 165
-#define EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN 166
-#define EVENT_PROF_SAMPLE_COST_CENTRE 167
-#define EVENT_PROF_BEGIN 168
-#define EVENT_IPE 169
-
-#define EVENT_USER_BINARY_MSG 181
-
-#define EVENT_CONC_MARK_BEGIN 200
-#define EVENT_CONC_MARK_END 201
-#define EVENT_CONC_SYNC_BEGIN 202
-#define EVENT_CONC_SYNC_END 203
-#define EVENT_CONC_SWEEP_BEGIN 204
-#define EVENT_CONC_SWEEP_END 205
-#define EVENT_CONC_UPD_REM_SET_FLUSH 206
-#define EVENT_NONMOVING_HEAP_CENSUS 207
-
-#define EVENT_TICKY_COUNTER_DEF 210
-#define EVENT_TICKY_COUNTER_SAMPLE 211
-#define EVENT_TICKY_COUNTER_BEGIN_SAMPLE 212
+#include "rts/EventLogConstants.h"
/*
* The highest event code +1 that ghc itself emits. Note that some event
* ranges higher than this are reserved but not currently emitted by ghc.
- * This must match the size of the EventDesc[] array in EventLog.c
*/
#define NUM_GHC_EVENT_TAGS 213
diff --git a/rts/rts.cabal.in b/rts/rts.cabal.in
index 9e998bb911..e7d5c4a7c7 100644
--- a/rts/rts.cabal.in
+++ b/rts/rts.cabal.in
@@ -168,6 +168,8 @@ library
ghcautoconf.h ghcconfig.h ghcplatform.h ghcversion.h
-- ^ from include
DerivedConstants.h ffi.h ffitarget.h
+ rts/EventLogConstants.h
+ rts/EventTypes.h
-- ^ generated
rts/Adjustor.h
rts/ExecPage.h