diff options
-rw-r--r-- | includes/rts/Flags.h | 4 | ||||
-rw-r--r-- | rts/Papi.c | 18 | ||||
-rw-r--r-- | rts/RtsFlags.c | 10 |
3 files changed, 27 insertions, 5 deletions
diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h index b86146148b..8bfadaa0cd 100644 --- a/includes/rts/Flags.h +++ b/includes/rts/Flags.h @@ -173,6 +173,8 @@ struct PAPI_FLAGS { nat eventType; /* The type of events to count */ nat numUserEvents; char * userEvents[MAX_PAPI_USER_EVENTS]; + /* Allow user to enter either PAPI preset or native events */ + nat userEventsKind[MAX_PAPI_USER_EVENTS]; }; #define PAPI_FLAG_CACHE_L1 1 @@ -181,6 +183,8 @@ struct PAPI_FLAGS { #define PAPI_FLAG_STALLS 4 #define PAPI_FLAG_CB_EVENTS 5 #define PAPI_USER_EVENTS 6 +#define PAPI_PRESET_EVENT_KIND 0 +#define PAPI_NATIVE_EVENT_KIND 1 #endif diff --git a/rts/Papi.c b/rts/Papi.c index 4d54c72682..f72660428b 100644 --- a/rts/Papi.c +++ b/rts/Papi.c @@ -74,6 +74,7 @@ int papi_error; /* Arbitrary, to avoid using malloc */ #define MAX_PAPI_EVENTS 10 +static char papiNativeEventNames[MAX_PAPI_EVENTS][PAPI_MAX_STR_LEN]; static nat n_papi_events = 0; @@ -86,10 +87,10 @@ long_long GC0Counters[MAX_PAPI_EVENTS]; long_long GC1Counters[MAX_PAPI_EVENTS]; long_long start_mutator_cycles; -long_long mutator_cycles; +long_long mutator_cycles = 0; long_long start_gc_cycles; -long_long gc0_cycles; -long_long gc1_cycles; +long_long gc0_cycles = 0; +long_long gc1_cycles = 0; @@ -145,11 +146,20 @@ init_countable_events(void) } else if (RtsFlags.PapiFlags.eventType==PAPI_USER_EVENTS) { nat i; char *name; + char *asciiEventCode; int code; for (i = 0; i < RtsFlags.PapiFlags.numUserEvents; i++) { + if(RtsFlags.PapiFlags.userEventsKind[i] == PAPI_PRESET_EVENT_KIND) { name = RtsFlags.PapiFlags.userEvents[i]; PAPI_CHECK(PAPI_event_name_to_code(name, &code)) - papi_add_event(name, code); + } + else { // PAPI_NATIVE_EVENT_KIND + asciiEventCode = RtsFlags.PapiFlags.userEvents[i]; + name = papiNativeEventNames[i]; + code = strtol(asciiEventCode, NULL, 16 /* hex number expected */); + PAPI_CHECK(PAPI_event_code_to_name(code, name)) + } + papi_add_event(name, code); } } else { // PAPI_ADD_EVENT(PAPI_L1_DCA); // L1 data cache accesses diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 0bd1b04313..5eb7800540 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -340,6 +340,8 @@ usage_text[] = { " b - branch mispredictions", " s - stalled cycles", " e - cache miss and branch misprediction events", +" +PAPI_EVENT - collect papi preset event PAPI_EVENT", +" #NATIVE_EVENT - collect native event NATIVE_EVENT (in hex)", #endif "", "RTS options may also be specified using the GHCRTS environment variable.", @@ -577,12 +579,18 @@ error = rtsTrue; RtsFlags.PapiFlags.eventType = PAPI_FLAG_CB_EVENTS; break; case '+': + case '#': if (RtsFlags.PapiFlags.numUserEvents >= MAX_PAPI_USER_EVENTS) { errorBelch("maximum number of PAPI events reached"); stg_exit(EXIT_FAILURE); } + nat eventNum = RtsFlags.PapiFlags.numUserEvents++; + char kind = rts_argv[arg][2]; + nat eventKind = kind == '+' ? PAPI_PRESET_EVENT_KIND : PAPI_NATIVE_EVENT_KIND; + + RtsFlags.PapiFlags.userEvents[eventNum] = rts_argv[arg] + 3; RtsFlags.PapiFlags.eventType = PAPI_USER_EVENTS; - RtsFlags.PapiFlags.userEvents[RtsFlags.PapiFlags.numUserEvents++] = rts_argv[arg] + 3; + RtsFlags.PapiFlags.userEventsKind[eventNum] = eventKind; break; default: bad_option( rts_argv[arg] ); |