|
Packit Service |
a1973e |
/*******************************************************************************
|
|
Packit Service |
a1973e |
* >>>>>> "Development of a PAPI Backend for the Sun Niagara 2 Processor" <<<<<<
|
|
Packit Service |
a1973e |
* -----------------------------------------------------------------------------
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* Fabian Gorsler <fabian.gorsler@smail.inf.h-bonn-rhein-sieg.de>
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* Hochschule Bonn-Rhein-Sieg, Sankt Augustin, Germany
|
|
Packit Service |
a1973e |
* University of Applied Sciences
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* -----------------------------------------------------------------------------
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* File: solaris-niagara2.c
|
|
Packit Service |
a1973e |
* Author: fg215045
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* Description: This source file is the implementation of a PAPI
|
|
Packit Service |
a1973e |
* component for the Sun Niagara 2 processor (aka UltraSPARC T2)
|
|
Packit Service |
a1973e |
* running on Solaris 10 with libcpc 2.
|
|
Packit Service |
a1973e |
* The machine for implementing this component was courtesy of RWTH
|
|
Packit Service |
a1973e |
* Aachen University, Germany. Thanks to the HPC-Team at RWTH!
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* Conventions used:
|
|
Packit Service |
a1973e |
* - __cpc_*: Functions, variables, etc. related to libcpc handling
|
|
Packit Service |
a1973e |
* - __sol_*: Functions, variables, etc. related to Solaris handling
|
|
Packit Service |
a1973e |
* - __int_*: Functions, variables, etc. related to extensions of libcpc
|
|
Packit Service |
a1973e |
* - _niagara*: Functions, variables, etc. needed by PAPI hardware dependent
|
|
Packit Service |
a1973e |
* layer, i.e. the component itself
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* ***** Feel free to convert this header to the PAPI default *****
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* -----------------------------------------------------------------------------
|
|
Packit Service |
a1973e |
* Created on April 23, 2009, 7:31 PM
|
|
Packit Service |
a1973e |
******************************************************************************/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include "papi.h"
|
|
Packit Service |
a1973e |
#include "papi_internal.h"
|
|
Packit Service |
a1973e |
#include "papi_vector.h"
|
|
Packit Service |
a1973e |
#include "solaris-niagara2.h"
|
|
Packit Service |
a1973e |
#include "papi_memory.h"
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include <libcpc.h>
|
|
Packit Service |
a1973e |
#include <procfs.h>
|
|
Packit Service |
a1973e |
#include <sys/types.h>
|
|
Packit Service |
a1973e |
#include <sys/stat.h>
|
|
Packit Service |
a1973e |
#include <fcntl.h>
|
|
Packit Service |
a1973e |
#include <unistd.h>
|
|
Packit Service |
a1973e |
#include <stdio.h>
|
|
Packit Service |
a1973e |
#include <stdlib.h>
|
|
Packit Service |
a1973e |
#include <strings.h>
|
|
Packit Service |
a1973e |
#include <sys/lwp.h>
|
|
Packit Service |
a1973e |
#include <limits.h>
|
|
Packit Service |
a1973e |
#include <sys/processor.h>
|
|
Packit Service |
a1973e |
#include <sys/types.h>
|
|
Packit Service |
a1973e |
#include <sys/time.h>
|
|
Packit Service |
a1973e |
#include <stdarg.h>
|
|
Packit Service |
a1973e |
#include <libgen.h>
|
|
Packit Service |
a1973e |
#include <ucontext.h>
|
|
Packit Service |
a1973e |
#include <sys/regset.h>
|
|
Packit Service |
a1973e |
#include <sys/utsname.h>
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include "solaris-common.h"
|
|
Packit Service |
a1973e |
#include "solaris-memory.h"
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define hwd_control_state_t _niagara2_control_state_t
|
|
Packit Service |
a1973e |
#define hwd_context_t _niagara2_context_t
|
|
Packit Service |
a1973e |
#define hwd_register_t _niagara2_register_t
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
extern caddr_t _start, _end, _etext, _edata;
|
|
Packit Service |
a1973e |
extern papi_vector_t _niagara2_vector;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Synthetic events */
|
|
Packit Service |
a1973e |
int __int_setup_synthetic_event( int, hwd_control_state_t *, void * );
|
|
Packit Service |
a1973e |
uint64_t __int_get_synthetic_event( int, hwd_control_state_t *, void * );
|
|
Packit Service |
a1973e |
void __int_walk_synthetic_events_action_count( void );
|
|
Packit Service |
a1973e |
void __int_walk_synthetic_events_action_store( void );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Simple error handlers for convenience */
|
|
Packit Service |
a1973e |
#define __CHECK_ERR_DFLT(retval) \
|
|
Packit Service |
a1973e |
if(retval != 0){ SUBDBG("RETVAL: %d\n", retval); return PAPI_ECMP;}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define __CHECK_ERR_NULL(retval) \
|
|
Packit Service |
a1973e |
if(retval == NULL){ SUBDBG("RETVAL: NULL\n"); return PAPI_ECMP;}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define __CHECK_ERR_PAPI(retval) \
|
|
Packit Service |
a1973e |
if(retval != PAPI_OK){ SUBDBG("RETVAL: %d\n", retval); return PAPI_ECMP;}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define __CHECK_ERR_INVA(retval) \
|
|
Packit Service |
a1973e |
if(retval != 0){ SUBDBG("RETVAL: %d\n", retval); return PAPI_EINVAL;}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define __CHECK_ERR_NEGV(retval) \
|
|
Packit Service |
a1973e |
if(retval < 0){ SUBDBG("RETVAL: %d\n", retval); return PAPI_ECMP;}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// PAPI defined variables
|
|
Packit Service |
a1973e |
extern papi_mdi_t _papi_hwi_system_info;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// The instance of libcpc
|
|
Packit Service |
a1973e |
static cpc_t *cpc = NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
typedef struct __t2_store
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
// Number of counters for a processing unit
|
|
Packit Service |
a1973e |
int npic;
|
|
Packit Service |
a1973e |
int *pic_ntv_count;
|
|
Packit Service |
a1973e |
int syn_evt_count;
|
|
Packit Service |
a1973e |
} __t2_store_t;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static __t2_store_t __t2_store;
|
|
Packit Service |
a1973e |
static char **__t2_ntv_events;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// Variables copied from the old component
|
|
Packit Service |
a1973e |
static int pid;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// Data types for utility functions
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
typedef struct __sol_processor_information
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int total;
|
|
Packit Service |
a1973e |
int clock;
|
|
Packit Service |
a1973e |
} __sol_processor_information_t;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
typedef struct __t2_pst_table
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int papi_pst;
|
|
Packit Service |
a1973e |
char *ntv_event[MAX_COUNTERS];
|
|
Packit Service |
a1973e |
int ntv_ctrs;
|
|
Packit Service |
a1973e |
int ntv_opcode;
|
|
Packit Service |
a1973e |
} __t2_pst_table_t;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define SYNTHETIC_EVENTS_SUPPORTED 1
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* This table structure holds all preset events */
|
|
Packit Service |
a1973e |
static __t2_pst_table_t __t2_table[] = {
|
|
Packit Service |
a1973e |
/* Presets defined by generic_events(3CPC) */
|
|
Packit Service |
a1973e |
{PAPI_L1_DCM,
|
|
Packit Service |
a1973e |
{"DC_miss", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_L1_ICM,
|
|
Packit Service |
a1973e |
{"IC_miss", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_L2_ICM,
|
|
Packit Service |
a1973e |
{"L2_imiss", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_TLB_DM,
|
|
Packit Service |
a1973e |
{"DTLB_miss", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_TLB_IM,
|
|
Packit Service |
a1973e |
{"ITLB_miss", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_TLB_TL,
|
|
Packit Service |
a1973e |
{"TLB_miss", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_L2_LDM,
|
|
Packit Service |
a1973e |
{"L2_dmiss_ld", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_BR_TKN,
|
|
Packit Service |
a1973e |
{"Br_taken", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_TOT_INS,
|
|
Packit Service |
a1973e |
{"Instr_cnt", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_LD_INS,
|
|
Packit Service |
a1973e |
{"Instr_ld", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_SR_INS,
|
|
Packit Service |
a1973e |
{"Instr_st", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_BR_INS,
|
|
Packit Service |
a1973e |
{"Br_completed", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
/* Presets additionally found, should be checked twice */
|
|
Packit Service |
a1973e |
{PAPI_BR_MSP,
|
|
Packit Service |
a1973e |
{"Br_taken", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_FP_INS,
|
|
Packit Service |
a1973e |
{"Instr_FGU_arithmetic", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_RES_STL,
|
|
Packit Service |
a1973e |
{"Idle_strands", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_SYC_INS,
|
|
Packit Service |
a1973e |
{"Atomics", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_L2_ICR,
|
|
Packit Service |
a1973e |
{"CPU_ifetch_to_PCX", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_L1_TCR,
|
|
Packit Service |
a1973e |
{"CPU_ld_to_PCX", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
{PAPI_L2_TCW,
|
|
Packit Service |
a1973e |
{"CPU_st_to_PCX", NULL}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
/* Derived presets found, should be checked twice */
|
|
Packit Service |
a1973e |
{PAPI_L1_TCM,
|
|
Packit Service |
a1973e |
{"IC_miss", "DC_miss"}, 2, DERIVED_ADD},
|
|
Packit Service |
a1973e |
{PAPI_BR_CN,
|
|
Packit Service |
a1973e |
{"Br_completed", "Br_taken"}, 2, DERIVED_ADD},
|
|
Packit Service |
a1973e |
{PAPI_BR_PRC,
|
|
Packit Service |
a1973e |
{"Br_completed", "Br_taken"}, 2, DERIVED_SUB},
|
|
Packit Service |
a1973e |
{PAPI_LST_INS,
|
|
Packit Service |
a1973e |
{"Instr_st", "Instr_ld"}, 2, DERIVED_ADD},
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
/* This preset does exist in order to support multiplexing */
|
|
Packit Service |
a1973e |
{PAPI_TOT_CYC,
|
|
Packit Service |
a1973e |
{"_syn_cycles_elapsed", "DC_miss"}, 1, NOT_DERIVED},
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
{0,
|
|
Packit Service |
a1973e |
{NULL, NULL}, 0, 0},
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
hwi_search_t *preset_table;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
enum
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
SYNTHETIC_CYCLES_ELAPSED = 1,
|
|
Packit Service |
a1973e |
SYNTHETIC_RETURN_ONE,
|
|
Packit Service |
a1973e |
SYNTHETIC_RETURN_TWO,
|
|
Packit Service |
a1973e |
} __int_synthetic_enum;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
typedef struct __int_synthetic_table
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int code;
|
|
Packit Service |
a1973e |
char *name;
|
|
Packit Service |
a1973e |
} __int_syn_table_t;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
static __int_syn_table_t __int_syn_table[] = {
|
|
Packit Service |
a1973e |
{SYNTHETIC_CYCLES_ELAPSED, "_syn_cycles_elapsed"},
|
|
Packit Service |
a1973e |
{SYNTHETIC_RETURN_ONE, "_syn_return_one"},
|
|
Packit Service |
a1973e |
{SYNTHETIC_RETURN_TWO, "_syn_return_two"},
|
|
Packit Service |
a1973e |
{-1, NULL},
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
a1973e |
/// PAPI HWD LAYER RELATED FUNCTIONS ///////////////////////////////////////////
|
|
Packit Service |
a1973e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* DESCRIPTION:
|
|
Packit Service |
a1973e |
* -----------------------------------------------------------------------------
|
|
Packit Service |
a1973e |
* Functions in this section are related to the PAPI hardware dependend layer,
|
|
Packit Service |
a1973e |
* also known as "HWD". In this case the HWD layer is the interface from PAPI
|
|
Packit Service |
a1973e |
* to libcpc 2/Solaris 10.
|
|
Packit Service |
a1973e |
******************************************************************************/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_set_domain( hwd_control_state_t * ctrl, int domain )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Clean and set the new flag for each counter */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < MAX_COUNTERS; i++ ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Setting flags for PIC#%d, old value: %p\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->flags[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->flags[i] &= ~( CPC_COUNTING_DOMAINS );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ cleaned value: %p\n",
|
|
Packit Service |
a1973e |
__func__, ctrl->flags[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->flags[i] |= __cpc_domain_translator( domain );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ new value: %p\n",
|
|
Packit Service |
a1973e |
__func__, ctrl->flags[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Recreate the set */
|
|
Packit Service |
a1973e |
__CHECK_ERR_PAPI( __cpc_recreate_set( ctrl ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Option #%d requested\n", __func__, code );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Only these options are handled which are handled in PAPI_set_opt, as many
|
|
Packit Service |
a1973e |
of the left out options are not settable, like PAPI_MAX_CPUS. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
switch ( code ) {
|
|
Packit Service |
a1973e |
case PAPI_DEFDOM:
|
|
Packit Service |
a1973e |
/* From papi.h: Domain for all new eventsets. Takes non-NULL option
|
|
Packit Service |
a1973e |
pointer. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_niagara2_vector.cmp_info.default_domain = option->domain.domain;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
case PAPI_DOMAIN:
|
|
Packit Service |
a1973e |
/* From papi.h: Domain for an eventset */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return _niagara2_set_domain( ctx, option->domain.domain );
|
|
Packit Service |
a1973e |
case PAPI_DEFGRN:
|
|
Packit Service |
a1973e |
/* From papi.h: Granularity for all new eventsets */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_niagara2_vector.cmp_info.default_granularity =
|
|
Packit Service |
a1973e |
option->granularity.granularity;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
case PAPI_GRANUL:
|
|
Packit Service |
a1973e |
/* From papi.h: Granularity for an eventset */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Only supported granularity is PAPI_GRN_THREAD */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
case PAPI_DEF_MPX_NS:
|
|
Packit Service |
a1973e |
/* From papi.h: Multiplexing/overflowing interval in ns, same as
|
|
Packit Service |
a1973e |
PAPI_DEF_ITIMER_NS */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* From the old component */
|
|
Packit Service |
a1973e |
option->itimer.ns = __sol_get_itimer_ns( option->itimer.ns );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PAPI_DEF_MPX_NS, option->itimer.ns=%d\n",
|
|
Packit Service |
a1973e |
__func__, option->itimer.ns );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
case PAPI_DEF_ITIMER: // IN THE OLD COMPONENT // USED
|
|
Packit Service |
a1973e |
/* From papi.h: Option to set the type of itimer used in both software
|
|
Packit Service |
a1973e |
multiplexing, overflowing and profiling */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* These tests are taken from the old component. For Solaris 10 the
|
|
Packit Service |
a1973e |
same rules apply as documented in getitimer(2). */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
|
|
Packit Service |
a1973e |
( option->itimer.itimer_sig != SIGALRM ) ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PAPI_DEF_ITIMER, ITIMER_REAL needs SIGALRM\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_EINVAL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
|
|
Packit Service |
a1973e |
( option->itimer.itimer_sig != SIGVTALRM ) ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PAPI_DEF_ITIMER, ITIMER_VIRTUAL needs SIGVTALRM\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_EINVAL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
|
|
Packit Service |
a1973e |
( option->itimer.itimer_sig != SIGPROF ) ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PAPI_DEF_ITIMER, ITIMER_PROF needs SIGPROF\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_EINVAL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* As in the old component defined, timer values below 0 are NOT
|
|
Packit Service |
a1973e |
filtered out, but timer values greater than 0 are rounded, either to
|
|
Packit Service |
a1973e |
a value which is at least itimer_res_ns or padded to a multiple of
|
|
Packit Service |
a1973e |
itimer_res_ns. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( option->itimer.ns > 0 ) {
|
|
Packit Service |
a1973e |
option->itimer.ns = __sol_get_itimer_ns( option->itimer.ns );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PAPI_DEF_ITIMER, option->itimer.ns=%d\n",
|
|
Packit Service |
a1973e |
__func__, option->itimer.ns );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
case PAPI_DEF_ITIMER_NS: // IN THE OLD COMPONENT // USED
|
|
Packit Service |
a1973e |
/* From papi.h: Multiplexing/overflowing interval in ns, same as
|
|
Packit Service |
a1973e |
PAPI_DEF_MPX_NS */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* From the old component */
|
|
Packit Service |
a1973e |
option->itimer.ns = __sol_get_itimer_ns( option->itimer.ns );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PAPI_DEF_ITIMER_NS, option->itimer.ns=%d\n",
|
|
Packit Service |
a1973e |
__func__, option->itimer.ns );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Option not found\n", __func__ );
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* This place should never be reached */
|
|
Packit Service |
a1973e |
return PAPI_EINVAL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
_niagara2_dispatch_timer( int signal, siginfo_t * si, void *info )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
EventSetInfo_t *ESI = NULL;
|
|
Packit Service |
a1973e |
ThreadInfo_t *thread = NULL;
|
|
Packit Service |
a1973e |
int overflow_vector = 0;
|
|
Packit Service |
a1973e |
hwd_control_state_t *ctrl = NULL;
|
|
Packit Service |
a1973e |
long_long results[MAX_COUNTERS];
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
// Hint from perf_events.c
|
|
Packit Service |
a1973e |
int cidx = _niagara2_vector.cmp_info.CmpIdx;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Overflow handler called by signal #%d\n", __func__,
|
|
Packit Service |
a1973e |
signal );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* From the old component */
|
|
Packit Service |
a1973e |
thread = _papi_hwi_lookup_thread( 0 );
|
|
Packit Service |
a1973e |
ESI = ( EventSetInfo_t * ) thread->running_eventset[cidx];
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* From the old component, modified */
|
|
Packit Service |
a1973e |
//
|
|
Packit Service |
a1973e |
if ( ESI == NULL || ESI->master != thread || ESI->ctl_state == NULL ||
|
|
Packit Service |
a1973e |
( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Problems with ESI, not necessarily serious\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ESI == NULL ) {
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ ESI is NULL\n", __func__ );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ESI->master != thread ) {
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ Thread mismatch, ESI->master=%#x thread=%#x\n",
|
|
Packit Service |
a1973e |
__func__, ESI->master, thread );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ESI->ctl_state == NULL ) {
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ Counter state invalid\n", __func__ );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
|
|
Packit Service |
a1973e |
SUBDBG
|
|
Packit Service |
a1973e |
( " -> %s: +++ Overflow flag missing, ESI->overflow.flags=%#x\n",
|
|
Packit Service |
a1973e |
__func__, ESI->overflow.flags );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
printf( " -> %s: Preconditions valid, trying to read counters\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl = ESI->ctl_state;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( _niagara2_read
|
|
Packit Service |
a1973e |
( ctrl, ctrl, ( long_long ** ) & results, NOT_A_PAPI_HWD_READ )
|
|
Packit Service |
a1973e |
!= PAPI_OK ) {
|
|
Packit Service |
a1973e |
/* Failure */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
printf( "%s: Failed to read counters\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
/* Success */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Counters read\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Iterate over all available counters in order to detect which counter
|
|
Packit Service |
a1973e |
overflowed (counter value should be 0 if an hw overflow happened),
|
|
Packit Service |
a1973e |
store the position in the overflow_vector, calculte the offset and
|
|
Packit Service |
a1973e |
shift (value range signed long long vs. unsigned long long). */
|
|
Packit Service |
a1973e |
for ( i = 0; i < ctrl->count; i++ ) {
|
|
Packit Service |
a1973e |
if ( results[i] >= 0 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Overflow detected at PIC #%d\n", __func__, i );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Set the bit in the overflow_vector */
|
|
Packit Service |
a1973e |
overflow_vector = overflow_vector | ( 1 << i );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* hoose which method to use depending on the overflow signal. */
|
|
Packit Service |
a1973e |
if ( signal == SIGEMT ) {
|
|
Packit Service |
a1973e |
/* Store the counter value, but only if we have a real *
|
|
Packit Service |
a1973e |
hardware overflow counting with libcpc/SIGEMT. */
|
|
Packit Service |
a1973e |
ctrl->preset[i] = UINT64_MAX - ctrl->threshold[i];
|
|
Packit Service |
a1973e |
ctrl->hangover[i] += ctrl->threshold[i];
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
/* Push the value back, this time PAPI does the work. This is
|
|
Packit Service |
a1973e |
software overflow handling. */
|
|
Packit Service |
a1973e |
cpc_request_preset( cpc, ctrl->idx[i], ctrl->result[i] );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: No overflow detected at PIC #%d, value=%ld\n",
|
|
Packit Service |
a1973e |
__func__, i, results[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Save the results read from the counter as we can not store the
|
|
Packit Service |
a1973e |
temporary value in hardware or libcpc. */
|
|
Packit Service |
a1973e |
if ( signal == SIGEMT ) {
|
|
Packit Service |
a1973e |
ctrl->preset[i] += results[i];
|
|
Packit Service |
a1973e |
ctrl->hangover[i] = results[i];
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Restarting set to push values back\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Push all values back to the counter as preset */
|
|
Packit Service |
a1973e |
cpc_set_restart( cpc, ctrl->set );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Passing overflow to PAPI with overflow_vector=%p\n",
|
|
Packit Service |
a1973e |
__func__, overflow_vector );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
/* hw is used as pointer in the dispatching routine of PAPI and might be
|
|
Packit Service |
a1973e |
changed. For safety it is not a pseudo pointer to NULL. */
|
|
Packit Service |
a1973e |
int hw;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( signal == SIGEMT ) {
|
|
Packit Service |
a1973e |
/* This is a hardware overflow */
|
|
Packit Service |
a1973e |
hw = 1;
|
|
Packit Service |
a1973e |
_papi_hwi_dispatch_overflow_signal( ctrl, ( caddr_t )
|
|
Packit Service |
a1973e |
_niagara2_get_overflow_address
|
|
Packit Service |
a1973e |
( info ), &hw, overflow_vector,
|
|
Packit Service |
a1973e |
1, &thread, ESI->CmpIdx );
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
/* This is a software overflow */
|
|
Packit Service |
a1973e |
hw = 0;
|
|
Packit Service |
a1973e |
_papi_hwi_dispatch_overflow_signal( ctrl, ( caddr_t )
|
|
Packit Service |
a1973e |
_niagara2_get_overflow_address
|
|
Packit Service |
a1973e |
( info ), &hw, overflow_vector,
|
|
Packit Service |
a1973e |
1, &thread, ESI->CmpIdx );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline void *
|
|
Packit Service |
a1973e |
_niagara2_get_overflow_address( void *context )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
ucontext_t *ctx = ( ucontext_t * ) context;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING/LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return ( void * ) ctx->uc_mcontext.gregs[REG_PC];
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Although the created set in this function will be destroyed by
|
|
Packit Service |
a1973e |
* _papi_update_control_state later, at least the functionality of the
|
|
Packit Service |
a1973e |
* underlying CPU driver will be tested completly.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_init_control_state( hwd_control_state_t * ctrl )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// cpc_seterrhndlr(cpc, myapp_errfn);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Clear the buffer */
|
|
Packit Service |
a1973e |
if ( ctrl->counter_buffer != NULL ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Cleaning buffer\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
cpc_buf_destroy( cpc, ctrl->counter_buffer );
|
|
Packit Service |
a1973e |
ctrl->counter_buffer = NULL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Clear the set */
|
|
Packit Service |
a1973e |
if ( ctrl->set != NULL ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Cleaning set\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
cpc_set_destroy( cpc, ctrl->set );
|
|
Packit Service |
a1973e |
ctrl->set = NULL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Indicate this idx has no request associated, this counter is unused. */
|
|
Packit Service |
a1973e |
for ( i = 0; i < MAX_COUNTERS; i++ ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Cleaning counter state #%d\n", __func__, i );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Indicate missing setup values */
|
|
Packit Service |
a1973e |
ctrl->idx[i] = EVENT_NOT_SET;
|
|
Packit Service |
a1973e |
ctrl->code[i].event_code = EVENT_NOT_SET;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* No flags yet set, this is for overflow and binding */
|
|
Packit Service |
a1973e |
ctrl->flags[i] = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Preset value for counting results */
|
|
Packit Service |
a1973e |
ctrl->preset[i] = DEFAULT_CNTR_PRESET;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Needed for overflow handling, will be set later */
|
|
Packit Service |
a1973e |
ctrl->threshold[i] = 0;
|
|
Packit Service |
a1973e |
ctrl->hangover[i] = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
ctrl->syn_hangover[i] = 0;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* No counters active in this set */
|
|
Packit Service |
a1973e |
ctrl->count = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
ctrl->syn_count = 0;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_init_component( int cidx )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Create an instance of libcpc */
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Trying to initalize libcpc\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
cpc = cpc_open( CPC_VER_CURRENT );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NULL( cpc );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Registering libcpc error handler\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
cpc_seterrhndlr( cpc, __cpc_error_handler );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Detecting supported PICs", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
__t2_store.npic = cpc_npic( cpc );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Storing component index, cidx=%d\n", __func__, cidx );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
_niagara2_vector.cmp_info.CmpIdx = cidx;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Gathering system information for PAPI\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
/* Store system info in central data structure */
|
|
Packit Service |
a1973e |
__CHECK_ERR_PAPI( _niagara2_get_system_info( &_papi_hwi_system_info ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Initializing locks\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
/* Set up the lock after initialization */
|
|
Packit Service |
a1973e |
_niagara2_lock_init( );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// Copied from the old component, _papi_init_component()
|
|
Packit Service |
a1973e |
SUBDBG( "Found %d %s %s CPUs at %d Mhz.\n",
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.hw_info.totalcpus,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.hw_info.vendor_string,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.hw_info.model_string,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.hw_info.cpu_max_mhz );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Build native event table */
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Building native event table\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
__CHECK_ERR_PAPI( __cpc_build_ntv_table( ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Build preset event table */
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Building PAPI preset table\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
__CHECK_ERR_PAPI( __cpc_build_pst_table( ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Register presets and finish event related setup */
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Registering presets in PAPI\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
__CHECK_ERR_PAPI( _papi_hwi_setup_all_presets( preset_table, NULL ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Everything is ok */
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
_niagara2_lock_init( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Copied from old component, lock_init() */
|
|
Packit Service |
a1973e |
memset( lock, 0x0, sizeof ( rwlock_t ) * PAPI_MAX_LOCK );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int event_code = EventCode & PAPI_NATIVE_AND_MASK;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( event_code >= 0 &&
|
|
Packit Service |
a1973e |
event_code <= _niagara2_vector.cmp_info.num_native_events ) {
|
|
Packit Service |
a1973e |
return PAPI_ENOEVNT;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
bits->event_code = event_code;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_ntv_code_to_descr( unsigned int EventCode, char *ntv_descr, int len )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING/LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* libcpc offers no descriptions, just a link to the reference manual */
|
|
Packit Service |
a1973e |
return _niagara2_ntv_code_to_name( EventCode, ntv_descr, len );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int event_code = EventCode & PAPI_NATIVE_AND_MASK;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( event_code >= 0 &&
|
|
Packit Service |
a1973e |
event_code <= _niagara2_vector.cmp_info.num_native_events ) {
|
|
Packit Service |
a1973e |
strlcpy( ntv_name, __t2_ntv_events[event_code], len );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( strlen( __t2_ntv_events[event_code] ) > len - 1 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* It's not a real error, but at least a hint */
|
|
Packit Service |
a1973e |
return PAPI_EBUF;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_ENOEVNT;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_ntv_enum_events( unsigned int *EventCode, int modifier )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
/* This code is very similar to the code from the old component. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int event_code = *EventCode & PAPI_NATIVE_AND_MASK;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( modifier == PAPI_ENUM_FIRST ) {
|
|
Packit Service |
a1973e |
*EventCode = PAPI_NATIVE_MASK + 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* The table needs to be shifted by one position (starting index 1), as PAPI
|
|
Packit Service |
a1973e |
expects native event codes not to be 0 (papi_internal.c:744). */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( event_code >= 1 &&
|
|
Packit Service |
a1973e |
event_code <= _niagara2_vector.cmp_info.num_native_events - 1 ) {
|
|
Packit Service |
a1973e |
*EventCode = *EventCode + 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// If nothing found report an error
|
|
Packit Service |
a1973e |
return PAPI_ENOEVNT;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_read( hwd_context_t * ctx, hwd_control_state_t * ctrl,
|
|
Packit Service |
a1973e |
long_long ** events, int flags )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: called with flags=%p\n", __func__, flags );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Take a new sample from the PIC to the buffer */
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_set_sample( cpc, ctrl->set, ctrl->counter_buffer ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Copy the buffer values from all active counters */
|
|
Packit Service |
a1973e |
for ( i = 0; i < ctrl->count; i++ ) {
|
|
Packit Service |
a1973e |
/* Retrieve the counting results of libcpc */
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_buf_get( cpc, ctrl->counter_buffer, ctrl->idx[i],
|
|
Packit Service |
a1973e |
&ctrl->result[i] ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* As libcpc uses uint64_t and PAPI uses int64_t, we need to normalize
|
|
Packit Service |
a1973e |
the result back to a value that PAPI can handle, otherwise the result
|
|
Packit Service |
a1973e |
is not usable as its in the negative range of int64_t and the result
|
|
Packit Service |
a1973e |
becomes useless for PAPI. */
|
|
Packit Service |
a1973e |
if ( ctrl->threshold[i] > 0 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Normalizing result on PIC#%d to %lld\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->result[i] );
|
|
Packit Service |
a1973e |
#endif /* DEBUG */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* This shifts the retrieved value back to the PAPI value range */
|
|
Packit Service |
a1973e |
ctrl->result[i] = ctrl->result[i] -
|
|
Packit Service |
a1973e |
( UINT64_MAX - ctrl->threshold[i] ) - 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Needed if called internally if a PIC didn't really overflow, but
|
|
Packit Service |
a1973e |
was programmed in the same set. */
|
|
Packit Service |
a1973e |
if ( flags != NOT_A_PAPI_HWD_READ ) {
|
|
Packit Service |
a1973e |
ctrl->result[i] = ctrl->hangover[i];
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Overflow scaling on PIC#%d:\n", __func__, i );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ ctrl->result[%d]=%llu\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->result[i] );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ ctrl->threshold[%d]=%lld\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->threshold[i] );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ ctrl->hangover[%d]=%lld\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->hangover[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: +++ ctrl->result[%d]=%llu\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->result[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
const int syn_barrier = _niagara2_vector.cmp_info.num_native_events
|
|
Packit Service |
a1973e |
- __t2_store.syn_evt_count;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < ctrl->count; i++ ) {
|
|
Packit Service |
a1973e |
if ( ctrl->code[i].event_code >= syn_barrier ) {
|
|
Packit Service |
a1973e |
ctrl->result[i] =
|
|
Packit Service |
a1973e |
__int_get_synthetic_event( ctrl->code[i].event_code
|
|
Packit Service |
a1973e |
- syn_barrier, ctrl, &i );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Pass the address of the results back to the calling function */
|
|
Packit Service |
a1973e |
*events = ( long_long * ) & ctrl->result[0];
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING: %s\n", "_papi_read" );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_reset( hwd_context_t * ctx, hwd_control_state_t * ctrl )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* This does a restart of the whole set, setting the internal counters back
|
|
Packit Service |
a1973e |
to the value passed as preset of the last call of cpc_set_add_request or
|
|
Packit Service |
a1973e |
cpc_request_preset. */
|
|
Packit Service |
a1973e |
cpc_set_restart( cpc, ctrl->set );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
const int syn_barrier = _niagara2_vector.cmp_info.num_native_events
|
|
Packit Service |
a1973e |
- __t2_store.syn_evt_count;
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ctrl->syn_count > 0 ) {
|
|
Packit Service |
a1973e |
for ( i = 0; i < MAX_COUNTERS; i++ ) {
|
|
Packit Service |
a1973e |
if ( ctrl->code[i].event_code >= syn_barrier ) {
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->syn_hangover[i] +=
|
|
Packit Service |
a1973e |
__int_get_synthetic_event( ctrl->code[i].event_code -
|
|
Packit Service |
a1973e |
syn_barrier, ctrl, &i );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
/* Seems not to be used. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING/LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_ENOSUPP;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
hwd_control_state_t *ctrl = ESI->ctl_state;
|
|
Packit Service |
a1973e |
struct sigaction sigact;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Overflow handling for %#x on PIC#%d requested\n",
|
|
Packit Service |
a1973e |
__func__, ctrl, EventIndex );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: ESI->overflow.flags=%#x\n\n", __func__, ctrl,
|
|
Packit Service |
a1973e |
ESI->overflow.flags );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* If threshold > 0, then activate hardware overflow handling, otherwise
|
|
Packit Service |
a1973e |
disable it. */
|
|
Packit Service |
a1973e |
if ( threshold > 0 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Activating overflow handling\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->preset[EventIndex] = UINT64_MAX - threshold;
|
|
Packit Service |
a1973e |
ctrl->threshold[EventIndex] = threshold;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* If SIGEMT is not yet enabled, enable it. In libcpc this means to re-
|
|
Packit Service |
a1973e |
recreate the used set. In order not to break PAPI operations only the
|
|
Packit Service |
a1973e |
event referred by EventIndex will be updated to use SIGEMT. */
|
|
Packit Service |
a1973e |
if ( !( ctrl->flags[EventIndex] & CPC_OVF_NOTIFY_EMT ) ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Need to activate SIGEMT on PIC %d\n",
|
|
Packit Service |
a1973e |
__func__, EventIndex );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Enable overflow handling */
|
|
Packit Service |
a1973e |
if ( __cpc_enable_sigemt( ctrl, EventIndex ) != PAPI_OK ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Activating SIGEMT failed for PIC %d\n",
|
|
Packit Service |
a1973e |
__func__, EventIndex );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: SIGEMT activated, will install signal handler\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// FIXME: Not really sure that this construct is working
|
|
Packit Service |
a1973e |
return _papi_hwi_start_signal( SIGEMT, 1, 0 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Disabling overflow handling\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Resetting values which were used for overflow handling */
|
|
Packit Service |
a1973e |
ctrl->preset[EventIndex] = DEFAULT_CNTR_PRESET;
|
|
Packit Service |
a1973e |
ctrl->flags[EventIndex] &= ~( CPC_OVF_NOTIFY_EMT );
|
|
Packit Service |
a1973e |
ctrl->threshold[EventIndex] = 0;
|
|
Packit Service |
a1973e |
ctrl->hangover[EventIndex] = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s:ctrl->preset[%d]=%d, ctrl->flags[%d]=%p\n",
|
|
Packit Service |
a1973e |
__func__, EventIndex, ctrl->preset[EventIndex],
|
|
Packit Service |
a1973e |
EventIndex, ctrl->flags[EventIndex] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Recreate the undelying set and disable the signal handler */
|
|
Packit Service |
a1973e |
__CHECK_ERR_PAPI( __cpc_recreate_set( ctrl ) );
|
|
Packit Service |
a1973e |
__CHECK_ERR_PAPI( _papi_hwi_stop_signal( SIGEMT ) );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_shutdown( hwd_context_t * ctx )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
cpc_buf_destroy( cpc, ctx->counter_buffer );
|
|
Packit Service |
a1973e |
cpc_set_destroy( cpc, ctx->set );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_shutdown_global( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Free allocated memory */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// papi_calloc in __cpc_build_ntv_table
|
|
Packit Service |
a1973e |
papi_free( __t2_store.pic_ntv_count );
|
|
Packit Service |
a1973e |
// papi_calloc in __cpc_build_ntv_table
|
|
Packit Service |
a1973e |
papi_free( __t2_ntv_events );
|
|
Packit Service |
a1973e |
// papi_calloc in __cpc_build_pst_table
|
|
Packit Service |
a1973e |
papi_free( preset_table );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Shutdown libcpc */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// cpc_open in _papi_init_component
|
|
Packit Service |
a1973e |
cpc_close( cpc );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_start( hwd_context_t * ctx, hwd_control_state_t * ctrl )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int retval;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Starting EventSet %p\n", __func__, ctrl );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Event count: ctrl->count=%d, ctrl->syn_count=%d\n",
|
|
Packit Service |
a1973e |
__func__, ctrl->count, ctrl->syn_count );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ctrl->count > 0 && ctrl->count == ctrl->syn_count ) {
|
|
Packit Service |
a1973e |
ctrl->idx[0] = cpc_set_add_request( cpc, ctrl->set, "Instr_cnt",
|
|
Packit Service |
a1973e |
ctrl->preset[0], ctrl->flags[0],
|
|
Packit Service |
a1973e |
0, NULL );
|
|
Packit Service |
a1973e |
ctrl->counter_buffer = cpc_buf_create( cpc, ctrl->set );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < MAX_COUNTERS; i++ ) {
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Flags for PIC#%d: ctrl->flags[%d]=%d\n", __func__,
|
|
Packit Service |
a1973e |
i, i, ctrl->flags[i] );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_bind_curlwp( cpc, ctrl->set, CPC_BIND_LWP_INHERIT ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Ensure the set is working properly */
|
|
Packit Service |
a1973e |
retval = cpc_set_sample( cpc, ctrl->set, ctrl->counter_buffer );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( retval != 0 ) {
|
|
Packit Service |
a1973e |
printf( "%s: cpc_set_sample failed, return=%d, errno=%d\n",
|
|
Packit Service |
a1973e |
__func__, retval, errno );
|
|
Packit Service |
a1973e |
return PAPI_ECMP;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_stop( hwd_context_t * ctx, hwd_control_state_t * ctrl )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_unbind( cpc, ctrl->set ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_update_control_state( hwd_control_state_t * ctrl,
|
|
Packit Service |
a1973e |
NativeInfo_t * native, int count,
|
|
Packit Service |
a1973e |
hwd_context_t * ctx )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Delete everything as we can't change an existing set */
|
|
Packit Service |
a1973e |
if ( ctrl->counter_buffer != NULL ) {
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_buf_destroy( cpc, ctrl->counter_buffer ) );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ctrl->set != NULL ) {
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_set_destroy( cpc, ctrl->set ) );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < MAX_COUNTERS; i++ ) {
|
|
Packit Service |
a1973e |
ctrl->idx[i] = EVENT_NOT_SET;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* New setup */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->set = cpc_set_create( cpc );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NULL( ctrl->set );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->count = count;
|
|
Packit Service |
a1973e |
ctrl->syn_count = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < count; i++ ) {
|
|
Packit Service |
a1973e |
/* Store the active event */
|
|
Packit Service |
a1973e |
ctrl->code[i].event_code = native[i].ni_event & PAPI_NATIVE_AND_MASK;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->flags[i] = __cpc_domain_translator( PAPI_DOM_USER );
|
|
Packit Service |
a1973e |
ctrl->preset[i] = DEFAULT_CNTR_PRESET;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG
|
|
Packit Service |
a1973e |
( " -> %s: EventSet@%p/PIC#%d - ntv request >>%s<< (%d), flags=%#x\n",
|
|
Packit Service |
a1973e |
__func__, ctrl, i, __t2_ntv_events[ctrl->code[i].event_code],
|
|
Packit Service |
a1973e |
ctrl->code[i].event_code, ctrl->flags[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Store the counter position (???) */
|
|
Packit Service |
a1973e |
native[i].ni_position = i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int syn_code = ctrl->code[i].event_code -
|
|
Packit Service |
a1973e |
( _niagara2_vector.cmp_info.num_native_events
|
|
Packit Service |
a1973e |
- __t2_store.syn_evt_count ) - 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Check if the event code is bigger than the CPC provided events. */
|
|
Packit Service |
a1973e |
if ( syn_code >= 0 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG
|
|
Packit Service |
a1973e |
( " -> %s: Adding synthetic event %#x (%s) on position %d\n",
|
|
Packit Service |
a1973e |
__func__, native[i].ni_event,
|
|
Packit Service |
a1973e |
__t2_ntv_events[ctrl->code[i].event_code], i );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Call the setup routine */
|
|
Packit Service |
a1973e |
__int_setup_synthetic_event( syn_code, ctrl, NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Clean the hangover count as this event is new */
|
|
Packit Service |
a1973e |
ctrl->syn_hangover[i] = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Register this event as being synthetic, as an event set only
|
|
Packit Service |
a1973e |
based on synthetic events can not be actived through libcpc */
|
|
Packit Service |
a1973e |
ctrl->syn_count++;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Jump to next iteration */
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Adding native event %#x (%s) on position %d\n",
|
|
Packit Service |
a1973e |
__func__, native[i].ni_event,
|
|
Packit Service |
a1973e |
__t2_ntv_events[ctrl->code[i].event_code], i );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Pass the event as request to libcpc */
|
|
Packit Service |
a1973e |
ctrl->idx[i] = cpc_set_add_request( cpc, ctrl->set,
|
|
Packit Service |
a1973e |
__t2_ntv_events[ctrl->code[i].
|
|
Packit Service |
a1973e |
event_code],
|
|
Packit Service |
a1973e |
ctrl->preset[i], ctrl->flags[i], 0,
|
|
Packit Service |
a1973e |
NULL );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NEGV( ctrl->idx[i] );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
if ( i == 0 ) {
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: nothing added\n", __func__ );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->counter_buffer = cpc_buf_create( cpc, ctrl->set );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NULL( ctrl->counter_buffer );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Finished the new setup */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Linking to context (same data type by typedef!) */
|
|
Packit Service |
a1973e |
ctx = ctrl;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_niagara2_update_shlib_info( papi_mdi_t *mdi )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *file = "/proc/self/map";
|
|
Packit Service |
a1973e |
char *resolve_pattern = "/proc/self/path/%s";
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
char lastobject[PRMAPSZ];
|
|
Packit Service |
a1973e |
char link[PAPI_HUGE_STR_LEN];
|
|
Packit Service |
a1973e |
char path[PAPI_HUGE_STR_LEN];
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
prmap_t mapping;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int fd, count = 0, total = 0, position = -1, first = 1;
|
|
Packit Service |
a1973e |
caddr_t t_min, t_max, d_min, d_max;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
PAPI_address_map_t *pam, *cur;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fd = open( file, O_RDONLY );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( fd == -1 ) {
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset( lastobject, 0, PRMAPSZ );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Preprocessing memory maps from procfs\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Search through the list of mappings in order to identify a) how many
|
|
Packit Service |
a1973e |
mappings are available and b) how many unique mappings are available. */
|
|
Packit Service |
a1973e |
while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Found a new memory map entry\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
/* Another entry found, just the total count of entries. */
|
|
Packit Service |
a1973e |
total++;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Is the mapping accessible and not anonymous? */
|
|
Packit Service |
a1973e |
if ( mapping.pr_mflags & ( MA_READ | MA_WRITE | MA_EXEC ) &&
|
|
Packit Service |
a1973e |
!( mapping.pr_mflags & MA_ANON ) ) {
|
|
Packit Service |
a1973e |
/* Test if a new library has been found. If a new library has been
|
|
Packit Service |
a1973e |
found a new entry needs to be counted. */
|
|
Packit Service |
a1973e |
if ( strcmp( lastobject, mapping.pr_mapname ) != 0 ) {
|
|
Packit Service |
a1973e |
strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
|
|
Packit Service |
a1973e |
count++;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Memory mapping entry valid for %s\n", __func__,
|
|
Packit Service |
a1973e |
mapping.pr_mapname );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Preprocessing done, starting to analyze\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Start from the beginning, now fill in the found mappings */
|
|
Packit Service |
a1973e |
if ( lseek( fd, 0, SEEK_SET ) == -1 ) {
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset( lastobject, 0, PRMAPSZ );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Allocate memory */
|
|
Packit Service |
a1973e |
pam =
|
|
Packit Service |
a1973e |
( PAPI_address_map_t * ) papi_calloc( count,
|
|
Packit Service |
a1973e |
sizeof ( PAPI_address_map_t ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( mapping.pr_mflags & MA_ANON ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG
|
|
Packit Service |
a1973e |
( " -> %s: Anonymous mapping (MA_ANON) found for %s, skipping\n",
|
|
Packit Service |
a1973e |
__func__, mapping.pr_mapname );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Check for a new entry */
|
|
Packit Service |
a1973e |
if ( strcmp( mapping.pr_mapname, lastobject ) != 0 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Analyzing mapping for %s\n", __func__,
|
|
Packit Service |
a1973e |
mapping.pr_mapname );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
cur = &( pam[++position] );
|
|
Packit Service |
a1973e |
strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
|
|
Packit Service |
a1973e |
snprintf( link, PAPI_HUGE_STR_LEN, resolve_pattern, lastobject );
|
|
Packit Service |
a1973e |
memset( path, 0, PAPI_HUGE_STR_LEN );
|
|
Packit Service |
a1973e |
readlink( link, path, PAPI_HUGE_STR_LEN );
|
|
Packit Service |
a1973e |
strncpy( cur->name, path, PAPI_HUGE_STR_LEN );
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Resolved name for %s: %s\n", __func__,
|
|
Packit Service |
a1973e |
mapping.pr_mapname, cur->name );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( mapping.pr_mflags & MA_READ ) {
|
|
Packit Service |
a1973e |
/* Data (MA_WRITE) or text (MA_READ) segment? */
|
|
Packit Service |
a1973e |
if ( mapping.pr_mflags & MA_WRITE ) {
|
|
Packit Service |
a1973e |
cur->data_start = ( caddr_t ) mapping.pr_vaddr;
|
|
Packit Service |
a1973e |
cur->data_end =
|
|
Packit Service |
a1973e |
( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( strcmp
|
|
Packit Service |
a1973e |
( cur->name,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.fullname ) == 0 ) {
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.data_start =
|
|
Packit Service |
a1973e |
cur->data_start;
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.data_end =
|
|
Packit Service |
a1973e |
cur->data_end;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( first )
|
|
Packit Service |
a1973e |
d_min = cur->data_start;
|
|
Packit Service |
a1973e |
if ( first )
|
|
Packit Service |
a1973e |
d_max = cur->data_end;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( cur->data_start < d_min ) {
|
|
Packit Service |
a1973e |
d_min = cur->data_start;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( cur->data_end > d_max ) {
|
|
Packit Service |
a1973e |
d_max = cur->data_end;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
} else if ( mapping.pr_mflags & MA_EXEC ) {
|
|
Packit Service |
a1973e |
cur->text_start = ( caddr_t ) mapping.pr_vaddr;
|
|
Packit Service |
a1973e |
cur->text_end =
|
|
Packit Service |
a1973e |
( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( strcmp
|
|
Packit Service |
a1973e |
( cur->name,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.fullname ) == 0 ) {
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.text_start =
|
|
Packit Service |
a1973e |
cur->text_start;
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.text_end =
|
|
Packit Service |
a1973e |
cur->text_end;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( first )
|
|
Packit Service |
a1973e |
t_min = cur->text_start;
|
|
Packit Service |
a1973e |
if ( first )
|
|
Packit Service |
a1973e |
t_max = cur->text_end;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( cur->text_start < t_min ) {
|
|
Packit Service |
a1973e |
t_min = cur->text_start;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( cur->text_end > t_max ) {
|
|
Packit Service |
a1973e |
t_max = cur->text_end;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
first = 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
close( fd );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* During the walk of shared objects the upper and lower bound of the
|
|
Packit Service |
a1973e |
segments could be discovered. The bounds are stored in the PAPI info
|
|
Packit Service |
a1973e |
structure. The information is important for the profiling functions of
|
|
Packit Service |
a1973e |
PAPI. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* This variant would pass the addresses of all text and data segments
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.text_start = t_min;
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.text_end = t_max;
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.data_start = d_min;
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.data_end = d_max;
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Analysis of memory maps done, results:\n", __func__ );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: text_start=%#x, text_end=%#x, text_size=%lld\n", __func__,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.text_start,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.text_end,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.text_end
|
|
Packit Service |
a1973e |
- _papi_hwi_system_info.exe_info.address_info.text_start );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: data_start=%#x, data_end=%#x, data_size=%lld\n", __func__,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.data_start,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.data_end,
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.exe_info.address_info.data_end
|
|
Packit Service |
a1973e |
- _papi_hwi_system_info.exe_info.address_info.data_start );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Store the map read and the total count of shlibs found */
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.shlib_info.map = pam;
|
|
Packit Service |
a1973e |
_papi_hwi_system_info.shlib_info.count = count;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
//////////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
a1973e |
/// UTILITY FUNCTIONS FOR ACCESS TO LIBCPC AND SOLARIS /////////////////////////
|
|
Packit Service |
a1973e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* DESCRIPTION:
|
|
Packit Service |
a1973e |
* -----------------------------------------------------------------------------
|
|
Packit Service |
a1973e |
* The following functions are for accessing libcpc 2 and Solaris related stuff
|
|
Packit Service |
a1973e |
* needed for PAPI.
|
|
Packit Service |
a1973e |
******************************************************************************/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__cpc_build_ntv_table( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i, tmp;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
__t2_store.pic_ntv_count = papi_calloc( __t2_store.npic, sizeof ( int ) );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NULL( __t2_store.pic_ntv_count );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Checking PICs for functionality\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < __t2_store.npic; i++ ) {
|
|
Packit Service |
a1973e |
cpc_walk_events_pic( cpc, i, NULL, __cpc_walk_events_pic_action_count );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Found %d events on PIC#%d\n", __func__,
|
|
Packit Service |
a1973e |
__t2_store.pic_ntv_count[i], i );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tmp = __t2_store.pic_ntv_count[0];
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* There should be at least one counter... */
|
|
Packit Service |
a1973e |
if ( tmp == 0 ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PIC#0 has 0 events\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_ECMP;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Check if all PICs have the same number of counters */
|
|
Packit Service |
a1973e |
for ( i = 0; i < __t2_store.npic; i++ ) {
|
|
Packit Service |
a1973e |
if ( __t2_store.pic_ntv_count[i] != tmp ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: PIC#%d has %d events, should have %d\n",
|
|
Packit Service |
a1973e |
__func__, i, __t2_store.pic_ntv_count[i], tmp );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_ECMP;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Count synthetic events which add functionality to libcpc */
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
__t2_store.syn_evt_count = 0;
|
|
Packit Service |
a1973e |
__int_walk_synthetic_events_action_count( );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Store the count of events available in central data structure */
|
|
Packit Service |
a1973e |
#ifndef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
_niagara2_vector.cmp_info.num_native_events = __t2_store.pic_ntv_count[0];
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
_niagara2_vector.cmp_info.num_native_events =
|
|
Packit Service |
a1973e |
__t2_store.pic_ntv_count[0] + __t2_store.syn_evt_count;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Allocate memory for storing all events found, including the first empty
|
|
Packit Service |
a1973e |
slot */
|
|
Packit Service |
a1973e |
__t2_ntv_events =
|
|
Packit Service |
a1973e |
papi_calloc( _niagara2_vector.cmp_info.num_native_events + 1,
|
|
Packit Service |
a1973e |
sizeof ( char * ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
__t2_ntv_events[0] = "THIS IS A BUG!";
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tmp = 1;
|
|
Packit Service |
a1973e |
cpc_walk_events_pic( cpc, 0, ( void * ) &tmp,
|
|
Packit Service |
a1973e |
__cpc_walk_events_pic_action_store );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
__int_walk_synthetic_events_action_store( );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
for ( i = 1; i < __t2_store.pic_ntv_count[0]; i++ ) {
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Event #%d: %s\n", __func__, i, __t2_ntv_events[i] );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Return event code for event_name */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__cpc_search_ntv_event( char *event_name, int *event_code )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < _niagara2_vector.cmp_info.num_native_events; i++ ) {
|
|
Packit Service |
a1973e |
if ( strcmp( event_name, __t2_ntv_events[i] ) == 0 ) {
|
|
Packit Service |
a1973e |
*event_code = i;
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_ENOEVNT;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__cpc_build_pst_table( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int num_psts, i, j, event_code, pst_events;
|
|
Packit Service |
a1973e |
hwi_search_t tmp;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
num_psts = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while ( __t2_table[num_psts].papi_pst != 0 ) {
|
|
Packit Service |
a1973e |
num_psts++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Found %d presets\n", __func__, num_psts );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
preset_table = papi_calloc( num_psts + 1, sizeof ( hwi_search_t ) );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NULL( preset_table );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pst_events = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < num_psts; i++ ) {
|
|
Packit Service |
a1973e |
memset( &tmp, PAPI_NULL, sizeof ( tmp ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Mark counters as unused. If they are needed, they will be overwritten
|
|
Packit Service |
a1973e |
later. See papi_preset.c:51 for more details. */
|
|
Packit Service |
a1973e |
for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
|
|
Packit Service |
a1973e |
tmp.data.native[j] = PAPI_NULL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tmp.event_code = __t2_table[i].papi_pst;
|
|
Packit Service |
a1973e |
tmp.data.derived = __t2_table[i].ntv_opcode;
|
|
Packit Service |
a1973e |
tmp.data.operation[0] = '\0';
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
switch ( __t2_table[i].ntv_opcode ) {
|
|
Packit Service |
a1973e |
case DERIVED_ADD:
|
|
Packit Service |
a1973e |
tmp.data.operation[0] = '+';
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case DERIVED_SUB:
|
|
Packit Service |
a1973e |
tmp.data.operation[0] = '-';
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( j = 0; j < __t2_table[i].ntv_ctrs; j++ ) {
|
|
Packit Service |
a1973e |
if ( __cpc_search_ntv_event
|
|
Packit Service |
a1973e |
( __t2_table[i].ntv_event[j], &event_code )
|
|
Packit Service |
a1973e |
>= PAPI_OK ) {
|
|
Packit Service |
a1973e |
tmp.data.native[j] = event_code;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: pst row %d - event_code=%d\n",
|
|
Packit Service |
a1973e |
__func__, i, tmp.event_code );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: pst row %d - data.derived=%d, data.operation=%c\n",
|
|
Packit Service |
a1973e |
__func__, i, tmp.data.derived, tmp.data.operation[0] );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: pst row %d - native event codes:\n", __func__, i );
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int d_i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( d_i = 0; d_i < PAPI_EVENTS_IN_DERIVED_EVENT; d_i++ ) {
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: pst row %d - +++ data.native[%d]=%d\n",
|
|
Packit Service |
a1973e |
__func__, i, d_i, tmp.data.native[d_i] );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memcpy( &preset_table[i], &tmp, sizeof ( tmp ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pst_events++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// Check!
|
|
Packit Service |
a1973e |
memset( &preset_table[num_psts], 0, sizeof ( hwi_search_t ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_niagara2_vector.cmp_info.num_preset_events = pst_events;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__cpc_recreate_set( hwd_control_state_t * ctrl )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
const int syn_barrier = _niagara2_vector.cmp_info.num_native_events
|
|
Packit Service |
a1973e |
- __t2_store.syn_evt_count;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Destroy the old buffer and the old set if they exist, we need to do a full
|
|
Packit Service |
a1973e |
recreate as changing flags or events through libcpc is not possible */
|
|
Packit Service |
a1973e |
if ( ctrl->counter_buffer != NULL ) {
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_buf_destroy( cpc, ctrl->counter_buffer ) );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ctrl->set != NULL ) {
|
|
Packit Service |
a1973e |
__CHECK_ERR_DFLT( cpc_set_destroy( cpc, ctrl->set ) );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Create a new set */
|
|
Packit Service |
a1973e |
ctrl->set = cpc_set_create( cpc );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NULL( ctrl->set );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( i = 0; i < ctrl->count; i++ ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Adding native event %#x (%s) on position %d\n",
|
|
Packit Service |
a1973e |
__func__, ctrl->code[i].event_code,
|
|
Packit Service |
a1973e |
__t2_ntv_events[ctrl->code[i].event_code], i );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Event setup: ctrl->code[%d].event_code=%#x\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->code[i].event_code );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Event setup: ctrl->preset[%d]=%d\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->preset[i] );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Event setup: ctrl->flags[%d]=%#x\n",
|
|
Packit Service |
a1973e |
__func__, i, ctrl->flags[i] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
/* Ensure that synthetic events are skipped */
|
|
Packit Service |
a1973e |
if ( ctrl->code[i].event_code >= syn_barrier ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Skipping counter %d, synthetic event found\n",
|
|
Packit Service |
a1973e |
__func__, i );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Next iteration */
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->idx[i] = cpc_set_add_request( cpc, ctrl->set,
|
|
Packit Service |
a1973e |
__t2_ntv_events[ctrl->code[i].
|
|
Packit Service |
a1973e |
event_code],
|
|
Packit Service |
a1973e |
ctrl->preset[i], ctrl->flags[i], 0,
|
|
Packit Service |
a1973e |
NULL );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NEGV( ctrl->idx[i] );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->counter_buffer = cpc_buf_create( cpc, ctrl->set );
|
|
Packit Service |
a1973e |
__CHECK_ERR_NULL( ctrl->counter_buffer );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__cpc_domain_translator( const int papi_domain )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int domain = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: papi_domain=%d requested\n", __func__, papi_domain );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( papi_domain & PAPI_DOM_USER ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Domain PAPI_DOM_USER/CPC_COUNT_USER selected\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
domain |= CPC_COUNT_USER;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( papi_domain & PAPI_DOM_KERNEL ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Domain PAPI_DOM_KERNEL/CPC_COUNT_SYSTEM selected\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
domain |= CPC_COUNT_SYSTEM;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( papi_domain & PAPI_DOM_SUPERVISOR ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Domain PAPI_DOM_SUPERVISOR/CPC_COUNT_HV selected\n",
|
|
Packit Service |
a1973e |
__func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
domain |= CPC_COUNT_HV;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: domain=%d\n", __func__, domain );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return domain;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
__cpc_error_handler( const char *fn, int subcode, const char *fmt, va_list ap )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* From the libcpc manpages */
|
|
Packit Service |
a1973e |
fprintf( stderr, "ERROR - libcpc error handler in %s() called!\n", fn );
|
|
Packit Service |
a1973e |
vfprintf( stderr, fmt, ap );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__cpc_enable_sigemt( hwd_control_state_t * ctrl, int position )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( position >= MAX_COUNTERS ) {
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Position of the counter does not exist\n", __func__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_EINVAL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ctrl->flags[position] = ctrl->flags[position] | CPC_OVF_NOTIFY_EMT;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return __cpc_recreate_set( ctrl );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
__cpc_walk_events_pic_action_count( void *arg, uint_t picno, const char *event )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
__t2_store.pic_ntv_count[picno]++;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG
|
|
Packit Service |
a1973e |
( " -> %s: Found one native event on PIC#%d (now totally %d events)\n",
|
|
Packit Service |
a1973e |
__func__, picno, __t2_store.pic_ntv_count[picno] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
__cpc_walk_events_pic_action_store( void *arg, uint_t picno, const char *event )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int *tmp = ( int * ) arg;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
__t2_ntv_events[*tmp] = papi_strdup( event );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Native event >>%s<< registered\n",
|
|
Packit Service |
a1973e |
__func__, __t2_ntv_events[*tmp] );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
*tmp = *tmp + 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__sol_get_processor_clock( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
processor_info_t pinfo;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
// Fetch information from the first processor in the system
|
|
Packit Service |
a1973e |
if ( processor_info( getcpuid( ), &pinfo ) == 0 ) {
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( " -> %s: Clock at %d MHz\n", __func__, pinfo.pi_clock );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return pinfo.pi_clock;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* This function either increases the ns supplied to itimer_res_ns or pads it up
|
|
Packit Service |
a1973e |
* to a multiple of itimer_res_ns if the value is bigger than itimer_res_ns.
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* The source is taken from the old component.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
__sol_get_itimer_ns( int ns )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
if ( ns < _papi_os_info.itimer_res_ns ) {
|
|
Packit Service |
a1973e |
return _papi_os_info.itimer_res_ns;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
int leftover_ns = ns % _papi_os_info.itimer_res_ns;
|
|
Packit Service |
a1973e |
return ns + leftover_ns;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline lwpstatus_t *
|
|
Packit Service |
a1973e |
__sol_get_lwp_status( const pid_t pid, const lwpid_t lwpid )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *pattern = "/proc/%d/lwp/%d/lwpstatus";
|
|
Packit Service |
a1973e |
char filename[PAPI_MIN_STR_LEN];
|
|
Packit Service |
a1973e |
int fd;
|
|
Packit Service |
a1973e |
static lwpstatus_t lwp;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset( &lwp, 0, sizeof ( lwp ) );
|
|
Packit Service |
a1973e |
snprintf( filename, PAPI_MIN_STR_LEN, pattern, pid, lwpid );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fd = open( filename, O_RDONLY );
|
|
Packit Service |
a1973e |
if ( fd == -1 )
|
|
Packit Service |
a1973e |
return NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
read( fd, ( void * ) &lwp, sizeof ( lwp ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
close( fd );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return &lw;;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline psinfo_t *
|
|
Packit Service |
a1973e |
__sol_get_proc_info( const pid_t pid )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *pattern = "/proc/%d/psinfo";
|
|
Packit Service |
a1973e |
char filename[PAPI_MIN_STR_LEN];
|
|
Packit Service |
a1973e |
int fd;
|
|
Packit Service |
a1973e |
static psinfo_t proc;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset( &proc, 0, sizeof ( proc ) );
|
|
Packit Service |
a1973e |
snprintf( filename, PAPI_MIN_STR_LEN, pattern, pid );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fd = open( filename, O_RDONLY );
|
|
Packit Service |
a1973e |
if ( fd == -1 )
|
|
Packit Service |
a1973e |
return NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
read( fd, ( void * ) &proc, sizeof ( proc ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
close( fd );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return &proc;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static inline pstatus_t *
|
|
Packit Service |
a1973e |
__sol_get_proc_status( const pid_t pid )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *pattern = "/proc/%d/status";
|
|
Packit Service |
a1973e |
char filename[PAPI_MIN_STR_LEN];
|
|
Packit Service |
a1973e |
int fd;
|
|
Packit Service |
a1973e |
static pstatus_t proc;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset( &proc, 0, sizeof ( proc ) );
|
|
Packit Service |
a1973e |
snprintf( filename, PAPI_MIN_STR_LEN, pattern, pid );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fd = open( filename, O_RDONLY );
|
|
Packit Service |
a1973e |
if ( fd == -1 )
|
|
Packit Service |
a1973e |
return NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
read( fd, ( void * ) &proc, sizeof ( proc ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
close( fd );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return &proc;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* This function handles synthetic events and returns their result. Synthetic
|
|
Packit Service |
a1973e |
* events are events retrieved from outside of libcpc, e.g. all events which
|
|
Packit Service |
a1973e |
* can not be retrieved using cpc_set_add_request/cpc_buf_get. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
uint64_t
|
|
Packit Service |
a1973e |
__int_get_synthetic_event( int code, hwd_control_state_t * ctrl, void *arg )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
switch ( code ) {
|
|
Packit Service |
a1973e |
case SYNTHETIC_CYCLES_ELAPSED:
|
|
Packit Service |
a1973e |
/* Return the count of ticks this set was bound. If a reset of the set
|
|
Packit Service |
a1973e |
has been executed the last count will be subtracted. */
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int *i = ( int * ) arg;
|
|
Packit Service |
a1973e |
return cpc_buf_tick( cpc,
|
|
Packit Service |
a1973e |
ctrl->counter_buffer ) - ctrl->syn_hangover[*i];
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
case SYNTHETIC_RETURN_ONE:
|
|
Packit Service |
a1973e |
// The name says it - only for testing purposes.
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return 1;
|
|
Packit Service |
a1973e |
case SYNTHETIC_RETURN_TWO:
|
|
Packit Service |
a1973e |
// The name says it - only for testing purposes.
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return 2;
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return PAPI_EINVAL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
__int_setup_synthetic_event( int code, hwd_control_state_t * ctrl, void *arg )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
switch ( code ) {
|
|
Packit Service |
a1973e |
case SYNTHETIC_CYCLES_ELAPSED:
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return PAPI_EINVAL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
__int_walk_synthetic_events_action_count( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Count all synthetic events in __int_syn_table, the last event is marked
|
|
Packit Service |
a1973e |
with an event code of -1. */
|
|
Packit Service |
a1973e |
while ( __int_syn_table[i].code != -1 ) {
|
|
Packit Service |
a1973e |
__t2_store.syn_evt_count++;
|
|
Packit Service |
a1973e |
i++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef SYNTHETIC_EVENTS_SUPPORTED
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
__int_walk_synthetic_events_action_store( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
/* The first index of a synthetic event starts after last native event */
|
|
Packit Service |
a1973e |
int i = 0;
|
|
Packit Service |
a1973e |
int offset = _niagara2_vector.cmp_info.num_native_events + 1 -
|
|
Packit Service |
a1973e |
__t2_store.syn_evt_count;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while ( i < __t2_store.syn_evt_count ) {
|
|
Packit Service |
a1973e |
__t2_ntv_events[i + offset] = papi_strdup( __int_syn_table[i].name );
|
|
Packit Service |
a1973e |
i++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
SUBDBG( "LEAVING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
|
|
Packit Service |
a1973e |
__LINE__ );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
papi_vector_t _niagara2_vector = {
|
|
Packit Service |
a1973e |
/************* COMPONENT CAPABILITIES/INFORMATION/ETC ************************/
|
|
Packit Service |
a1973e |
.cmp_info = {
|
|
Packit Service |
a1973e |
.name = "solaris-niagara2",
|
|
Packit Service |
a1973e |
.description = "Solaris Counters",
|
|
Packit Service |
a1973e |
.num_cntrs = MAX_COUNTERS,
|
|
Packit Service |
a1973e |
.num_mpx_cntrs = MAX_COUNTERS,
|
|
Packit Service |
a1973e |
.default_domain = PAPI_DOM_USER,
|
|
Packit Service |
a1973e |
.available_domains = ( PAPI_DOM_USER | PAPI_DOM_KERNEL
|
|
Packit Service |
a1973e |
| PAPI_DOM_SUPERVISOR ),
|
|
Packit Service |
a1973e |
.default_granularity = PAPI_GRN_THR,
|
|
Packit Service |
a1973e |
.available_granularities = PAPI_GRN_THR,
|
|
Packit Service |
a1973e |
.fast_real_timer = 1,
|
|
Packit Service |
a1973e |
.fast_virtual_timer = 1,
|
|
Packit Service |
a1973e |
.attach = 1,
|
|
Packit Service |
a1973e |
.attach_must_ptrace = 1,
|
|
Packit Service |
a1973e |
.hardware_intr = 1,
|
|
Packit Service |
a1973e |
.hardware_intr_sig = SIGEMT,
|
|
Packit Service |
a1973e |
.precise_intr = 1,
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
/************* COMPONENT DATA STRUCTURE SIZES ********************************/
|
|
Packit Service |
a1973e |
.size = {
|
|
Packit Service |
a1973e |
.context = sizeof ( hwd_context_t ),
|
|
Packit Service |
a1973e |
.control_state = sizeof ( hwd_control_state_t ),
|
|
Packit Service |
a1973e |
.reg_value = sizeof ( hwd_register_t ),
|
|
Packit Service |
a1973e |
.reg_alloc = sizeof ( niagara2_reg_alloc_t ),
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
/************* COMPONENT INTERFACE FUNCTIONS *********************************/
|
|
Packit Service |
a1973e |
.init_control_state = _niagara2_init_control_state,
|
|
Packit Service |
a1973e |
.start = _niagara2_start,
|
|
Packit Service |
a1973e |
.stop = _niagara2_stop,
|
|
Packit Service |
a1973e |
.read = _niagara2_read,
|
|
Packit Service |
a1973e |
.write = NULL, /* NOT IMPLEMENTED */
|
|
Packit Service |
a1973e |
.shutdown_thread = _niagara2_shutdown,
|
|
Packit Service |
a1973e |
.shutdown_component = _niagara2_shutdown_global,
|
|
Packit Service |
a1973e |
.ctl = _niagara2_ctl,
|
|
Packit Service |
a1973e |
.update_control_state = _niagara2_update_control_state,
|
|
Packit Service |
a1973e |
.set_domain = _niagara2_set_domain,
|
|
Packit Service |
a1973e |
.reset = _niagara2_reset,
|
|
Packit Service |
a1973e |
.set_overflow = _niagara2_set_overflow,
|
|
Packit Service |
a1973e |
.set_profile = _niagara2_set_profile,
|
|
Packit Service |
a1973e |
.stop_profiling = NULL, /* NOT IMPLEMENTED */
|
|
Packit Service |
a1973e |
.ntv_enum_events = _niagara2_ntv_enum_events,
|
|
Packit Service |
a1973e |
.ntv_name_to_code = NULL, /* NOT IMPLEMENTED */
|
|
Packit Service |
a1973e |
.ntv_code_to_name = _niagara2_ntv_code_to_name,
|
|
Packit Service |
a1973e |
.ntv_code_to_descr = _niagara2_ntv_code_to_descr,
|
|
Packit Service |
a1973e |
.ntv_code_to_bits = _niagara2_ntv_code_to_bits,
|
|
Packit Service |
a1973e |
.init_component = _niagara2_init_component,
|
|
Packit Service |
a1973e |
.dispatch_timer = _niagara2_dispatch_timer,
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
papi_os_vector_t _papi_os_vector = {
|
|
Packit Service |
a1973e |
.get_memory_info = _niagara2_get_memory_info,
|
|
Packit Service |
a1973e |
.get_dmem_info = _solaris_get_dmem_info,
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
.get_real_usec = _solaris_get_real_usec,
|
|
Packit Service |
a1973e |
.get_real_cycles = _solaris_get_real_cycles,
|
|
Packit Service |
a1973e |
.get_virt_usec = _solaris_get_virt_usec,
|
|
Packit Service |
a1973e |
.update_shlib_info = _solaris_update_shlib_info,
|
|
Packit Service |
a1973e |
.get_system_info = _solaris_get_system_info,
|
|
Packit Service |
a1973e |
};
|