|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
/* THIS IS OPEN SOURCE CODE */
|
|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* File: papi_internal.c
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Author: Philip Mucci
|
|
Packit |
577717 |
* mucci@cs.utk.edu
|
|
Packit |
577717 |
* Mods: dan terpstra
|
|
Packit |
577717 |
* terpstra@cs.utk.edu
|
|
Packit |
577717 |
* Mods: Min Zhou
|
|
Packit |
577717 |
* min@cs.utk.edu
|
|
Packit |
577717 |
* Mods: Kevin London
|
|
Packit |
577717 |
* london@cs.utk.edu
|
|
Packit |
577717 |
* Mods: Per Ekman
|
|
Packit |
577717 |
* pek@pdc.kth.se
|
|
Packit |
577717 |
* Mods: Haihang You
|
|
Packit |
577717 |
* you@cs.utk.edu
|
|
Packit |
577717 |
* Mods: Maynard Johnson
|
|
Packit |
577717 |
* maynardj@us.ibm.com
|
|
Packit |
577717 |
* Mods: Brian Sheely
|
|
Packit |
577717 |
* bsheely@eecs.utk.edu
|
|
Packit |
577717 |
* Mods: <Gary Mohr>
|
|
Packit |
577717 |
* <gary.mohr@bull.com>
|
|
Packit |
577717 |
* Mods: <your name here>
|
|
Packit |
577717 |
* <your email address>
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <stdarg.h>
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <errno.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <ctype.h>
|
|
Packit |
577717 |
#include <assert.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_internal.h"
|
|
Packit |
577717 |
#include "papi_vector.h"
|
|
Packit |
577717 |
#include "papi_memory.h"
|
|
Packit |
577717 |
#include "sw_multiplex.h"
|
|
Packit |
577717 |
#include "extras.h"
|
|
Packit |
577717 |
#include "papi_preset.h"
|
|
Packit |
577717 |
#include "cpus.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi_common_strings.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Advanced definitons */
|
|
Packit |
577717 |
static int default_debug_handler( int errorCode );
|
|
Packit |
577717 |
static long long handle_derived( EventInfo_t * evi, long long *from );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Global definitions used by other files */
|
|
Packit |
577717 |
int init_level = PAPI_NOT_INITED;
|
|
Packit |
577717 |
int _papi_hwi_error_level = PAPI_QUIET;
|
|
Packit |
577717 |
PAPI_debug_handler_t _papi_hwi_debug_handler = default_debug_handler;
|
|
Packit |
577717 |
papi_mdi_t _papi_hwi_system_info;
|
|
Packit |
577717 |
int _papi_hwi_errno = PAPI_OK;
|
|
Packit |
577717 |
int _papi_hwi_num_errors = 0;
|
|
Packit |
577717 |
hwi_presets_t user_defined_events[PAPI_MAX_USER_EVENTS];
|
|
Packit |
577717 |
int user_defined_events_count = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*****************************/
|
|
Packit |
577717 |
/* Native Event Mapping Code */
|
|
Packit |
577717 |
/*****************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define NATIVE_EVENT_CHUNKSIZE 1024
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct native_event_info {
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
int component_event;
|
|
Packit |
577717 |
int ntv_idx;
|
|
Packit |
577717 |
char *evt_name;
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// The following array is indexed by the papi event code (after the native bit has been removed)
|
|
Packit |
577717 |
static struct native_event_info *_papi_native_events=NULL;
|
|
Packit |
577717 |
static int num_native_events=0;
|
|
Packit |
577717 |
static int num_native_chunks=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
char **_papi_errlist= NULL;
|
|
Packit |
577717 |
static int num_error_chunks = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// pointer to event:mask string associated with last enum call to a components
|
|
Packit |
577717 |
// will be NULL for non libpfm4 components
|
|
Packit |
577717 |
// this is needed because libpfm4 event codes and papi event codes do not contain mask information
|
|
Packit |
577717 |
char *papi_event_string = NULL;
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_set_papi_event_string (const char *event_string) {
|
|
Packit |
577717 |
INTDBG("event_string: %s\n", event_string);
|
|
Packit |
577717 |
if (papi_event_string != NULL) {
|
|
Packit |
577717 |
free (papi_event_string);
|
|
Packit |
577717 |
papi_event_string = NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (event_string != NULL) {
|
|
Packit |
577717 |
papi_event_string = strdup(event_string);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
char *
|
|
Packit |
577717 |
_papi_hwi_get_papi_event_string () {
|
|
Packit |
577717 |
INTDBG("papi_event_string: %s\n", papi_event_string);
|
|
Packit |
577717 |
return papi_event_string;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_free_papi_event_string() {
|
|
Packit |
577717 |
if (papi_event_string != NULL) {
|
|
Packit |
577717 |
free(papi_event_string);
|
|
Packit |
577717 |
papi_event_string = NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit Service |
a5d459 |
|
|
Packit Service |
7c6464 |
// A place to keep the current papi event code so some component functions can fetch its value
|
|
Packit Service |
7c6464 |
// The current event code can be stored here prior to component calls and cleared after the component returns
|
|
Packit Service |
7c6464 |
static THREAD_LOCAL_STORAGE_KEYWORD unsigned int papi_event_code = -1;
|
|
Packit Service |
7c6464 |
static THREAD_LOCAL_STORAGE_KEYWORD int papi_event_code_changed = -1;
|
|
Packit Service |
7c6464 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_set_papi_event_code (unsigned int event_code, int update_flag) {
|
|
Packit |
577717 |
INTDBG("new event_code: %#x, update_flag: %d, previous event_code: %#x\n", event_code, update_flag, papi_event_code);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if call is just to reset and start over, set both flags to show nothing saved yet
|
|
Packit |
577717 |
if (update_flag < 0) {
|
|
Packit Service |
7c6464 |
papi_event_code_changed = -1;
|
|
Packit Service |
7c6464 |
papi_event_code = -1;
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if 0, it is being set prior to calling a component, if >0 it is being changed by the component
|
|
Packit Service |
7c6464 |
papi_event_code_changed = update_flag;
|
|
Packit |
577717 |
// save the event code passed in
|
|
Packit Service |
7c6464 |
papi_event_code = event_code;
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
unsigned int
|
|
Packit |
577717 |
_papi_hwi_get_papi_event_code () {
|
|
Packit |
577717 |
INTDBG("papi_event_code: %#x\n", papi_event_code);
|
|
Packit Service |
7c6464 |
return papi_event_code;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* Get the index into the ESI->NativeInfoArray for the current PAPI event code */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_get_ntv_idx (unsigned int papi_evt_code) {
|
|
Packit |
577717 |
INTDBG("ENTER: papi_evt_code: %#x\n", papi_evt_code);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int result;
|
|
Packit |
577717 |
int event_index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (papi_evt_code == 0) {
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOEVNT, invalid papi event code\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
event_index=papi_evt_code&PAPI_NATIVE_AND_MASK;
|
|
Packit |
577717 |
if ((event_index<0) || (event_index>=num_native_events)) {
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOEVNT, invalid index into native event array\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=_papi_native_events[event_index].ntv_idx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: result: %d\n", result);
|
|
Packit |
577717 |
return result;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
//
|
|
Packit |
577717 |
// Check for the presence of a component name or pmu name in the event string.
|
|
Packit |
577717 |
// If found check if it matches this component or one of the pmu's supported by this component.
|
|
Packit |
577717 |
//
|
|
Packit |
577717 |
// returns true if the event could be for this component and false if it is not for this component.
|
|
Packit |
577717 |
// if there is no component or pmu name then it could be for this component and returns true.
|
|
Packit |
577717 |
//
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
is_supported_by_component(int cidx, char *event_name) {
|
|
Packit |
577717 |
INTDBG("ENTER: cidx: %d, event_name: %s\n", cidx, event_name);
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
int component_name = 0;
|
|
Packit |
577717 |
int pmu_name = 0;
|
|
Packit |
577717 |
char *wptr = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if event does not have a component name or pmu name, return to show it could be supported by this component
|
|
Packit |
577717 |
// when component and pmu names are not provided, we just have to call the components to see if they recognize the event
|
|
Packit |
577717 |
//
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// look for component names first
|
|
Packit |
577717 |
if ((wptr = strstr(event_name, ":::")) != NULL) {
|
|
Packit |
577717 |
component_name = 1;
|
|
Packit |
577717 |
} else if ((wptr = strstr(event_name, "::")) != NULL) {
|
|
Packit |
577717 |
pmu_name = 1;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
INTDBG("EXIT: No Component or PMU name in event string, try this component\n");
|
|
Packit |
577717 |
// need to force all components to be called to find owner of this event
|
|
Packit |
577717 |
// ???? can we assume the default pmu when no component or pmu name is provided ????
|
|
Packit |
577717 |
return 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// get a temporary copy of the component or pmu name
|
|
Packit |
577717 |
int name_len = wptr - event_name;
|
|
Packit |
577717 |
wptr = strdup(event_name);
|
|
Packit |
577717 |
wptr[name_len] = '\0';
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if a component name was found, compare it to the component name in the component info structure
|
|
Packit |
577717 |
if (component_name) {
|
|
Packit |
577717 |
// INTDBG("component_name: %s\n", _papi_hwd[cidx]->cmp_info.name);
|
|
Packit |
577717 |
if (strcmp (wptr, _papi_hwd[cidx]->cmp_info.name) == 0) {
|
|
Packit |
577717 |
free (wptr);
|
|
Packit |
577717 |
INTDBG("EXIT: Component %s supports this event\n", _papi_hwd[cidx]->cmp_info.name);
|
|
Packit |
577717 |
return 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if a pmu name was found, compare it to the pmu name list if the component info structure (if there is one)
|
|
Packit |
577717 |
if (pmu_name) {
|
|
Packit |
577717 |
for ( i=0 ; i
|
|
Packit |
577717 |
if (_papi_hwd[cidx]->cmp_info.pmu_names[i] == NULL) {
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
// INTDBG("pmu_name[%d]: %p (%s)\n", i, _papi_hwd[cidx]->cmp_info.pmu_names[i], _papi_hwd[cidx]->cmp_info.pmu_names[i]);
|
|
Packit |
577717 |
if (strcmp (wptr, _papi_hwd[cidx]->cmp_info.pmu_names[i]) == 0) {
|
|
Packit |
577717 |
INTDBG("EXIT: Component %s supports PMU %s and this event\n", _papi_hwd[cidx]->cmp_info.name, wptr);
|
|
Packit |
577717 |
free (wptr);
|
|
Packit |
577717 |
return 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
free (wptr);
|
|
Packit |
577717 |
INTDBG("EXIT: Component does not support this event\n");
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @internal
|
|
Packit |
577717 |
* @class _papi_hwi_prefix_component_name
|
|
Packit |
577717 |
* @brief Prefixes a component's name to each of its events.
|
|
Packit |
577717 |
* @param *component_name
|
|
Packit |
577717 |
* @param *event_name
|
|
Packit |
577717 |
* @param *out
|
|
Packit |
577717 |
* @param *out_len
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Given sane component_name and event_name it returns component_name:::event_name.
|
|
Packit |
577717 |
* It is safe in the case that event_name == out and it checks against the
|
|
Packit |
577717 |
* traditional PAPI 'cpu' components, opting to not prepend those.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_prefix_component_name( char *component_name, char *event_name, char *out, int out_len)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int size1, size2;
|
|
Packit |
577717 |
char temp[out_len];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
size1 = strlen(event_name);
|
|
Packit |
577717 |
size2 = strlen(component_name);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* sanity checks */
|
|
Packit |
577717 |
if ( size1 == 0 ) {
|
|
Packit |
577717 |
return (PAPI_EBUG); /* hopefully event_name always has length?! */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( size1 >= out_len )
|
|
Packit |
577717 |
return (PAPI_ENOMEM);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Guard against event_name == out */
|
|
Packit |
577717 |
memcpy( temp, event_name, out_len );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* no component name to prefix */
|
|
Packit |
577717 |
if ( size2 == 0 ) {
|
|
Packit |
577717 |
sprintf(out, "%s%c", temp, '\0' );
|
|
Packit |
577717 |
return (PAPI_OK);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Don't prefix 'cpu' component names for now */
|
|
Packit |
577717 |
if ( strstr(component_name, "pe") ||
|
|
Packit |
577717 |
strstr(component_name, "bgq") ||
|
|
Packit |
577717 |
strstr(component_name, "bgp") ) {
|
|
Packit |
577717 |
sprintf( out, "%s%c", temp, '\0');
|
|
Packit |
577717 |
return (PAPI_OK);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* strlen(component_name) + ::: + strlen(event_name) + NULL */
|
|
Packit |
577717 |
if ( size1+size2+3+1 > out_len )
|
|
Packit |
577717 |
return (PAPI_ENOMEM);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf( out, "%s:::%s%c" , component_name, temp, '\0');
|
|
Packit |
577717 |
return (PAPI_OK);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @internal
|
|
Packit |
577717 |
* @class _papi_hwi_strip_component_prefix
|
|
Packit |
577717 |
* @brief Strip off cmp_name::: from an event name.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *event_name
|
|
Packit |
577717 |
* @return Start of the component consumable portion of the name.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* This function checks specifically for ':::' and will return the start of
|
|
Packit |
577717 |
* event_name if it doesn't find the ::: .
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
const char *_papi_hwi_strip_component_prefix(const char *event_name)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
const char *start = NULL;
|
|
Packit |
577717 |
/* We assume ::: is the seperator
|
|
Packit |
577717 |
* eg:
|
|
Packit |
577717 |
* papi_component:::event_name
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
start = strstr( event_name, ":::" );
|
|
Packit |
577717 |
if ( start != NULL )
|
|
Packit |
577717 |
start+= 3; /* return the actual start of event_name */
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
start = event_name;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return (start);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* find the papi event code (4000xxx) associated with the specified component, native event, and event name */
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_papi_hwi_find_native_event(int cidx, int event, const char *event_name) {
|
|
Packit |
577717 |
INTDBG("ENTER: cidx: %x, event: %#x, event_name: %s\n", cidx, event, event_name);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if no event name passed in, it can not be found
|
|
Packit |
577717 |
if (event_name == NULL) {
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOEVNT\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
// if we have have not set up this event name yet, look at next
|
|
Packit |
577717 |
if (_papi_native_events[i].evt_name == NULL) {
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// is this entry for the correct component and event code
|
|
Packit |
577717 |
if ((_papi_native_events[i].cidx==cidx) &&
|
|
Packit |
577717 |
(_papi_native_events[i].component_event==event)) {
|
|
Packit |
577717 |
// if this event name matches what we want, return its papi event code
|
|
Packit |
577717 |
if (strcmp(event_name, _papi_native_events[i].evt_name) == 0) {
|
|
Packit |
577717 |
INTDBG("EXIT: event: %#x, component_event: %#x, ntv_idx: %d, event_name: %s\n",
|
|
Packit |
577717 |
i|PAPI_NATIVE_MASK, _papi_native_events[i].component_event, _papi_native_events[i].ntv_idx, _papi_native_events[i].evt_name);
|
|
Packit |
577717 |
return i|PAPI_NATIVE_MASK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOEVNT\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_papi_hwi_add_native_event(int cidx, int ntv_event, int ntv_idx, const char *event_name) {
|
|
Packit |
577717 |
INTDBG("ENTER: cidx: %d, ntv_event: %#x, ntv_idx: %d, event_name: %s\n", cidx, ntv_event, ntv_idx, event_name);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int new_native_event;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_lock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (num_native_events>=num_native_chunks*NATIVE_EVENT_CHUNKSIZE) {
|
|
Packit |
577717 |
num_native_chunks++;
|
|
Packit |
577717 |
_papi_native_events=(struct native_event_info *) realloc(_papi_native_events,
|
|
Packit |
577717 |
num_native_chunks*NATIVE_EVENT_CHUNKSIZE*
|
|
Packit |
577717 |
sizeof(struct native_event_info));
|
|
Packit |
577717 |
if (_papi_native_events==NULL) {
|
|
Packit |
577717 |
new_native_event=PAPI_ENOMEM;
|
|
Packit |
577717 |
goto native_alloc_early_out;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_native_events[num_native_events].cidx=cidx;
|
|
Packit |
577717 |
_papi_native_events[num_native_events].component_event=ntv_event;
|
|
Packit |
577717 |
_papi_native_events[num_native_events].ntv_idx=ntv_idx;
|
|
Packit |
577717 |
if (event_name != NULL) {
|
|
Packit |
577717 |
_papi_native_events[num_native_events].evt_name=strdup(event_name);
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
_papi_native_events[num_native_events].evt_name=NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
new_native_event=num_native_events|PAPI_NATIVE_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
num_native_events++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
native_alloc_early_out:
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: new_native_event: %#x, num_native_events: %d\n", new_native_event, num_native_events);
|
|
Packit |
577717 |
return new_native_event;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @internal
|
|
Packit |
577717 |
* @class _papi_hwi_add_error
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Adds a new error string to PAPI's internal store.
|
|
Packit |
577717 |
* MAKE SURE you are not holding INTERNAL_LOCK when you call me!
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_papi_hwi_add_error( char *error )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("Adding a new Error message |%s|\n", error);
|
|
Packit |
577717 |
_papi_hwi_lock(INTERNAL_LOCK);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (_papi_hwi_num_errors >= num_error_chunks*NATIVE_EVENT_CHUNKSIZE) {
|
|
Packit |
577717 |
num_error_chunks++;
|
|
Packit |
577717 |
_papi_errlist= (char **) realloc(_papi_errlist,
|
|
Packit |
577717 |
num_error_chunks*NATIVE_EVENT_CHUNKSIZE*sizeof(char *));
|
|
Packit |
577717 |
if (_papi_errlist==NULL) {
|
|
Packit |
577717 |
_papi_hwi_num_errors = -2;
|
|
Packit |
577717 |
goto bail;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_errlist[_papi_hwi_num_errors] = strdup( error );
|
|
Packit |
577717 |
if ( _papi_errlist[_papi_hwi_num_errors] == NULL )
|
|
Packit |
577717 |
_papi_hwi_num_errors = -2;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
bail:
|
|
Packit |
577717 |
_papi_hwi_unlock(INTERNAL_LOCK);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return _papi_hwi_num_errors++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
_papi_hwi_cleanup_errors()
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_errlist == NULL ||
|
|
Packit |
577717 |
_papi_hwi_num_errors == 0 )
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_lock( INTERNAL_LOCK );
|
|
Packit |
577717 |
for (i=0; i < _papi_hwi_num_errors; i++ ) {
|
|
Packit |
577717 |
free( _papi_errlist[i]);
|
|
Packit |
577717 |
_papi_errlist[i] = NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
free( _papi_errlist );
|
|
Packit |
577717 |
_papi_errlist = NULL;
|
|
Packit |
577717 |
_papi_hwi_num_errors = 0;
|
|
Packit |
577717 |
num_error_chunks=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_papi_hwi_lookup_error( char *error )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i=0; i<_papi_hwi_num_errors; i++) {
|
|
Packit |
577717 |
if ( !strncasecmp( _papi_errlist[i], error, strlen( error ) ) )
|
|
Packit |
577717 |
return i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return (-1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @internal
|
|
Packit |
577717 |
* @class _papi_hwi_publish_error
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @return
|
|
Packit |
577717 |
* <= 0 : Code for the error.
|
|
Packit |
577717 |
* < 0 : We couldn't get memory to allocate for your error.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* An internal interface for adding an error code to the library.
|
|
Packit |
577717 |
* The returned code is suitable for returning to users.
|
|
Packit |
577717 |
* */
|
|
Packit |
577717 |
int _papi_hwi_publish_error( char *error )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int error_code = -1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( (error_code = _papi_hwi_lookup_error( error )) < 0 )
|
|
Packit |
577717 |
error_code = _papi_hwi_add_error(error);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return (-error_code); /* internally error_code is an index, externally, it should be <= 0 */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_init_errors(void) {
|
|
Packit |
577717 |
/* we use add error to avoid the cost of lookups, we know the errors are not there yet */
|
|
Packit |
577717 |
_papi_hwi_add_error("No error");
|
|
Packit |
577717 |
_papi_hwi_add_error("Invalid argument");
|
|
Packit |
577717 |
_papi_hwi_add_error("Insufficient memory");
|
|
Packit |
577717 |
_papi_hwi_add_error("A System/C library call failed");
|
|
Packit |
577717 |
_papi_hwi_add_error("Not supported by component");
|
|
Packit |
577717 |
_papi_hwi_add_error("Access to the counters was lost or interrupted");
|
|
Packit |
577717 |
_papi_hwi_add_error("Internal error, please send mail to the developers");
|
|
Packit |
577717 |
_papi_hwi_add_error("Event does not exist");
|
|
Packit |
577717 |
_papi_hwi_add_error("Event exists, but cannot be counted due to hardware resource limits");
|
|
Packit |
577717 |
_papi_hwi_add_error("EventSet is currently not running");
|
|
Packit |
577717 |
_papi_hwi_add_error("EventSet is currently counting");
|
|
Packit |
577717 |
_papi_hwi_add_error("No such EventSet available");
|
|
Packit |
577717 |
_papi_hwi_add_error("Event in argument is not a valid preset");
|
|
Packit |
577717 |
_papi_hwi_add_error("Hardware does not support performance counters");
|
|
Packit |
577717 |
_papi_hwi_add_error("Unknown error code");
|
|
Packit |
577717 |
_papi_hwi_add_error("Permission level does not permit operation");
|
|
Packit |
577717 |
_papi_hwi_add_error("PAPI hasn't been initialized yet");
|
|
Packit |
577717 |
_papi_hwi_add_error("Component Index isn't set");
|
|
Packit |
577717 |
_papi_hwi_add_error("Not supported");
|
|
Packit |
577717 |
_papi_hwi_add_error("Not implemented");
|
|
Packit |
577717 |
_papi_hwi_add_error("Buffer size exceeded");
|
|
Packit |
577717 |
_papi_hwi_add_error("EventSet domain is not supported for the operation");
|
|
Packit |
577717 |
_papi_hwi_add_error("Invalid or missing event attributes");
|
|
Packit |
577717 |
_papi_hwi_add_error("Too many events or attributes");
|
|
Packit |
577717 |
_papi_hwi_add_error("Bad combination of features");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_invalid_cmp( int cidx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return ( cidx < 0 || cidx >= papi_num_components );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_component_index( int event_code ) {
|
|
Packit |
577717 |
INTDBG("ENTER: event_code: %#x\n", event_code);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
int event_index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* currently assume presets are for component 0 only */
|
|
Packit |
577717 |
if (IS_PRESET(event_code)) {
|
|
Packit |
577717 |
INTDBG("EXIT: Event %#x is a PRESET, assigning component %d\n", event_code,0);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* user defined events are treated like preset events (component 0 only) */
|
|
Packit |
577717 |
if (IS_USER_DEFINED(event_code)) {
|
|
Packit |
577717 |
INTDBG("EXIT: Event %#x is USER DEFINED, assigning component %d\n", event_code,0);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
event_index=event_code&PAPI_NATIVE_AND_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( (event_index < 0) || (event_index>=num_native_events)) {
|
|
Packit |
577717 |
INTDBG("EXIT: Event index %#x is out of range, num_native_events: %d\n", event_index, num_native_events);
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
cidx=_papi_native_events[event_index].cidx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((cidx<0) || (cidx >= papi_num_components)) {
|
|
Packit |
577717 |
INTDBG("EXIT: Component index %#x is out of range, papi_num_components: %d\n", cidx, papi_num_components);
|
|
Packit |
577717 |
return PAPI_ENOCMP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: Found cidx: %d event_index: %d, event_code: %#x\n", cidx, event_index, event_code);
|
|
Packit |
577717 |
return cidx;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Convert an internal component event to a papi event code */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name) {
|
|
Packit |
577717 |
INTDBG("Entry: cidx: %d, event: %#x, ntv_idx: %d, event_name: %s\n", cidx, event_code, ntv_idx, event_name);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int result;
|
|
Packit |
577717 |
|
|
Packit Service |
7c6464 |
if (papi_event_code_changed > 0) {
|
|
Packit |
577717 |
result = _papi_hwi_get_papi_event_code();
|
|
Packit |
577717 |
INTDBG("EXIT: papi_event_code: %#x set by the component\n", result);
|
|
Packit |
577717 |
return result;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=_papi_hwi_find_native_event(cidx, event_code, event_name);
|
|
Packit |
577717 |
if (result==PAPI_ENOEVNT) {
|
|
Packit |
577717 |
// Need to create one
|
|
Packit |
577717 |
result=_papi_hwi_add_native_event(cidx, event_code, ntv_idx, event_name);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: result: %#x\n", result);
|
|
Packit |
577717 |
return result;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Convert a native_event code to an internal event code */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_eventcode_to_native(int event_code) {
|
|
Packit |
577717 |
INTDBG("ENTER: event_code: %#x\n", event_code);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int result;
|
|
Packit |
577717 |
int event_index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
event_index=event_code&PAPI_NATIVE_AND_MASK;
|
|
Packit |
577717 |
if ((event_index < 0) || (event_index>=num_native_events)) {
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOEVNT\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=_papi_native_events[event_index].component_event;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: result: %#x\n", result);
|
|
Packit |
577717 |
return result;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*********************/
|
|
Packit |
577717 |
/* Utility functions */
|
|
Packit |
577717 |
/*********************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
PAPIERROR( char *format, ... )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
va_list args;
|
|
Packit |
577717 |
if ( ( _papi_hwi_error_level != PAPI_QUIET ) ||
|
|
Packit |
577717 |
( getenv( "PAPI_VERBOSE" ) ) ) {
|
|
Packit |
577717 |
va_start( args, format );
|
|
Packit |
577717 |
fprintf( stderr, "PAPI Error: " );
|
|
Packit |
577717 |
vfprintf( stderr, format, args );
|
|
Packit |
577717 |
fprintf( stderr, "\n" );
|
|
Packit |
577717 |
va_end( args );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
PAPIWARN( char *format, ... )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
va_list args;
|
|
Packit |
577717 |
if ( ( _papi_hwi_error_level != PAPI_QUIET ) ||
|
|
Packit |
577717 |
( getenv( "PAPI_VERBOSE" ) ) ) {
|
|
Packit |
577717 |
va_start( args, format );
|
|
Packit |
577717 |
fprintf( stderr, "PAPI Warning: " );
|
|
Packit |
577717 |
vfprintf( stderr, format, args );
|
|
Packit |
577717 |
fprintf( stderr, "\n" );
|
|
Packit |
577717 |
va_end( args );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
default_debug_handler( int errorCode )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
char str[PAPI_HUGE_STR_LEN];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( errorCode == PAPI_OK )
|
|
Packit |
577717 |
return ( errorCode );
|
|
Packit |
577717 |
if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) ) {
|
|
Packit |
577717 |
PAPIERROR( "%s %d,%s,Bug! Unknown error code", PAPI_ERROR_CODE_str,
|
|
Packit |
577717 |
errorCode, "" );
|
|
Packit |
577717 |
return ( PAPI_EBUG );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch ( _papi_hwi_error_level ) {
|
|
Packit |
577717 |
case PAPI_VERB_ECONT:
|
|
Packit |
577717 |
case PAPI_VERB_ESTOP:
|
|
Packit |
577717 |
/* gcc 2.96 bug fix, do not change */
|
|
Packit |
577717 |
/* fprintf(stderr,"%s %d: %s: %s\n",PAPI_ERROR_CODE_str,errorCode,_papi_hwi_err[-errorCode].name,_papi_hwi_err[-errorCode].descr); */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf( str, "%s %d,%s", PAPI_ERROR_CODE_str, errorCode,
|
|
Packit |
577717 |
_papi_errlist[-errorCode] );
|
|
Packit |
577717 |
if ( errorCode == PAPI_ESYS )
|
|
Packit |
577717 |
sprintf( str + strlen( str ), ": %s", strerror( errno ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
PAPIERROR( str );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_error_level == PAPI_VERB_ESTOP )
|
|
Packit |
577717 |
abort( ); /* patch provided by will cohen of redhat */
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
return errorCode;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PAPI_QUIET:
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return errorCode;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( PAPI_EBUG ); /* Never get here */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
allocate_eventset_map( DynamicArray_t * map )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* Allocate and clear the Dynamic Array structure */
|
|
Packit |
577717 |
if ( map->dataSlotArray != NULL )
|
|
Packit |
577717 |
papi_free( map->dataSlotArray );
|
|
Packit |
577717 |
memset( map, 0x00, sizeof ( DynamicArray_t ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Allocate space for the EventSetInfo_t pointers */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
map->dataSlotArray =
|
|
Packit |
577717 |
( EventSetInfo_t ** ) papi_malloc( PAPI_INIT_SLOTS *
|
|
Packit |
577717 |
sizeof ( EventSetInfo_t * ) );
|
|
Packit |
577717 |
if ( map->dataSlotArray == NULL ) {
|
|
Packit |
577717 |
return ( PAPI_ENOMEM );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
memset( map->dataSlotArray, 0x00,
|
|
Packit |
577717 |
PAPI_INIT_SLOTS * sizeof ( EventSetInfo_t * ) );
|
|
Packit |
577717 |
map->totalSlots = PAPI_INIT_SLOTS;
|
|
Packit |
577717 |
map->availSlots = PAPI_INIT_SLOTS;
|
|
Packit |
577717 |
map->fullSlots = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
expand_dynamic_array( DynamicArray_t * DA )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int number;
|
|
Packit |
577717 |
EventSetInfo_t **n;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*realloc existing PAPI_EVENTSET_MAP.dataSlotArray */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
number = DA->totalSlots * 2;
|
|
Packit |
577717 |
n = ( EventSetInfo_t ** ) papi_realloc( DA->dataSlotArray,
|
|
Packit |
577717 |
( size_t ) number *
|
|
Packit |
577717 |
sizeof ( EventSetInfo_t * ) );
|
|
Packit |
577717 |
if ( n == NULL )
|
|
Packit |
577717 |
return ( PAPI_ENOMEM );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Need to assign this value, what if realloc moved it? */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DA->dataSlotArray = n;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( DA->dataSlotArray + DA->totalSlots, 0x00,
|
|
Packit |
577717 |
( size_t ) DA->totalSlots * sizeof ( EventSetInfo_t * ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DA->totalSlots = number;
|
|
Packit |
577717 |
DA->availSlots = number - DA->fullSlots;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
EventInfoArrayLength( const EventSetInfo_t * ESI )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return ( _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*========================================================================*/
|
|
Packit |
577717 |
/* This function allocates space for one EventSetInfo_t structure and for */
|
|
Packit |
577717 |
/* all of the pointers in this structure. If any malloc in this function */
|
|
Packit |
577717 |
/* fails, all memory malloced to the point of failure is freed, and NULL */
|
|
Packit |
577717 |
/* is returned. Upon success, a pointer to the EventSetInfo_t data */
|
|
Packit |
577717 |
/* structure is returned. */
|
|
Packit |
577717 |
/*========================================================================*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
create_EventSet( EventSetInfo_t ** here )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
EventSetInfo_t *ESI;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI = ( EventSetInfo_t * ) papi_calloc( 1, sizeof ( EventSetInfo_t ) );
|
|
Packit |
577717 |
if ( ESI == NULL ) {
|
|
Packit |
577717 |
return PAPI_ENOMEM;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
*here = ESI;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_assign_eventset( EventSetInfo_t *ESI, int cidx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: ESI: %p (%d), cidx: %d\n", ESI, ESI->EventSetIndex, cidx);
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
size_t max_counters;
|
|
Packit |
577717 |
char *ptr;
|
|
Packit |
577717 |
unsigned int i, j;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If component doesn't exist... */
|
|
Packit |
577717 |
if (_papi_hwi_invalid_cmp(cidx)) return PAPI_ECMP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Assigned at create time */
|
|
Packit |
577717 |
ESI->domain.domain = _papi_hwd[cidx]->cmp_info.default_domain;
|
|
Packit |
577717 |
ESI->granularity.granularity =
|
|
Packit |
577717 |
_papi_hwd[cidx]->cmp_info.default_granularity;
|
|
Packit |
577717 |
ESI->CmpIdx = cidx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* ??? */
|
|
Packit |
577717 |
max_counters = ( size_t ) _papi_hwd[cidx]->cmp_info.num_mpx_cntrs;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->ctl_state = (hwd_control_state_t *) papi_calloc( 1, (size_t)
|
|
Packit |
577717 |
_papi_hwd[cidx]->size.control_state );
|
|
Packit |
577717 |
ESI->sw_stop = (long long *) papi_calloc( ( size_t ) max_counters,
|
|
Packit |
577717 |
sizeof ( long long ) );
|
|
Packit |
577717 |
ESI->hw_start = ( long long * ) papi_calloc( ( size_t ) max_counters,
|
|
Packit |
577717 |
sizeof ( long long ) );
|
|
Packit |
577717 |
ESI->EventInfoArray = ( EventInfo_t * ) papi_calloc( (size_t) max_counters,
|
|
Packit |
577717 |
sizeof ( EventInfo_t ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* allocate room for the native events and for the component-private */
|
|
Packit |
577717 |
/* register structures */
|
|
Packit |
577717 |
/* ugh is there a cleaner way to allocate this? vmw */
|
|
Packit |
577717 |
ESI->NativeInfoArray = ( NativeInfo_t * )
|
|
Packit |
577717 |
papi_calloc( ( size_t ) max_counters, sizeof ( NativeInfo_t ));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->NativeBits = papi_calloc(( size_t ) max_counters,
|
|
Packit |
577717 |
( size_t ) _papi_hwd[cidx]->size.reg_value );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* NOTE: the next two malloc allocate blocks of memory that are later */
|
|
Packit |
577717 |
/* parcelled into overflow and profile arrays */
|
|
Packit |
577717 |
ESI->overflow.deadline = ( long long * )
|
|
Packit |
577717 |
papi_malloc( ( sizeof ( long long ) +
|
|
Packit |
577717 |
sizeof ( int ) * 3 ) * ( size_t ) max_counters );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->profile.prof = ( PAPI_sprofil_t ** )
|
|
Packit |
577717 |
papi_malloc( ( sizeof ( PAPI_sprofil_t * ) * ( size_t ) max_counters +
|
|
Packit |
577717 |
( size_t ) max_counters * sizeof ( int ) * 4 ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If any of these allocations failed, free things up and fail */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( ESI->ctl_state == NULL ) ||
|
|
Packit |
577717 |
( ESI->sw_stop == NULL ) ||
|
|
Packit |
577717 |
( ESI->hw_start == NULL ) ||
|
|
Packit |
577717 |
( ESI->NativeInfoArray == NULL ) ||
|
|
Packit |
577717 |
( ESI->NativeBits == NULL ) ||
|
|
Packit |
577717 |
( ESI->EventInfoArray == NULL ) ||
|
|
Packit |
577717 |
( ESI->profile.prof == NULL ) ||
|
|
Packit |
577717 |
( ESI->overflow.deadline == NULL ) ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->sw_stop ) papi_free( ESI->sw_stop );
|
|
Packit |
577717 |
if ( ESI->hw_start ) papi_free( ESI->hw_start );
|
|
Packit |
577717 |
if ( ESI->EventInfoArray ) papi_free( ESI->EventInfoArray );
|
|
Packit |
577717 |
if ( ESI->NativeInfoArray ) papi_free( ESI->NativeInfoArray );
|
|
Packit |
577717 |
if ( ESI->NativeBits ) papi_free( ESI->NativeBits );
|
|
Packit |
577717 |
if ( ESI->ctl_state ) papi_free( ESI->ctl_state );
|
|
Packit |
577717 |
if ( ESI->overflow.deadline ) papi_free( ESI->overflow.deadline );
|
|
Packit |
577717 |
if ( ESI->profile.prof ) papi_free( ESI->profile.prof );
|
|
Packit |
577717 |
papi_free( ESI );
|
|
Packit |
577717 |
return PAPI_ENOMEM;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Carve up the overflow block into separate arrays */
|
|
Packit |
577717 |
ptr = ( char * ) ESI->overflow.deadline;
|
|
Packit |
577717 |
ptr += sizeof ( long long ) * max_counters;
|
|
Packit |
577717 |
ESI->overflow.threshold = ( int * ) ptr;
|
|
Packit |
577717 |
ptr += sizeof ( int ) * max_counters;
|
|
Packit |
577717 |
ESI->overflow.EventIndex = ( int * ) ptr;
|
|
Packit |
577717 |
ptr += sizeof ( int ) * max_counters;
|
|
Packit |
577717 |
ESI->overflow.EventCode = ( int * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Carve up the profile block into separate arrays */
|
|
Packit |
577717 |
ptr = ( char * ) ESI->profile.prof +
|
|
Packit |
577717 |
( sizeof ( PAPI_sprofil_t * ) * max_counters );
|
|
Packit |
577717 |
ESI->profile.count = ( int * ) ptr;
|
|
Packit |
577717 |
ptr += sizeof ( int ) * max_counters;
|
|
Packit |
577717 |
ESI->profile.threshold = ( int * ) ptr;
|
|
Packit |
577717 |
ptr += sizeof ( int ) * max_counters;
|
|
Packit |
577717 |
ESI->profile.EventIndex = ( int * ) ptr;
|
|
Packit |
577717 |
ptr += sizeof ( int ) * max_counters;
|
|
Packit |
577717 |
ESI->profile.EventCode = ( int * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* initialize_EventInfoArray */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < max_counters; i++ ) {
|
|
Packit |
577717 |
ESI->EventInfoArray[i].event_code=( unsigned int ) PAPI_NULL;
|
|
Packit |
577717 |
ESI->EventInfoArray[i].ops = NULL;
|
|
Packit |
577717 |
ESI->EventInfoArray[i].derived=NOT_DERIVED;
|
|
Packit |
577717 |
for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
|
|
Packit |
577717 |
ESI->EventInfoArray[i].pos[j] = PAPI_NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* initialize_NativeInfoArray */
|
|
Packit |
577717 |
for( i = 0; i < max_counters; i++ ) {
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_event = -1;
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_position = -1;
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_papi_code = -1;
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_owners = 0;
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_bits = ((unsigned char*)ESI->NativeBits) +
|
|
Packit |
577717 |
(i*_papi_hwd[cidx]->size.reg_value);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->NativeCount = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->state = PAPI_STOPPED;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* these used to be init_config */
|
|
Packit |
577717 |
retval = _papi_hwd[cidx]->init_control_state( ESI->ctl_state );
|
|
Packit |
577717 |
retval |= _papi_hwd[cidx]->set_domain( ESI->ctl_state, ESI->domain.domain);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*========================================================================*/
|
|
Packit |
577717 |
/* This function should free memory for one EventSetInfo_t structure. */
|
|
Packit |
577717 |
/* The argument list consists of a pointer to the EventSetInfo_t */
|
|
Packit |
577717 |
/* structure, *ESI. */
|
|
Packit |
577717 |
/* The calling function should check for ESI==NULL. */
|
|
Packit |
577717 |
/*========================================================================*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_free_EventSet( EventSetInfo_t * ESI )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
_papi_hwi_cleanup_eventset( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef DEBUG
|
|
Packit |
577717 |
memset( ESI, 0x00, sizeof ( EventSetInfo_t ) );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
papi_free( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
add_EventSet( EventSetInfo_t * ESI, ThreadInfo_t * master )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
|
|
Packit |
577717 |
int i, errorCode;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_lock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( map->availSlots == 0 ) {
|
|
Packit |
577717 |
errorCode = expand_dynamic_array( map );
|
|
Packit |
577717 |
if ( errorCode < PAPI_OK ) {
|
|
Packit |
577717 |
_papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
return ( errorCode );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
i = 0;
|
|
Packit |
577717 |
for ( i = 0; i < map->totalSlots; i++ ) {
|
|
Packit |
577717 |
if ( map->dataSlotArray[i] == NULL ) {
|
|
Packit |
577717 |
ESI->master = master;
|
|
Packit |
577717 |
ESI->EventSetIndex = i;
|
|
Packit |
577717 |
map->fullSlots++;
|
|
Packit |
577717 |
map->availSlots--;
|
|
Packit |
577717 |
map->dataSlotArray[i] = ESI;
|
|
Packit |
577717 |
_papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
return ( PAPI_EBUG );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_create_eventset( int *EventSet, ThreadInfo_t * handle )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
EventSetInfo_t *ESI;
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Is the EventSet already in existence? */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( EventSet == NULL ) || ( handle == NULL ) )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( *EventSet != PAPI_NULL )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Well, then allocate a new one. Use n to keep track of a NEW EventSet */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = create_EventSet( &ESI );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->CmpIdx = -1; /* when eventset is created, it is not decided yet which component it belongs to, until first event is added */
|
|
Packit |
577717 |
ESI->state = PAPI_STOPPED;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Add it to the global table */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = add_EventSet( ESI, handle );
|
|
Packit |
577717 |
if ( retval < PAPI_OK ) {
|
|
Packit |
577717 |
_papi_hwi_free_EventSet( ESI );
|
|
Packit |
577717 |
return retval ;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
*EventSet = ESI->EventSetIndex;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG( "(%p,%p): new EventSet in slot %d\n",
|
|
Packit |
577717 |
( void * ) EventSet, handle, *EventSet );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This function returns the index of the the next free slot
|
|
Packit |
577717 |
in the EventInfoArray. If EventCode is already in the list,
|
|
Packit |
577717 |
it returns PAPI_ECNFLCT. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
get_free_EventCodeIndex( const EventSetInfo_t * ESI, unsigned int EventCode )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int k;
|
|
Packit |
577717 |
int lowslot = PAPI_ECNFLCT;
|
|
Packit |
577717 |
int limit = EventInfoArrayLength( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Check for duplicate events and get the lowest empty slot */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( k = 0; k < limit; k++ ) {
|
|
Packit |
577717 |
if ( ESI->EventInfoArray[k].event_code == EventCode )
|
|
Packit |
577717 |
return ( PAPI_ECNFLCT );
|
|
Packit |
577717 |
/*if ((ESI->EventInfoArray[k].event_code == PAPI_NULL) && (lowslot == PAPI_ECNFLCT)) */
|
|
Packit |
577717 |
if ( ESI->EventInfoArray[k].event_code == ( unsigned int ) PAPI_NULL ) {
|
|
Packit |
577717 |
lowslot = k;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( lowslot );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This function returns the index of the EventCode or error */
|
|
Packit |
577717 |
/* Index to what? The index to everything stored EventCode in the */
|
|
Packit |
577717 |
/* EventSet. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_lookup_EventCodeIndex( const EventSetInfo_t * ESI,
|
|
Packit |
577717 |
unsigned int EventCode )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
int limit = EventInfoArrayLength( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < limit; i++ ) {
|
|
Packit |
577717 |
if ( ESI->EventInfoArray[i].event_code == EventCode ) {
|
|
Packit |
577717 |
return i;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This function only removes empty EventSets */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_remove_EventSet( EventSetInfo_t * ESI )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
i = ESI->EventSetIndex;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_lock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_free_EventSet( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* do bookkeeping for PAPI_EVENTSET_MAP */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
map->dataSlotArray[i] = NULL;
|
|
Packit |
577717 |
map->availSlots++;
|
|
Packit |
577717 |
map->fullSlots--;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* this function checks if an event is already in an EventSet
|
|
Packit |
577717 |
Success, return ESI->NativeInfoArray[] index
|
|
Packit |
577717 |
Fail, return PAPI_ENOEVNT;
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
event_already_in_eventset( EventSetInfo_t * ESI, int papi_event )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG( "ENTER: ESI: %p, papi_event: %#x\n", ESI, papi_event);
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int nevt = _papi_hwi_eventcode_to_native(papi_event);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* to find the native event from the native events list */
|
|
Packit |
577717 |
for( i = 0; i < ESI->NativeCount; i++ ) {
|
|
Packit |
577717 |
if ( nevt == ESI->NativeInfoArray[i].ni_event ) {
|
|
Packit |
577717 |
// Also need to check papi event code if set because the same event with different masks
|
|
Packit |
577717 |
// will generate the same libpfm4 event code (what was checked above). But there will be
|
|
Packit |
577717 |
// different papi events created for it and they need to be handled separately.
|
|
Packit |
577717 |
if (papi_event == ESI->NativeInfoArray[i].ni_papi_code) {
|
|
Packit |
577717 |
INTDBG( "EXIT: event: %#x already mapped at index: %d\n", papi_event, i);
|
|
Packit |
577717 |
return i;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "EXIT: PAPI_ENOEVNT\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This function goes through the events in an EventSet's EventInfoArray */
|
|
Packit |
577717 |
/* And maps each event (whether native or part of a preset) to */
|
|
Packit |
577717 |
/* an event in the EventSets NativeInfoArray. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* We need to do this every time a native event is added to or removed */
|
|
Packit |
577717 |
/* from an eventset. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* It is also called after a update controlstate as the components are */
|
|
Packit |
577717 |
/* allowed to re-arrange the native events to fit hardware constraints. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_map_events_to_native( EventSetInfo_t *ESI)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: ESI: %p, ESI->EventInfoArray: %p, ESI->NativeInfoArray: %p, ESI->NumberOfEvents: %d, ESI->NativeCount: %d\n", ESI, ESI->EventInfoArray, ESI->NativeInfoArray, ESI->NumberOfEvents, ESI->NativeCount);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i, event, k, n, preset_index = 0, nevt;
|
|
Packit |
577717 |
int total_events = ESI->NumberOfEvents;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
event = 0;
|
|
Packit |
577717 |
for( i = 0; i < total_events; i++ ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* find the first event that isn't PAPI_NULL */
|
|
Packit |
577717 |
/* Is this really necessary? --vmw */
|
|
Packit |
577717 |
while ( ESI->EventInfoArray[event].event_code == ( unsigned int ) PAPI_NULL ) {
|
|
Packit |
577717 |
event++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If it's a preset */
|
|
Packit |
577717 |
if ( IS_PRESET(ESI->EventInfoArray[event].event_code) ) {
|
|
Packit |
577717 |
preset_index = ( int ) ESI->EventInfoArray[event].event_code & PAPI_PRESET_AND_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* walk all sub-events in the preset */
|
|
Packit |
577717 |
for( k = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT; k++ ) {
|
|
Packit |
577717 |
nevt = _papi_hwi_presets[preset_index].code[k];
|
|
Packit |
577717 |
if ( nevt == PAPI_NULL ) {
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("Looking for subevent %#x\n",nevt);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Match each sub-event to something in the Native List */
|
|
Packit |
577717 |
for( n = 0; n < ESI->NativeCount; n++ ) {
|
|
Packit |
577717 |
if ( nevt == ESI->NativeInfoArray[n].ni_papi_code ) {
|
|
Packit |
577717 |
INTDBG("Found papi event: %#x, &ESI->NativeInfoArray[%d]: %p, ni_event: %#x, ni_position %d\n",
|
|
Packit |
577717 |
nevt, n, &(ESI->NativeInfoArray[n]), ESI->NativeInfoArray[n].ni_event, ESI->NativeInfoArray[n].ni_position);
|
|
Packit |
577717 |
ESI->EventInfoArray[event].pos[k] = ESI->NativeInfoArray[n].ni_position;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* If it's a native event */
|
|
Packit |
577717 |
else if( IS_NATIVE(ESI->EventInfoArray[event].event_code) ) {
|
|
Packit |
577717 |
nevt = ( int ) ESI->EventInfoArray[event].event_code;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// get index into native info array for this event
|
|
Packit |
577717 |
int nidx = event_already_in_eventset( ESI, nevt );
|
|
Packit |
577717 |
// if not found, then we need to return an error
|
|
Packit |
577717 |
if (nidx == PAPI_ENOEVNT) {
|
|
Packit |
577717 |
INTDBG("EXIT: needed event not found\n");
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
ESI->EventInfoArray[event].pos[0] = ESI->NativeInfoArray[nidx].ni_position;
|
|
Packit |
577717 |
INTDBG("nidx: %d, ni_position: %d\n", nidx, ESI->NativeInfoArray[nidx].ni_position);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* If it's a user-defined event */
|
|
Packit |
577717 |
else if ( IS_USER_DEFINED(ESI->EventInfoArray[event].event_code) ) {
|
|
Packit |
577717 |
preset_index = ( int ) ESI->EventInfoArray[event].event_code & PAPI_UE_AND_MASK;
|
|
Packit |
577717 |
for ( k = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT; k++ ) {
|
|
Packit |
577717 |
nevt = user_defined_events[preset_index].code[k];
|
|
Packit |
577717 |
INTDBG("nevt: %#x, user_defined_events[%d].code[%d]: %#x, code[%d]: %#x\n",
|
|
Packit |
577717 |
nevt, preset_index, k, user_defined_events[preset_index].code[k], k+1, user_defined_events[preset_index].code[k+1]);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( nevt == PAPI_NULL ) break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Match each sub-event to something in the Native List */
|
|
Packit |
577717 |
for ( n = 0; n < ESI->NativeCount; n++ ) {
|
|
Packit |
577717 |
// if this is the event we are looking for, set its position and exit inner loop to look for next sub-event
|
|
Packit |
577717 |
if ( _papi_hwi_eventcode_to_native(nevt) == ESI->NativeInfoArray[n].ni_event ) {
|
|
Packit |
577717 |
ESI->EventInfoArray[event].pos[k] = ESI->NativeInfoArray[n].ni_position;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
event++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG("EXIT: \n");
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
add_native_fail_clean( EventSetInfo_t *ESI, int nevt )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: ESI: %p, nevt: %#x\n", ESI, nevt);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i, max_counters;
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
cidx = _papi_hwi_component_index( nevt );
|
|
Packit |
577717 |
if (cidx<0) return PAPI_ENOCMP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
max_counters = _papi_hwd[cidx]->cmp_info.num_mpx_cntrs;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* to find the native event from the native events list */
|
|
Packit |
577717 |
for( i = 0; i < max_counters; i++ ) {
|
|
Packit |
577717 |
// INTDBG("ESI->NativeInfoArray[%d]: %p, ni_event: %#x, ni_papi_event_code: %#x, ni_position: %d, ni_owners: %d\n",
|
|
Packit |
577717 |
// i, &(ESI->NativeInfoArray[i]), ESI->NativeInfoArray[i].ni_event, ESI->NativeInfoArray[i].ni_papi_code, ESI->NativeInfoArray[i].ni_position, ESI->NativeInfoArray[i].ni_owners);
|
|
Packit |
577717 |
if ( nevt == ESI->NativeInfoArray[i].ni_papi_code ) {
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_owners--;
|
|
Packit |
577717 |
/* to clean the entry in the nativeInfo array */
|
|
Packit |
577717 |
if ( ESI->NativeInfoArray[i].ni_owners == 0 ) {
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_event = -1;
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_position = -1;
|
|
Packit |
577717 |
ESI->NativeInfoArray[i].ni_papi_code = -1;
|
|
Packit |
577717 |
ESI->NativeCount--;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "EXIT: nevt: %#x, returned: %d\n", nevt, i);
|
|
Packit |
577717 |
return i;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "EXIT: returned: -1\n");
|
|
Packit |
577717 |
return -1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* since update_control_state trashes overflow settings, this puts things
|
|
Packit |
577717 |
back into balance. */
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
update_overflow( EventSetInfo_t * ESI )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i, retval = PAPI_OK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
|
|
Packit |
577717 |
for( i = 0; i < ESI->overflow.event_counter; i++ ) {
|
|
Packit |
577717 |
retval = _papi_hwd[ESI->CmpIdx]->set_overflow( ESI,
|
|
Packit |
577717 |
ESI->overflow.EventIndex[i],
|
|
Packit |
577717 |
ESI->overflow.threshold[i] );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* this function is called by _papi_hwi_add_event when adding native events
|
|
Packit |
577717 |
ESI: event set to add the events to
|
|
Packit |
577717 |
nevnt: pointer to array of native event table indexes to add
|
|
Packit |
577717 |
size: number of native events to add
|
|
Packit |
577717 |
out: ???
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return: < 0 = error
|
|
Packit |
577717 |
0 = no new events added
|
|
Packit |
577717 |
1 = new events added
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
add_native_events( EventSetInfo_t *ESI, unsigned int *nevt,
|
|
Packit |
577717 |
int size, EventInfo_t *out )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG ("ENTER: ESI: %p, nevt: %p, size: %d, out: %p\n", ESI, nevt, size, out);
|
|
Packit |
577717 |
int nidx, i, j, added_events = 0;
|
|
Packit |
577717 |
int retval, retval2;
|
|
Packit |
577717 |
int max_counters;
|
|
Packit |
577717 |
hwd_context_t *context;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
max_counters = _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Walk through the list of native events, adding them */
|
|
Packit |
577717 |
for( i = 0; i < size; i++ ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Check to see if event is already in EventSet */
|
|
Packit |
577717 |
nidx = event_already_in_eventset( ESI, nevt[i] );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( nidx >= 0 ) {
|
|
Packit |
577717 |
/* Event is already there. Set position */
|
|
Packit |
577717 |
out->pos[i] = ESI->NativeInfoArray[nidx].ni_position;
|
|
Packit |
577717 |
ESI->NativeInfoArray[nidx].ni_owners++;
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Event wasn't already there */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->NativeCount == max_counters ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* No more room in counters! */
|
|
Packit |
577717 |
for( j = 0; j < i; j++ ) {
|
|
Packit |
577717 |
if ( ( nidx = add_native_fail_clean( ESI, nevt[j] ) ) >= 0 ) {
|
|
Packit |
577717 |
out->pos[j] = -1;
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "should not happen!\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "EXIT: counters are full!\n" );
|
|
Packit |
577717 |
return PAPI_ECOUNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* there is an empty slot for the native event; */
|
|
Packit |
577717 |
/* initialize the native index for the new added event */
|
|
Packit |
577717 |
INTDBG( "Adding nevt[%d]: %#x, ESI->NativeInfoArray[%d]: %p, Component: %d\n",
|
|
Packit |
577717 |
i, nevt[i], ESI->NativeCount, &ESI->NativeInfoArray[ESI->NativeCount], ESI->CmpIdx );
|
|
Packit |
577717 |
ESI->NativeInfoArray[ESI->NativeCount].ni_event =
|
|
Packit |
577717 |
_papi_hwi_eventcode_to_native(nevt[i]);
|
|
Packit |
577717 |
ESI->NativeInfoArray[ESI->NativeCount].ni_papi_code = nevt[i];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->NativeInfoArray[ESI->NativeCount].ni_owners = 1;
|
|
Packit |
577717 |
ESI->NativeCount++;
|
|
Packit |
577717 |
added_events++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("added_events: %d\n", added_events);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* if we added events we need to tell the component so it */
|
|
Packit |
577717 |
/* can add them too. */
|
|
Packit |
577717 |
if ( added_events ) {
|
|
Packit |
577717 |
/* get the context we should use for this event set */
|
|
Packit |
577717 |
context = _papi_hwi_get_context( ESI, NULL );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwd[ESI->CmpIdx]->allocate_registers( ESI ) == PAPI_OK ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _papi_hwd[ESI->CmpIdx]->update_control_state( ESI->ctl_state,
|
|
Packit |
577717 |
ESI->NativeInfoArray,
|
|
Packit |
577717 |
ESI->NativeCount,
|
|
Packit |
577717 |
context);
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
clean:
|
|
Packit |
577717 |
for( i = 0; i < size; i++ ) {
|
|
Packit |
577717 |
if ( ( nidx = add_native_fail_clean( ESI, nevt[i] ) ) >= 0 ) {
|
|
Packit |
577717 |
out->pos[i] = -1;
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "should not happen!\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* re-establish the control state after the previous error */
|
|
Packit |
577717 |
retval2 = _papi_hwd[ESI->CmpIdx]->update_control_state(
|
|
Packit |
577717 |
ESI->ctl_state,
|
|
Packit |
577717 |
ESI->NativeInfoArray,
|
|
Packit |
577717 |
ESI->NativeCount,
|
|
Packit |
577717 |
context);
|
|
Packit |
577717 |
if ( retval2 != PAPI_OK ) {
|
|
Packit |
577717 |
PAPIERROR("update_control_state failed to re-establish working events!" );
|
|
Packit |
577717 |
INTDBG( "EXIT: update_control_state returned: %d\n", retval2);
|
|
Packit |
577717 |
return retval2;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "EXIT: update_control_state returned: %d\n", retval);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "EXIT: update_control_state returned: %d, we return: 1 (need remap)\n", retval);
|
|
Packit |
577717 |
return 1; /* need remap */
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
retval = PAPI_EMISC;
|
|
Packit |
577717 |
goto clean;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "EXIT: PAPI_OK\n");
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_add_event( EventSetInfo_t * ESI, int EventCode )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: ESI: %p (%d), EventCode: %#x\n", ESI, ESI->EventSetIndex, EventCode);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i, j, thisindex, remap, retval = PAPI_OK;
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
cidx=_papi_hwi_component_index( EventCode );
|
|
Packit |
577717 |
if (cidx<0) return PAPI_ENOCMP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Sanity check that the new EventCode is from the same component */
|
|
Packit |
577717 |
/* as previous events. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->CmpIdx < 0 ) {
|
|
Packit |
577717 |
if ( ( retval = _papi_hwi_assign_eventset( ESI, cidx)) != PAPI_OK ) {
|
|
Packit |
577717 |
INTDBG("EXIT: Error assigning eventset to component index %d\n", cidx);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
if ( ESI->CmpIdx != cidx ) {
|
|
Packit |
577717 |
INTDBG("EXIT: Event is not valid for component index %d\n", cidx);
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Make sure the event is not present and get the next free slot. */
|
|
Packit |
577717 |
thisindex = get_free_EventCodeIndex( ESI, ( unsigned int ) EventCode );
|
|
Packit |
577717 |
if ( thisindex < PAPI_OK ) {
|
|
Packit |
577717 |
return thisindex;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("Adding event to slot %d of EventSet %d\n",thisindex,ESI->EventSetIndex);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If it is a software MPX EventSet, add it to the multiplex data structure */
|
|
Packit |
577717 |
/* and this thread's multiplex list */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !_papi_hwi_is_sw_multiplex( ESI ) ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Handle preset case */
|
|
Packit |
577717 |
if ( IS_PRESET(EventCode) ) {
|
|
Packit |
577717 |
int count;
|
|
Packit |
577717 |
int preset_index = EventCode & ( int ) PAPI_PRESET_AND_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Check if it's within the valid range */
|
|
Packit |
577717 |
if ( ( preset_index < 0 ) || ( preset_index >= PAPI_MAX_PRESET_EVENTS ) ) {
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* count the number of native events in this preset */
|
|
Packit |
577717 |
count = ( int ) _papi_hwi_presets[preset_index].count;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Check if event exists */
|
|
Packit |
577717 |
if ( !count ) {
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* check if the native events have been used as overflow events */
|
|
Packit |
577717 |
/* this is not allowed */
|
|
Packit |
577717 |
if ( ESI->state & PAPI_OVERFLOWING ) {
|
|
Packit |
577717 |
for( i = 0; i < count; i++ ) {
|
|
Packit |
577717 |
for( j = 0; j < ESI->overflow.event_counter; j++ ) {
|
|
Packit |
577717 |
if ( ESI->overflow.EventCode[j] ==(int)
|
|
Packit |
577717 |
( _papi_hwi_presets[preset_index].code[i] ) ) {
|
|
Packit |
577717 |
return PAPI_ECNFLCT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Try to add the preset. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
remap = add_native_events( ESI,
|
|
Packit |
577717 |
_papi_hwi_presets[preset_index].code,
|
|
Packit |
577717 |
count, &ESI->EventInfoArray[thisindex] );
|
|
Packit |
577717 |
if ( remap < 0 ) {
|
|
Packit |
577717 |
return remap;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
/* Fill in the EventCode (machine independent) information */
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].event_code =
|
|
Packit |
577717 |
( unsigned int ) EventCode;
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].derived =
|
|
Packit |
577717 |
_papi_hwi_presets[preset_index].derived_int;
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].ops =
|
|
Packit |
577717 |
_papi_hwi_presets[preset_index].postfix;
|
|
Packit |
577717 |
ESI->NumberOfEvents++;
|
|
Packit |
577717 |
_papi_hwi_map_events_to_native( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* Handle adding Native events */
|
|
Packit |
577717 |
else if ( IS_NATIVE(EventCode) ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Check if native event exists */
|
|
Packit |
577717 |
if ( _papi_hwi_query_native_event( ( unsigned int ) EventCode ) != PAPI_OK ) {
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* check if the native events have been used as overflow events */
|
|
Packit |
577717 |
/* This is not allowed */
|
|
Packit |
577717 |
if ( ESI->state & PAPI_OVERFLOWING ) {
|
|
Packit |
577717 |
for( j = 0; j < ESI->overflow.event_counter; j++ ) {
|
|
Packit |
577717 |
if ( EventCode == ESI->overflow.EventCode[j] ) {
|
|
Packit |
577717 |
return PAPI_ECNFLCT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Try to add the native event. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
remap = add_native_events( ESI, (unsigned int *)&EventCode, 1,
|
|
Packit |
577717 |
&ESI->EventInfoArray[thisindex] );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( remap < 0 ) {
|
|
Packit |
577717 |
return remap;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Fill in the EventCode (machine independent) information */
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].event_code =
|
|
Packit |
577717 |
( unsigned int ) EventCode;
|
|
Packit |
577717 |
ESI->NumberOfEvents++;
|
|
Packit |
577717 |
_papi_hwi_map_events_to_native( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else if ( IS_USER_DEFINED( EventCode ) ) {
|
|
Packit |
577717 |
int count;
|
|
Packit |
577717 |
int index = EventCode & PAPI_UE_AND_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( index < 0 || index >= user_defined_events_count )
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
count = ( int ) user_defined_events[index].count;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < count; i++ ) {
|
|
Packit |
577717 |
for ( j = 0; j < ESI->overflow.event_counter; j++ ) {
|
|
Packit |
577717 |
if ( ESI->overflow.EventCode[j] ==
|
|
Packit |
577717 |
(int)(user_defined_events[index].code[i]) ) {
|
|
Packit |
577717 |
return ( PAPI_EBUG );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
remap = add_native_events( ESI,
|
|
Packit |
577717 |
user_defined_events[index].code,
|
|
Packit |
577717 |
count, &ESI->EventInfoArray[thisindex] );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( remap < 0 ) {
|
|
Packit |
577717 |
return remap;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].event_code = (unsigned int) EventCode;
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].derived = user_defined_events[index].derived_int;
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].ops = user_defined_events[index].postfix;
|
|
Packit |
577717 |
ESI->NumberOfEvents++;
|
|
Packit |
577717 |
_papi_hwi_map_events_to_native( ESI );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* not Native, Preset, or User events */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_EBUG;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Multiplexing is special. See multiplex.c */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = mpx_add_event( &ESI->multiplex.mpx_evset, EventCode,
|
|
Packit |
577717 |
ESI->domain.domain,
|
|
Packit |
577717 |
ESI->granularity.granularity );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( retval < PAPI_OK ) {
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Relevant (???) */
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].event_code = ( unsigned int ) EventCode;
|
|
Packit |
577717 |
ESI->EventInfoArray[thisindex].derived = NOT_DERIVED;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->NumberOfEvents++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* event is in the EventInfoArray but not mapped to the NativeEvents */
|
|
Packit |
577717 |
/* this causes issues if you try to set overflow on the event. */
|
|
Packit |
577717 |
/* in theory this wouldn't matter anyway. */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* reinstate the overflows if any */
|
|
Packit |
577717 |
retval=update_overflow( ESI );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
remove_native_events( EventSetInfo_t *ESI, int *nevt, int size )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG( "Entry: ESI: %p, nevt: %p, size: %d\n", ESI, nevt, size);
|
|
Packit |
577717 |
NativeInfo_t *native = ESI->NativeInfoArray;
|
|
Packit |
577717 |
hwd_context_t *context;
|
|
Packit |
577717 |
int i, j, zero = 0, retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Remove the references to this event from the native events:
|
|
Packit |
577717 |
for all the metrics in this event,
|
|
Packit |
577717 |
compare to each native event in this event set,
|
|
Packit |
577717 |
and decrement owners if they match */
|
|
Packit |
577717 |
for( i = 0; i < size; i++ ) {
|
|
Packit |
577717 |
int cevt = _papi_hwi_eventcode_to_native(nevt[i]);
|
|
Packit |
577717 |
// INTDBG( "nevt[%d]: %#x, cevt: %#x\n", i, nevt[i], cevt);
|
|
Packit |
577717 |
for( j = 0; j < ESI->NativeCount; j++ ) {
|
|
Packit |
577717 |
if ((native[j].ni_event == cevt) && (native[j].ni_papi_code == nevt[i]) ) {
|
|
Packit |
577717 |
// INTDBG( "native[%d]: %p, ni_papi_code: %#x, ni_event: %#x, ni_position: %d, ni_owners: %d\n",
|
|
Packit |
577717 |
// j, &(native[j]), native[j].ni_papi_code, native[j].ni_event, native[j].ni_position, native[j].ni_owners);
|
|
Packit |
577717 |
native[j].ni_owners--;
|
|
Packit |
577717 |
if ( native[j].ni_owners == 0 ) {
|
|
Packit |
577717 |
zero++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Remove any native events from the array if owners dropped to zero.
|
|
Packit |
577717 |
The NativeInfoArray must be dense, with no empty slots, so if we
|
|
Packit |
577717 |
remove an element, we must compact the list */
|
|
Packit |
577717 |
for( i = 0; i < ESI->NativeCount; i++ ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( native[i].ni_event == -1 ) continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( native[i].ni_owners == 0 ) {
|
|
Packit |
577717 |
int copy = 0;
|
|
Packit |
577717 |
int sz = _papi_hwd[ESI->CmpIdx]->size.reg_value;
|
|
Packit |
577717 |
for( j = ESI->NativeCount - 1; j > i; j-- ) {
|
|
Packit |
577717 |
if ( native[j].ni_event == -1 || native[j].ni_owners == 0 ) continue;
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
/* copy j into i */
|
|
Packit |
577717 |
native[i].ni_event = native[j].ni_event;
|
|
Packit |
577717 |
native[i].ni_position = native[j].ni_position;
|
|
Packit |
577717 |
native[i].ni_owners = native[j].ni_owners;
|
|
Packit |
577717 |
/* copy opaque [j].ni_bits to [i].ni_bits */
|
|
Packit |
577717 |
memcpy( native[i].ni_bits, native[j].ni_bits, ( size_t ) sz );
|
|
Packit |
577717 |
/* reset j to initialized state */
|
|
Packit |
577717 |
native[j].ni_event = -1;
|
|
Packit |
577717 |
native[j].ni_position = -1;
|
|
Packit |
577717 |
native[j].ni_owners = 0;
|
|
Packit |
577717 |
copy++;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( copy == 0 ) {
|
|
Packit |
577717 |
/* set this structure back to empty state */
|
|
Packit |
577717 |
/* ni_owners is already 0 and contents of ni_bits doesn't matter */
|
|
Packit |
577717 |
native[i].ni_event = -1;
|
|
Packit |
577717 |
native[i].ni_position = -1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG( "ESI->NativeCount: %d, zero: %d\n", ESI->NativeCount, zero);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* to reset hwd_control_state values */
|
|
Packit |
577717 |
ESI->NativeCount -= zero;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If we removed any elements,
|
|
Packit |
577717 |
clear the now empty slots, reinitialize the index, and update the count.
|
|
Packit |
577717 |
Then send the info down to the component to update the hwd control structure. */
|
|
Packit |
577717 |
retval = PAPI_OK;
|
|
Packit |
577717 |
if ( zero ) {
|
|
Packit |
577717 |
/* get the context we should use for this event set */
|
|
Packit |
577717 |
context = _papi_hwi_get_context( ESI, NULL );
|
|
Packit |
577717 |
retval = _papi_hwd[ESI->CmpIdx]->update_control_state( ESI->ctl_state,
|
|
Packit |
577717 |
native, ESI->NativeCount, context);
|
|
Packit |
577717 |
if ( retval == PAPI_OK )
|
|
Packit |
577717 |
retval = update_overflow( ESI );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_remove_event( EventSetInfo_t * ESI, int EventCode )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int j = 0, retval, thisindex;
|
|
Packit |
577717 |
EventInfo_t *array;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
thisindex =
|
|
Packit |
577717 |
_papi_hwi_lookup_EventCodeIndex( ESI, ( unsigned int ) EventCode );
|
|
Packit |
577717 |
if ( thisindex < PAPI_OK )
|
|
Packit |
577717 |
return ( thisindex );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If it is a MPX EventSet, remove it from the multiplex data structure and
|
|
Packit |
577717 |
this threads multiplex list */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
|
|
Packit |
577717 |
retval = mpx_remove_event( &ESI->multiplex.mpx_evset, EventCode );
|
|
Packit |
577717 |
if ( retval < PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
} else
|
|
Packit |
577717 |
/* Remove the events hardware dependent stuff from the EventSet */
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if ( IS_PRESET(EventCode) ) {
|
|
Packit |
577717 |
int preset_index = EventCode & PAPI_PRESET_AND_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Check if it's within the valid range */
|
|
Packit |
577717 |
if ( ( preset_index < 0 ) ||
|
|
Packit |
577717 |
( preset_index >= PAPI_MAX_PRESET_EVENTS ) )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Check if event exists */
|
|
Packit |
577717 |
if ( !_papi_hwi_presets[preset_index].count )
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Remove the preset event. */
|
|
Packit |
577717 |
for ( j = 0; _papi_hwi_presets[preset_index].code[j] != (unsigned int)PAPI_NULL;
|
|
Packit |
577717 |
j++ );
|
|
Packit |
577717 |
retval = remove_native_events( ESI, ( int * )_papi_hwi_presets[preset_index].code, j );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
} else if ( IS_NATIVE(EventCode) ) {
|
|
Packit |
577717 |
/* Check if native event exists */
|
|
Packit |
577717 |
if ( _papi_hwi_query_native_event( ( unsigned int ) EventCode ) !=
|
|
Packit |
577717 |
PAPI_OK )
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Remove the native event. */
|
|
Packit |
577717 |
retval = remove_native_events( ESI, &EventCode, 1 );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
} else if ( IS_USER_DEFINED( EventCode ) ) {
|
|
Packit |
577717 |
int index = EventCode & PAPI_UE_AND_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( (index < 0) || (index >= user_defined_events_count) )
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT &&
|
|
Packit |
577717 |
user_defined_events[index].code[j] != 0; j++ ) {
|
|
Packit |
577717 |
retval = remove_native_events( ESI, ( int * )user_defined_events[index].code, j);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
array = ESI->EventInfoArray;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Compact the Event Info Array list if it's not the last event */
|
|
Packit |
577717 |
/* clear the newly empty slot in the array */
|
|
Packit |
577717 |
for ( ; thisindex < ESI->NumberOfEvents - 1; thisindex++ )
|
|
Packit |
577717 |
array[thisindex] = array[thisindex + 1];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
array[thisindex].event_code = ( unsigned int ) PAPI_NULL;
|
|
Packit |
577717 |
for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ )
|
|
Packit |
577717 |
array[thisindex].pos[j] = PAPI_NULL;
|
|
Packit |
577717 |
array[thisindex].ops = NULL;
|
|
Packit |
577717 |
array[thisindex].derived = NOT_DERIVED;
|
|
Packit |
577717 |
ESI->NumberOfEvents--;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_read( hwd_context_t * context, EventSetInfo_t * ESI,
|
|
Packit |
577717 |
long long *values )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: context: %p, ESI: %p, values: %p\n", context, ESI, values);
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
long long *dp = NULL;
|
|
Packit |
577717 |
int i, index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _papi_hwd[ESI->CmpIdx]->read( context, ESI->ctl_state,
|
|
Packit |
577717 |
&dp, ESI->state );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
INTDBG("EXIT: retval: %d\n", retval);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This routine distributes hardware counters to software counters in the
|
|
Packit |
577717 |
order that they were added. Note that the higher level
|
|
Packit |
577717 |
EventInfoArray[i] entries may not be contiguous because the user
|
|
Packit |
577717 |
has the right to remove an event.
|
|
Packit |
577717 |
But if we do compaction after remove event, this function can be
|
|
Packit |
577717 |
changed.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i != ESI->NumberOfEvents; i++ ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
index = ESI->EventInfoArray[i].pos[0];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( index == -1 )
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG( "ESI->EventInfoArray: %p, pos[%d]: %d, dp[%d]: %lld, derived[%d]: %#x\n", ESI->EventInfoArray, i, index, index, dp[index], i, ESI->EventInfoArray[i].derived );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If this is not a derived event */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->EventInfoArray[i].derived == NOT_DERIVED ) {
|
|
Packit |
577717 |
values[i] = dp[index];
|
|
Packit |
577717 |
INTDBG( "value: %#llx\n", values[i] );
|
|
Packit |
577717 |
} else { /* If this is a derived event */
|
|
Packit |
577717 |
values[i] = handle_derived( &ESI->EventInfoArray[i], dp );
|
|
Packit |
577717 |
#ifdef DEBUG
|
|
Packit |
577717 |
if ( values[i] < ( long long ) 0 ) {
|
|
Packit |
577717 |
INTDBG( "Derived Event is negative!!: %lld\n", values[i] );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "derived value: %#llx \n", values[i] );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_OK\n");
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_cleanup_eventset( EventSetInfo_t * ESI )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i, j, num_cntrs, retval;
|
|
Packit |
577717 |
hwd_context_t *context;
|
|
Packit |
577717 |
int EventCode;
|
|
Packit |
577717 |
NativeInfo_t *native;
|
|
Packit |
577717 |
if ( !_papi_hwi_invalid_cmp( ESI->CmpIdx ) ) {
|
|
Packit |
577717 |
num_cntrs = _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
|
|
Packit |
577717 |
EventCode=ESI->EventInfoArray[i].event_code;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* skip if event not there */
|
|
Packit |
577717 |
if ( EventCode == PAPI_NULL ) continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If it is a MPX EventSet, remove it from the multiplex */
|
|
Packit |
577717 |
/* data structure and this thread's multiplex list */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
|
|
Packit |
577717 |
retval = mpx_remove_event( &ESI->multiplex.mpx_evset, EventCode );
|
|
Packit |
577717 |
if ( retval < PAPI_OK )
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
native = ESI->NativeInfoArray;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* clear out ESI->NativeInfoArray */
|
|
Packit |
577717 |
/* do we really need to do this, seeing as we free() it later? */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for( j = 0; j < ESI->NativeCount; j++ ) {
|
|
Packit |
577717 |
native[j].ni_event = -1;
|
|
Packit |
577717 |
native[j].ni_position = -1;
|
|
Packit |
577717 |
native[j].ni_owners = 0;
|
|
Packit |
577717 |
/* native[j].ni_bits?? */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* do we really need to do this, seeing as we free() it later? */
|
|
Packit |
577717 |
ESI->EventInfoArray[i].event_code= ( unsigned int ) PAPI_NULL;
|
|
Packit |
577717 |
for( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
|
|
Packit |
577717 |
ESI->EventInfoArray[i].pos[j] = PAPI_NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
ESI->EventInfoArray[i].ops = NULL;
|
|
Packit |
577717 |
ESI->EventInfoArray[i].derived = NOT_DERIVED;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
context = _papi_hwi_get_context( ESI, NULL );
|
|
Packit |
577717 |
/* calling with count of 0 equals a close? */
|
|
Packit |
577717 |
retval = _papi_hwd[ESI->CmpIdx]->update_control_state( ESI->ctl_state,
|
|
Packit |
577717 |
NULL, 0, context);
|
|
Packit |
577717 |
if (retval!=PAPI_OK) {
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->CmpIdx = -1;
|
|
Packit |
577717 |
ESI->NumberOfEvents = 0;
|
|
Packit |
577717 |
ESI->NativeCount = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( ESI->state & PAPI_MULTIPLEXING ) && ESI->multiplex.mpx_evset )
|
|
Packit |
577717 |
papi_free( ESI->multiplex.mpx_evset );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( ESI->state & PAPI_CPU_ATTACH ) && ESI->CpuInfo )
|
|
Packit |
577717 |
_papi_hwi_shutdown_cpu( ESI->CpuInfo );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->ctl_state )
|
|
Packit |
577717 |
papi_free( ESI->ctl_state );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->sw_stop )
|
|
Packit |
577717 |
papi_free( ESI->sw_stop );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->hw_start )
|
|
Packit |
577717 |
papi_free( ESI->hw_start );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->EventInfoArray )
|
|
Packit |
577717 |
papi_free( ESI->EventInfoArray );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->NativeInfoArray )
|
|
Packit |
577717 |
papi_free( ESI->NativeInfoArray );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->NativeBits )
|
|
Packit |
577717 |
papi_free( ESI->NativeBits );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->overflow.deadline )
|
|
Packit |
577717 |
papi_free( ESI->overflow.deadline );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->profile.prof )
|
|
Packit |
577717 |
papi_free( ESI->profile.prof );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->ctl_state = NULL;
|
|
Packit |
577717 |
ESI->sw_stop = NULL;
|
|
Packit |
577717 |
ESI->hw_start = NULL;
|
|
Packit |
577717 |
ESI->EventInfoArray = NULL;
|
|
Packit |
577717 |
ESI->NativeInfoArray = NULL;
|
|
Packit |
577717 |
ESI->NativeBits = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( &ESI->domain, 0x0, sizeof(EventSetDomainInfo_t) );
|
|
Packit |
577717 |
memset( &ESI->granularity, 0x0, sizeof(EventSetGranularityInfo_t) );
|
|
Packit |
577717 |
memset( &ESI->overflow, 0x0, sizeof(EventSetOverflowInfo_t) );
|
|
Packit |
577717 |
memset( &ESI->multiplex, 0x0, sizeof(EventSetMultiplexInfo_t) );
|
|
Packit |
577717 |
memset( &ESI->attach, 0x0, sizeof(EventSetAttachInfo_t) );
|
|
Packit |
577717 |
memset( &ESI->cpu, 0x0, sizeof(EventSetCpuInfo_t) );
|
|
Packit |
577717 |
memset( &ESI->profile, 0x0, sizeof(EventSetProfileInfo_t) );
|
|
Packit |
577717 |
memset( &ESI->inherit, 0x0, sizeof(EventSetInheritInfo_t) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->CpuInfo = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_convert_eventset_to_multiplex( _papi_int_multiplex_t * mpx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval, i, j = 0, *mpxlist = NULL;
|
|
Packit |
577717 |
EventSetInfo_t *ESI = mpx->ESI;
|
|
Packit |
577717 |
int flags = mpx->flags;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If there are any events in the EventSet,
|
|
Packit |
577717 |
convert them to multiplex events */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->NumberOfEvents ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
mpxlist =
|
|
Packit |
577717 |
( int * ) papi_malloc( sizeof ( int ) *
|
|
Packit |
577717 |
( size_t ) ESI->NumberOfEvents );
|
|
Packit |
577717 |
if ( mpxlist == NULL )
|
|
Packit |
577717 |
return ( PAPI_ENOMEM );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Build the args to MPX_add_events(). */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Remember the EventInfoArray can be sparse
|
|
Packit |
577717 |
and the data can be non-contiguous */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < EventInfoArrayLength( ESI ); i++ )
|
|
Packit |
577717 |
if ( ESI->EventInfoArray[i].event_code !=
|
|
Packit |
577717 |
( unsigned int ) PAPI_NULL )
|
|
Packit |
577717 |
mpxlist[j++] = ( int ) ESI->EventInfoArray[i].event_code;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Resize the EventInfo_t array */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex == 0 ) ||
|
|
Packit |
577717 |
( ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex ) &&
|
|
Packit |
577717 |
( flags & PAPI_MULTIPLEX_FORCE_SW ) ) ) {
|
|
Packit |
577717 |
retval =
|
|
Packit |
577717 |
MPX_add_events( &ESI->multiplex.mpx_evset, mpxlist, j,
|
|
Packit |
577717 |
ESI->domain.domain,
|
|
Packit |
577717 |
ESI->granularity.granularity );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
papi_free( mpxlist );
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
papi_free( mpxlist );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Update the state before initialization! */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ESI->state |= PAPI_MULTIPLEXING;
|
|
Packit |
577717 |
if ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex &&
|
|
Packit |
577717 |
( flags & PAPI_MULTIPLEX_FORCE_SW ) )
|
|
Packit |
577717 |
ESI->multiplex.flags = PAPI_MULTIPLEX_FORCE_SW;
|
|
Packit |
577717 |
ESI->multiplex.ns = ( int ) mpx->ns;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "components_config.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int papi_num_components = ( sizeof ( _papi_hwd ) / sizeof ( *_papi_hwd ) ) - 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Routine that initializes all available components.
|
|
Packit |
577717 |
* A component is available if a pointer to its info vector
|
|
Packit |
577717 |
* appears in the NULL terminated_papi_hwd table.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_init_global( void )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval, i = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _papi_hwi_innoculate_os_vector( &_papi_os_vector );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
while ( _papi_hwd[i] ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _papi_hwi_innoculate_vector( _papi_hwd[i] );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* We can be disabled by user before init */
|
|
Packit |
577717 |
if (!_papi_hwd[i]->cmp_info.disabled) {
|
|
Packit |
577717 |
retval = _papi_hwd[i]->init_component( i );
|
|
Packit |
577717 |
_papi_hwd[i]->cmp_info.disabled=retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Do some sanity checking */
|
|
Packit |
577717 |
if (retval==PAPI_OK) {
|
|
Packit |
577717 |
if (_papi_hwd[i]->cmp_info.num_cntrs >
|
|
Packit |
577717 |
_papi_hwd[i]->cmp_info.num_mpx_cntrs) {
|
|
Packit |
577717 |
fprintf(stderr,"Warning! num_cntrs %d is more than num_mpx_cntrs %d for component %s\n",
|
|
Packit |
577717 |
_papi_hwd[i]->cmp_info.num_cntrs,
|
|
Packit |
577717 |
_papi_hwd[i]->cmp_info.num_mpx_cntrs,
|
|
Packit |
577717 |
_papi_hwd[i]->cmp_info.name);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
i++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Machine info struct initialization using defaults */
|
|
Packit |
577717 |
/* See _papi_mdi definition in papi_internal.h */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_init_global_internal( void )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset(&_papi_hwi_system_info,0x0,sizeof( _papi_hwi_system_info ));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( _papi_hwi_using_signal,0x0,sizeof( _papi_hwi_using_signal ));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Global struct to maintain EventSet mapping */
|
|
Packit |
577717 |
retval = allocate_eventset_map( &_papi_hwi_system_info.global_eventset_map );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_system_info.pid = 0; /* Process identifier */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* PAPI_hw_info_t struct */
|
|
Packit |
577717 |
memset(&(_papi_hwi_system_info.hw_info),0x0,sizeof(PAPI_hw_info_t));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_shutdown_global_internal( void )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
_papi_hwi_cleanup_all_presets( );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_cleanup_errors( );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_lock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
papi_free( _papi_hwi_system_info.global_eventset_map.dataSlotArray );
|
|
Packit |
577717 |
memset( &_papi_hwi_system_info.global_eventset_map,
|
|
Packit |
577717 |
0x00, sizeof ( DynamicArray_t ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_system_info.shlib_info.map ) {
|
|
Packit |
577717 |
papi_free( _papi_hwi_system_info.shlib_info.map );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
memset( &_papi_hwi_system_info, 0x0, sizeof ( _papi_hwi_system_info ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_dummy_handler( int EventSet, void *address, long long overflow_vector,
|
|
Packit |
577717 |
void *context )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* This function is not used and shouldn't be called. */
|
|
Packit |
577717 |
( void ) EventSet; /*unused */
|
|
Packit |
577717 |
( void ) address; /*unused */
|
|
Packit |
577717 |
( void ) overflow_vector; /*unused */
|
|
Packit |
577717 |
( void ) context; /*unused */
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
handle_derived_add( int *position, long long *from )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int pos, i;
|
|
Packit |
577717 |
long long retval = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
i = 0;
|
|
Packit |
577717 |
while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
|
|
Packit |
577717 |
pos = position[i++];
|
|
Packit |
577717 |
if ( pos == PAPI_NULL )
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
INTDBG( "Compound event, adding %lld to %lld\n", from[pos], retval );
|
|
Packit |
577717 |
retval += from[pos];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
handle_derived_subtract( int *position, long long *from )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int pos, i;
|
|
Packit |
577717 |
long long retval = from[position[0]];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
i = 1;
|
|
Packit |
577717 |
while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
|
|
Packit |
577717 |
pos = position[i++];
|
|
Packit |
577717 |
if ( pos == PAPI_NULL )
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
INTDBG( "Compound event, subtracting pos=%d %lld from %lld\n", pos,
|
|
Packit |
577717 |
from[pos], retval );
|
|
Packit |
577717 |
retval -= from[pos];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
units_per_second( long long units, long long cycles )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return ( ( units * (long long) _papi_hwi_system_info.hw_info.cpu_max_mhz *
|
|
Packit |
577717 |
(long long) 1000000 ) / cycles );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
handle_derived_ps( int *position, long long *from )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return ( units_per_second( from[position[1]], from[position[0]] ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
handle_derived_add_ps( int *position, long long *from )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
long long tmp = handle_derived_add( position + 1, from );
|
|
Packit |
577717 |
return ( units_per_second( tmp, from[position[0]] ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* this function implement postfix calculation, it reads in a string where I use:
|
|
Packit |
577717 |
| as delimiter
|
|
Packit |
577717 |
N2 indicate No. 2 native event in the derived preset
|
|
Packit |
577717 |
+, -, *, / as operator
|
|
Packit |
577717 |
# as MHZ(million hz) got from _papi_hwi_system_info.hw_info.cpu_max_mhz*1000000.0
|
|
Packit |
577717 |
|
|
Packit |
577717 |
Haihang (you@cs.utk.edu)
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
_papi_hwi_postfix_calc( EventInfo_t * evi, long long *hw_counter )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
char *point = evi->ops, operand[16];
|
|
Packit |
577717 |
double stack[PAPI_EVENTS_IN_DERIVED_EVENT];
|
|
Packit |
577717 |
int i, val, top = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("ENTER: evi: %p, evi->ops: %p (%s), evi->pos[0]: %d, evi->pos[1]: %d, hw_counter: %p (%lld %lld)\n",
|
|
Packit |
577717 |
evi, evi->ops, evi->ops, evi->pos[0], evi->pos[1], hw_counter, hw_counter[0], hw_counter[1]);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset(&stack,0,PAPI_EVENTS_IN_DERIVED_EVENT*sizeof(double));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
while ( *point != '\0' ) {
|
|
Packit |
577717 |
if ( *point == '|' ) { /* consume '|' characters */
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
} else if ( *point == 'N' ) { /* to get count for each native event */
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
i = 0;
|
|
Packit |
577717 |
while ( isdigit(*point) ) {
|
|
Packit |
577717 |
assert(i<16);
|
|
Packit |
577717 |
operand[i] = *point;
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
i++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
assert(0
|
|
Packit |
577717 |
operand[i] = '\0';
|
|
Packit |
577717 |
val = atoi( operand );
|
|
Packit |
577717 |
assert( top < PAPI_EVENTS_IN_DERIVED_EVENT );
|
|
Packit |
577717 |
assert( 0 <= val && val < PAPI_EVENTS_IN_DERIVED_EVENT );
|
|
Packit |
577717 |
stack[top] = ( double ) hw_counter[evi->pos[val]];
|
|
Packit |
577717 |
top++;
|
|
Packit |
577717 |
} else if ( *point == '#' ) { /* to get mhz */
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
assert( top < PAPI_EVENTS_IN_DERIVED_EVENT );
|
|
Packit |
577717 |
stack[top] = _papi_hwi_system_info.hw_info.cpu_max_mhz * 1000000.0;
|
|
Packit |
577717 |
top++;
|
|
Packit |
577717 |
} else if ( isdigit( *point ) ) {
|
|
Packit |
577717 |
i = 0;
|
|
Packit |
577717 |
while ( isdigit(*point) ) {
|
|
Packit |
577717 |
assert(i<16);
|
|
Packit |
577717 |
operand[i] = *point;
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
i++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
assert(0
|
|
Packit |
577717 |
operand[i] = '\0';
|
|
Packit |
577717 |
assert( top < PAPI_EVENTS_IN_DERIVED_EVENT );
|
|
Packit |
577717 |
stack[top] = atoi( operand );
|
|
Packit |
577717 |
top++;
|
|
Packit |
577717 |
} else if ( *point == '+' ) { /* + calculation */
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
assert(top >= 2);
|
|
Packit |
577717 |
stack[top - 2] += stack[top - 1];
|
|
Packit |
577717 |
top--;
|
|
Packit |
577717 |
} else if ( *point == '-' ) { /* - calculation */
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
assert(top >= 2);
|
|
Packit |
577717 |
stack[top - 2] -= stack[top - 1];
|
|
Packit |
577717 |
top--;
|
|
Packit |
577717 |
} else if ( *point == '*' ) { /* * calculation */
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
assert(top >= 2);
|
|
Packit |
577717 |
stack[top - 2] *= stack[top - 1];
|
|
Packit |
577717 |
top--;
|
|
Packit |
577717 |
} else if ( *point == '/' ) { /* / calculation */
|
|
Packit |
577717 |
point++;
|
|
Packit |
577717 |
assert(top >= 2);
|
|
Packit |
577717 |
/* FIXME should handle runtime divide by zero */
|
|
Packit |
577717 |
stack[top - 2] /= stack[top - 1];
|
|
Packit |
577717 |
top--;
|
|
Packit |
577717 |
} else { /* flag an error parsing the preset */
|
|
Packit |
577717 |
PAPIERROR( "BUG! Unable to parse \"%s\"", evi->ops );
|
|
Packit |
577717 |
return ( long long ) stack[0];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
assert(top == 1);
|
|
Packit |
577717 |
INTDBG("EXIT: stack[0]: %lld\n", (long long)stack[0]);
|
|
Packit |
577717 |
return ( long long ) stack[0];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
handle_derived( EventInfo_t * evi, long long *from )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: evi: %p, evi->derived: %d, from: %p\n", evi, evi->derived, from);
|
|
Packit |
577717 |
switch ( evi->derived ) {
|
|
Packit |
577717 |
case DERIVED_ADD:
|
|
Packit |
577717 |
return ( handle_derived_add( evi->pos, from ) );
|
|
Packit |
577717 |
case DERIVED_ADD_PS:
|
|
Packit |
577717 |
return ( handle_derived_add_ps( evi->pos, from ) );
|
|
Packit |
577717 |
case DERIVED_SUB:
|
|
Packit |
577717 |
return ( handle_derived_subtract( evi->pos, from ) );
|
|
Packit |
577717 |
case DERIVED_PS:
|
|
Packit |
577717 |
return ( handle_derived_ps( evi->pos, from ) );
|
|
Packit |
577717 |
case DERIVED_POSTFIX:
|
|
Packit |
577717 |
return ( _papi_hwi_postfix_calc( evi, from ) );
|
|
Packit |
577717 |
case DERIVED_CMPD: /* This type has existed for a long time, but was never implemented.
|
|
Packit |
577717 |
Probably because its a no-op. However, if it's in a header, it
|
|
Packit |
577717 |
should be supported. As I found out when I implemented it in
|
|
Packit |
577717 |
Pentium 4 for testing...dkt */
|
|
Packit |
577717 |
return ( from[evi->pos[0]] );
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
PAPIERROR( "BUG! Unknown derived command %d, returning 0", evi->derived );
|
|
Packit |
577717 |
INTDBG("EXIT: Unknown derived command %d\n", evi->derived);
|
|
Packit |
577717 |
return ( ( long long ) 0 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* table matching derived types to derived strings.
|
|
Packit |
577717 |
used by get_info, encode_event, xml translator
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static const hwi_describe_t _papi_hwi_derived[] = {
|
|
Packit |
577717 |
{NOT_DERIVED, "NOT_DERIVED", "Do nothing"},
|
|
Packit |
577717 |
{DERIVED_ADD, "DERIVED_ADD", "Add counters"},
|
|
Packit |
577717 |
{DERIVED_PS, "DERIVED_PS",
|
|
Packit |
577717 |
"Divide by the cycle counter and convert to seconds"},
|
|
Packit |
577717 |
{DERIVED_ADD_PS, "DERIVED_ADD_PS",
|
|
Packit |
577717 |
"Add 2 counters then divide by the cycle counter and xl8 to secs."},
|
|
Packit |
577717 |
{DERIVED_CMPD, "DERIVED_CMPD",
|
|
Packit |
577717 |
"Event lives in first counter but takes 2 or more codes"},
|
|
Packit |
577717 |
{DERIVED_SUB, "DERIVED_SUB", "Sub all counters from first counter"},
|
|
Packit |
577717 |
{DERIVED_POSTFIX, "DERIVED_POSTFIX",
|
|
Packit |
577717 |
"Process counters based on specified postfix string"},
|
|
Packit |
577717 |
{DERIVED_INFIX, "DERIVED_INFIX",
|
|
Packit |
577717 |
"Process counters based on specified infix string"},
|
|
Packit |
577717 |
{-1, NULL, NULL}
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* _papi_hwi_derived_type:
|
|
Packit |
577717 |
Helper routine to extract a derived type from a derived string
|
|
Packit |
577717 |
returns type value if found, otherwise returns -1
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_derived_type( char *tmp, int *code )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i = 0;
|
|
Packit |
577717 |
while ( _papi_hwi_derived[i].name != NULL ) {
|
|
Packit |
577717 |
if ( strcasecmp( tmp, _papi_hwi_derived[i].name ) == 0 ) {
|
|
Packit |
577717 |
*code = _papi_hwi_derived[i].value;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
i++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "Invalid derived string %s\n", tmp );
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* _papi_hwi_derived_string:
|
|
Packit |
577717 |
Helper routine to extract a derived string from a derived type
|
|
Packit |
577717 |
copies derived type string into derived if found,
|
|
Packit |
577717 |
otherwise returns PAPI_EINVAL
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_papi_hwi_derived_string( int type, char *derived, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int j;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( j = 0; _papi_hwi_derived[j].value != -1; j++ ) {
|
|
Packit |
577717 |
if ( _papi_hwi_derived[j].value == type ) {
|
|
Packit |
577717 |
strncpy( derived, _papi_hwi_derived[j].name, ( size_t )\
|
|
Packit |
577717 |
len );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG( "Invalid derived type %d\n", type );
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* _papi_hwi_get_preset_event_info:
|
|
Packit |
577717 |
Assumes EventCode contains a valid preset code.
|
|
Packit |
577717 |
But defensive programming says check for NULL pointers.
|
|
Packit |
577717 |
Returns a filled in PAPI_event_info_t structure containing
|
|
Packit |
577717 |
descriptive strings and values for the specified preset event.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_get_preset_event_info( int EventCode, PAPI_event_info_t * info )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i = EventCode & PAPI_PRESET_AND_MASK;
|
|
Packit |
577717 |
unsigned int j;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_presets[i].symbol ) { /* if the event is in the preset table */
|
|
Packit |
577717 |
// since we are setting the whole structure to zero the strncpy calls below will
|
|
Packit |
577717 |
// be leaving NULL terminates strings as long as they copy 1 less byte than the
|
|
Packit |
577717 |
// buffer size of the field.
|
|
Packit |
577717 |
memset( info, 0, sizeof ( PAPI_event_info_t ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
info->event_code = ( unsigned int ) EventCode;
|
|
Packit |
577717 |
strncpy( info->symbol, _papi_hwi_presets[i].symbol,
|
|
Packit |
577717 |
sizeof(info->symbol)-1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_presets[i].short_descr != NULL )
|
|
Packit |
577717 |
strncpy( info->short_descr, _papi_hwi_presets[i].short_descr,
|
|
Packit |
577717 |
sizeof ( info->short_descr )-1 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_presets[i].long_descr != NULL )
|
|
Packit |
577717 |
strncpy( info->long_descr, _papi_hwi_presets[i].long_descr,
|
|
Packit |
577717 |
sizeof ( info->long_descr )-1 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
info->event_type = _papi_hwi_presets[i].event_type;
|
|
Packit |
577717 |
info->count = _papi_hwi_presets[i].count;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_derived_string( _papi_hwi_presets[i].derived_int,
|
|
Packit |
577717 |
info->derived, sizeof ( info->derived ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_presets[i].postfix != NULL )
|
|
Packit |
577717 |
strncpy( info->postfix, _papi_hwi_presets[i].postfix,
|
|
Packit |
577717 |
sizeof ( info->postfix )-1 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(j=0;j < info->count; j++) {
|
|
Packit |
577717 |
info->code[j]=_papi_hwi_presets[i].code[j];
|
|
Packit |
577717 |
strncpy(info->name[j], _papi_hwi_presets[i].name[j],
|
|
Packit |
577717 |
sizeof(info->name[j])-1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( _papi_hwi_presets[i].note != NULL ) {
|
|
Packit |
577717 |
strncpy( info->note, _papi_hwi_presets[i].note,
|
|
Packit |
577717 |
sizeof ( info->note )-1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* _papi_hwi_get_user_event_info:
|
|
Packit |
577717 |
Assumes EventCode contains a valid user event code.
|
|
Packit |
577717 |
But defensive programming says check for NULL pointers.
|
|
Packit |
577717 |
Returns a filled in PAPI_event_info_t structure containing
|
|
Packit |
577717 |
descriptive strings and values for the specified preset event.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_get_user_event_info( int EventCode, PAPI_event_info_t * info )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
unsigned int i = EventCode & PAPI_UE_AND_MASK;
|
|
Packit |
577717 |
unsigned int j;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if event code not in valid range, return error
|
|
Packit |
577717 |
if (i >= PAPI_MAX_USER_EVENTS) {
|
|
Packit |
577717 |
INTDBG("EXIT: Invalid event index: %d, max value is: %d\n", i, PAPI_MAX_USER_EVENTS - 1);
|
|
Packit |
577717 |
return( PAPI_ENOEVNT );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( user_defined_events[i].symbol == NULL) { /* if the event is in the preset table */
|
|
Packit |
577717 |
INTDBG("EXIT: Event symbol for this event is NULL\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* set whole structure to 0 */
|
|
Packit |
577717 |
memset( info, 0, sizeof ( PAPI_event_info_t ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
info->event_code = ( unsigned int ) EventCode;
|
|
Packit |
577717 |
strncpy( info->symbol, user_defined_events[i].symbol,
|
|
Packit |
577717 |
sizeof(info->symbol)-1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( user_defined_events[i].short_descr != NULL )
|
|
Packit |
577717 |
strncpy( info->short_descr, user_defined_events[i].short_descr,
|
|
Packit |
577717 |
sizeof(info->short_descr)-1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( user_defined_events[i].long_descr != NULL )
|
|
Packit |
577717 |
strncpy( info->long_descr, user_defined_events[i].long_descr,
|
|
Packit |
577717 |
sizeof(info->long_descr)-1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// info->event_type = user_defined_events[i].event_type;
|
|
Packit |
577717 |
info->count = user_defined_events[i].count;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_papi_hwi_derived_string( user_defined_events[i].derived_int,
|
|
Packit |
577717 |
info->derived, sizeof(info->derived)-1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( user_defined_events[i].postfix != NULL )
|
|
Packit |
577717 |
strncpy( info->postfix, user_defined_events[i].postfix,
|
|
Packit |
577717 |
sizeof(info->postfix)-1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(j=0;j < info->count; j++) {
|
|
Packit |
577717 |
info->code[j]=user_defined_events[i].code[j];
|
|
Packit |
577717 |
INTDBG("info->code[%d]: %#x\n", j, info->code[j]);
|
|
Packit |
577717 |
strncpy(info->name[j], user_defined_events[i].name[j], sizeof(info->name[j])-1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( user_defined_events[i].note != NULL ) {
|
|
Packit |
577717 |
strncpy( info->note, user_defined_events[i].note, sizeof(info->note)-1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_OK: event_code: %#x, symbol: %s, short_desc: %s, long_desc: %s\n", info->event_code, info->symbol, info->short_descr, info->long_descr);
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Returns PAPI_OK if native EventCode found, or PAPI_ENOEVNT if not;
|
|
Packit |
577717 |
Used to enumerate the entire array, e.g. for native_avail.c */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_query_native_event( unsigned int EventCode )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: EventCode: %#x\n", EventCode);
|
|
Packit |
577717 |
char name[PAPI_HUGE_STR_LEN]; /* probably overkill, */
|
|
Packit |
577717 |
/* but should always be big enough */
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
int nevt_code;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
cidx = _papi_hwi_component_index( EventCode );
|
|
Packit |
577717 |
if (cidx<0) {
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOCMP\n");
|
|
Packit |
577717 |
return PAPI_ENOCMP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
|
|
Packit |
577717 |
_papi_hwi_set_papi_event_code(EventCode, 0);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
|
|
Packit |
577717 |
INTDBG("EXIT: nevt_code: %d\n", nevt_code);
|
|
Packit |
577717 |
return nevt_code;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
int ret = _papi_hwd[cidx]->ntv_code_to_name( (unsigned int)nevt_code, name, sizeof(name));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: ret: %d\n", ret);
|
|
Packit |
577717 |
return (ret);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Converts an ASCII name into a native event code usable by other routines
|
|
Packit |
577717 |
Returns code = 0 and PAPI_OK if name not found.
|
|
Packit |
577717 |
This allows for sparse native event arrays */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_native_name_to_code( const char *in, int *out )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: in: %s, out: %p\n", in, out);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int retval = PAPI_ENOEVNT;
|
|
Packit |
577717 |
char name[PAPI_HUGE_STR_LEN]; /* make sure it's big enough */
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
char *full_event_name;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (in == NULL) {
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_EINVAL\n");
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
full_event_name = strdup(in);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
in = _papi_hwi_strip_component_prefix(in);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// look in each component
|
|
Packit |
577717 |
for(cidx=0; cidx < papi_num_components; cidx++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (_papi_hwd[cidx]->cmp_info.disabled) continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if this component does not support the pmu which defines this event, no need to call it
|
|
Packit |
577717 |
if (is_supported_by_component(cidx, full_event_name) == 0) continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("cidx: %d, name: %s, event: %s\n", cidx, _papi_hwd[cidx]->cmp_info.name, in);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// show that we do not have an event code yet (the component may create one and update this info)
|
|
Packit |
577717 |
// this also clears any values left over from a previous call
|
|
Packit |
577717 |
_papi_hwi_set_papi_event_code(-1, -1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if component has a ntv_name_to_code function, use it to get event code
|
|
Packit |
577717 |
if (_papi_hwd[cidx]->ntv_name_to_code != NULL) {
|
|
Packit |
577717 |
// try and get this events event code
|
|
Packit |
577717 |
retval = _papi_hwd[cidx]->ntv_name_to_code( in, ( unsigned * ) out );
|
|
Packit |
577717 |
if (retval==PAPI_OK) {
|
|
Packit |
577717 |
*out = _papi_hwi_native_to_eventcode(cidx, *out, -1, in);
|
|
Packit |
577717 |
free (full_event_name);
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_OK event: %s code: %#x\n", in, *out);
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
// force the code through the work around
|
|
Packit |
577717 |
retval = PAPI_ECMP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If not implemented, work around */
|
|
Packit |
577717 |
if ( retval==PAPI_ECMP) {
|
|
Packit |
577717 |
i = 0;
|
|
Packit |
577717 |
retval = _papi_hwd[cidx]->ntv_enum_events( &i, PAPI_ENUM_FIRST );
|
|
Packit |
577717 |
if (retval != PAPI_OK) {
|
|
Packit |
577717 |
free (full_event_name);
|
|
Packit |
577717 |
INTDBG("EXIT: retval: %d\n", retval);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// _papi_hwi_lock( INTERNAL_LOCK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
do {
|
|
Packit |
577717 |
// save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
|
|
Packit |
577717 |
_papi_hwi_set_papi_event_code(i, 0);
|
|
Packit |
577717 |
retval = _papi_hwd[cidx]->ntv_code_to_name(i, name, sizeof(name));
|
|
Packit |
577717 |
/* printf("%#x\nname =|%s|\ninput=|%s|\n", i, name, in); */
|
|
Packit |
577717 |
if ( retval == PAPI_OK && in != NULL) {
|
|
Packit |
577717 |
if ( strcasecmp( name, in ) == 0 ) {
|
|
Packit |
577717 |
*out = _papi_hwi_native_to_eventcode(cidx, i, -1, name);
|
|
Packit |
577717 |
free (full_event_name);
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_OK, event: %s, code: %#x\n", in, *out);
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
retval = PAPI_ENOEVNT;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
*out = 0;
|
|
Packit |
577717 |
retval = PAPI_ENOEVNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} while ( ( _papi_hwd[cidx]->ntv_enum_events( &i, PAPI_ENUM_EVENTS ) == PAPI_OK ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// _papi_hwi_unlock( INTERNAL_LOCK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
free (full_event_name);
|
|
Packit |
577717 |
INTDBG("EXIT: retval: %d\n", retval);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Returns event name based on native event code.
|
|
Packit |
577717 |
Returns NULL if name not found */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_native_code_to_name( unsigned int EventCode,
|
|
Packit |
577717 |
char *hwi_name, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: EventCode: %#x, hwi_name: %p, len: %d\n", EventCode, hwi_name, len);
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
int nevt_code;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
cidx = _papi_hwi_component_index( EventCode );
|
|
Packit |
577717 |
if (cidx<0) return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( EventCode & PAPI_NATIVE_MASK ) {
|
|
Packit |
577717 |
// save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
|
|
Packit |
577717 |
_papi_hwi_set_papi_event_code(EventCode, 0);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
|
|
Packit |
577717 |
INTDBG("EXIT: nevt_code: %d\n", nevt_code);
|
|
Packit |
577717 |
return nevt_code;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if ( (retval = _papi_hwd[cidx]->ntv_code_to_name(
|
|
Packit |
577717 |
(unsigned int)nevt_code,
|
|
Packit |
577717 |
hwi_name, len) ) == PAPI_OK ) {
|
|
Packit |
577717 |
retval = _papi_hwi_prefix_component_name( _papi_hwd[cidx]->cmp_info.short_name,
|
|
Packit |
577717 |
hwi_name, hwi_name, len);
|
|
Packit |
577717 |
INTDBG("EXIT: retval: %d\n", retval);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG("EXIT: retval: %d\n", retval);
|
|
Packit |
577717 |
return (retval);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOEVNT\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* The native event equivalent of PAPI_get_event_info */
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_get_native_event_info( unsigned int EventCode,
|
|
Packit |
577717 |
PAPI_event_info_t *info )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
int cidx;
|
|
Packit |
577717 |
int nevt_code;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
cidx = _papi_hwi_component_index( EventCode );
|
|
Packit |
577717 |
if (cidx<0) return PAPI_ENOCMP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (_papi_hwd[cidx]->cmp_info.disabled) return PAPI_ENOCMP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( EventCode & PAPI_NATIVE_MASK ) {
|
|
Packit |
577717 |
// save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
|
|
Packit |
577717 |
_papi_hwi_set_papi_event_code(EventCode, 0);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* clear the event info */
|
|
Packit |
577717 |
memset( info, 0, sizeof ( PAPI_event_info_t ) );
|
|
Packit |
577717 |
info->event_code = ( unsigned int ) EventCode;
|
|
Packit |
577717 |
info->component_index = (unsigned int) cidx;
|
|
Packit |
577717 |
retval = _papi_hwd[cidx]->ntv_code_to_info(
|
|
Packit |
577717 |
_papi_hwi_eventcode_to_native(EventCode), info);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If component error, it's missing the ntv_code_to_info vector */
|
|
Packit |
577717 |
/* so we'll have to fake it. */
|
|
Packit |
577717 |
if ( retval == PAPI_ECMP ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("missing NTV_CODE_TO_INFO, faking\n");
|
|
Packit |
577717 |
/* Fill in the info structure */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
|
|
Packit |
577717 |
INTDBG("EXIT: nevt_code: %d\n", nevt_code);
|
|
Packit |
577717 |
return nevt_code;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if ( (retval = _papi_hwd[cidx]->ntv_code_to_name(
|
|
Packit |
577717 |
(unsigned int)nevt_code,
|
|
Packit |
577717 |
info->symbol,
|
|
Packit |
577717 |
sizeof(info->symbol)) ) == PAPI_OK ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
INTDBG("EXIT: retval: %d\n", retval);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) <0) {
|
|
Packit |
577717 |
INTDBG("EXIT: nevt_code: %d\n", nevt_code);
|
|
Packit |
577717 |
return nevt_code;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
retval = _papi_hwd[cidx]->ntv_code_to_descr(
|
|
Packit |
577717 |
(unsigned int)nevt_code,
|
|
Packit |
577717 |
info->long_descr,
|
|
Packit |
577717 |
sizeof ( info->long_descr));
|
|
Packit |
577717 |
if (retval!=PAPI_OK) {
|
|
Packit |
577717 |
INTDBG("Failed ntv_code_to_descr()\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
retval = _papi_hwi_prefix_component_name(
|
|
Packit |
577717 |
_papi_hwd[cidx]->cmp_info.short_name,
|
|
Packit |
577717 |
info->symbol,
|
|
Packit |
577717 |
info->symbol,
|
|
Packit |
577717 |
sizeof(info->symbol) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: retval: %d\n", retval);
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
INTDBG("EXIT: PAPI_ENOEVNT\n");
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
EventSetInfo_t *
|
|
Packit |
577717 |
_papi_hwi_lookup_EventSet( int eventset )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
const DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
|
|
Packit |
577717 |
EventSetInfo_t *set;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( eventset < 0 ) || ( eventset > map->totalSlots ) )
|
|
Packit |
577717 |
return ( NULL );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
set = map->dataSlotArray[eventset];
|
|
Packit |
577717 |
#ifdef DEBUG
|
|
Packit |
577717 |
if ( ( ISLEVEL( DEBUG_THREADS ) ) && ( _papi_hwi_thread_id_fn ) &&
|
|
Packit |
577717 |
( set->master->tid != _papi_hwi_thread_id_fn( ) ) )
|
|
Packit |
577717 |
return ( NULL );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( set );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_papi_hwi_is_sw_multiplex(EventSetInfo_t *ESI)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* Are we multiplexing at all */
|
|
Packit |
577717 |
if ( ( ESI->state & PAPI_MULTIPLEXING ) == 0 ) {
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Does the component support kernel multiplexing */
|
|
Packit |
577717 |
if ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex ) {
|
|
Packit |
577717 |
/* Have we forced software multiplexing */
|
|
Packit |
577717 |
if ( ESI->multiplex.flags == PAPI_MULTIPLEX_FORCE_SW ) {
|
|
Packit |
577717 |
return 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* Nope, using hardware multiplexing */
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* We are multiplexing but the component does not support hardware */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
hwd_context_t *
|
|
Packit |
577717 |
_papi_hwi_get_context( EventSetInfo_t * ESI, int *is_dirty )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
INTDBG("Entry: ESI: %p, is_dirty: %p\n", ESI, is_dirty);
|
|
Packit |
577717 |
int dirty_ctx;
|
|
Packit |
577717 |
hwd_context_t *ctx=NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* assume for now the control state is clean (last updated by this ESI) */
|
|
Packit |
577717 |
dirty_ctx = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* get a context pointer based on if we are counting for a thread or for a cpu */
|
|
Packit |
577717 |
if (ESI->state & PAPI_CPU_ATTACHED) {
|
|
Packit |
577717 |
/* use cpu context */
|
|
Packit |
577717 |
ctx = ESI->CpuInfo->context[ESI->CmpIdx];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* if the user wants to know if the control state was last set by the same event set, tell him */
|
|
Packit |
577717 |
if (is_dirty != NULL) {
|
|
Packit |
577717 |
if (ESI->CpuInfo->from_esi != ESI) {
|
|
Packit |
577717 |
dirty_ctx = 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*is_dirty = dirty_ctx;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
ESI->CpuInfo->from_esi = ESI;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* use thread context */
|
|
Packit |
577717 |
ctx = ESI->master->context[ESI->CmpIdx];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* if the user wants to know if the control state was last set by the same event set, tell him */
|
|
Packit |
577717 |
if (is_dirty != NULL) {
|
|
Packit |
577717 |
if (ESI->master->from_esi != ESI) {
|
|
Packit |
577717 |
dirty_ctx = 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*is_dirty = dirty_ctx;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
ESI->master->from_esi = ESI;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return( ctx );
|
|
Packit |
577717 |
}
|