static ib_counter_t* add_ib_counter(const char* name, const char* file_name, int extended, ib_device_t *device) { ib_counter_t *new_cnt = (ib_counter_t*) papi_calloc(sizeof(ib_counter_t), 1); if (new_cnt == 0) { PAPIERROR("cannot allocate memory for new IB counter structure"); return (0); } new_cnt->ev_name = strdup(name); new_cnt->ev_file_name = strdup(file_name); new_cnt->extended = extended; new_cnt->ev_device = device; if (new_cnt->ev_name==0 || new_cnt->ev_file_name==0) { PAPIERROR("cannot allocate memory for counter internal fields"); papi_free(new_cnt); return (0); } // prepend the new counter to the counter list new_cnt->next = root_counter; root_counter = new_cnt; return (new_cnt); }
static int attach( hwd_control_state_t * ctl, unsigned long tid ) { struct vperfctr_control tmp; #ifdef VPERFCTR_CONTROL_CLOEXEC tmp.flags = VPERFCTR_CONTROL_CLOEXEC; #endif ctl->rvperfctr = rvperfctr_open( ( int ) tid ); if ( ctl->rvperfctr == NULL ) { PAPIERROR( VOPEN_ERROR ); return ( PAPI_ESYS ); } SUBDBG( "_papi_hwd_ctl rvperfctr_open() = %p\n", ctl->rvperfctr ); /* Initialize the per thread/process virtualized TSC */ memset( &tmp, 0x0, sizeof ( tmp ) ); tmp.cpu_control.tsc_on = 1; /* Start the per thread/process virtualized TSC */ if ( rvperfctr_control( ctl->rvperfctr, &tmp ) < 0 ) { PAPIERROR( RCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); } /* end attach() */
static int _x86_start( hwd_context_t * ctx, hwd_control_state_t * state ) { int error; #ifdef DEBUG print_control( &state->control.cpu_control ); #endif if ( state->rvperfctr != NULL ) { if ( ( error = rvperfctr_control( state->rvperfctr, &state->control ) ) < 0 ) { SUBDBG( "rvperfctr_control returns: %d\n", error ); PAPIERROR( RCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); } if ( ( error = vperfctr_control( ctx->perfctr, &state->control ) ) < 0 ) { SUBDBG( "vperfctr_control returns: %d\n", error ); PAPIERROR( VCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); }
int _xml_papi_hwi_setup_all_presets( char *arch, hwi_dev_notes_t * notes ) { int done = 0; FILE *fp = fopen( "./papi_events.xml", "r" ); XML_Parser p = XML_ParserCreate( NULL ); if ( !p ) { PAPIERROR( "Couldn't allocate memory for XML parser." ); fclose(fp); return ( PAPI_ESYS ); } XML_SetElementHandler( p, _xml_start, _xml_end ); XML_SetCharacterDataHandler( p, _xml_content ); if ( fp == NULL ) { PAPIERROR( "Error opening Preset XML file." ); fclose(fp); return ( PAPI_ESYS ); } xml_arch = arch; do { int len; void *buffer = XML_GetBuffer( p, BUFFSIZE ); if ( buffer == NULL ) { PAPIERROR( "Couldn't allocate memory for XML buffer." ); fclose(fp); return ( PAPI_ESYS ); } len = fread( buffer, 1, BUFFSIZE, fp ); if ( ferror( fp ) ) { PAPIERROR( "XML read error." ); fclose(fp); return ( PAPI_ESYS ); } done = feof( fp ); if ( !XML_ParseBuffer( p, len, len == 0 ) ) { PAPIERROR( "Parse error at line %d:\n%s", XML_GetCurrentLineNumber( p ), XML_ErrorString( XML_GetErrorCode( p ) ) ); fclose(fp); return ( PAPI_ESYS ); } if ( error ) { fclose(fp); return ( PAPI_ESYS ); } } while ( !done ); XML_ParserFree( p ); fclose( fp ); return ( PAPI_OK ); }
int _perfctr_init( hwd_context_t * ctx ) { struct vperfctr_control tmp; int error; /* Initialize our thread/process pointer. */ if ( ( ctx->perfctr = vperfctr_open( ) ) == NULL ) { #ifdef VPERFCTR_OPEN_CREAT_EXCL /* New versions of perfctr have this, which allows us to get a previously created context, i.e. one created after a fork and now we're inside a new process that has been exec'd */ if ( errno ) { if ( ( ctx->perfctr = vperfctr_open_mode( 0 ) ) == NULL ) { PAPIERROR( VOPEN_ERROR ); return ( PAPI_ESYS ); } } else { PAPIERROR( VOPEN_ERROR ); return ( PAPI_ESYS ); } #else PAPIERROR( VOPEN_ERROR ); return ( PAPI_ESYS ); #endif } SUBDBG( "_papi_hwd_init vperfctr_open() = %p\n", ctx->perfctr ); /* Initialize the per thread/process virtualized TSC */ memset( &tmp, 0x0, sizeof ( tmp ) ); tmp.cpu_control.tsc_on = 1; #ifdef VPERFCTR_CONTROL_CLOEXEC tmp.flags = VPERFCTR_CONTROL_CLOEXEC; SUBDBG( "close on exec\t\t\t%u\n", tmp.flags ); #endif /* Start the per thread/process virtualized TSC */ error = vperfctr_control( ctx->perfctr, &tmp ); if ( error < 0 ) { SUBDBG( "starting virtualized TSC; vperfctr_control returns %d\n", error ); PAPIERROR( VCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); }
void _perfctr_dispatch_timer( int signal, siginfo_t * si, void *context ) { ( void ) signal; /*unused */ _papi_hwi_context_t ctx; ThreadInfo_t *master = NULL; int isHardware = 0; caddr_t address; int cidx = _perfctr_vector.cmp_info.CmpIdx; hwd_context_t *our_context; ctx.si = si; ctx.ucontext = ( ucontext_t * ) context; #define OVERFLOW_MASK si->si_pmc_ovf_mask #define GEN_OVERFLOW 0 address = ( caddr_t ) GET_OVERFLOW_ADDRESS( ( ctx ) ); _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, &isHardware, OVERFLOW_MASK, GEN_OVERFLOW, &master, _perfctr_vector.cmp_info.CmpIdx ); /* We are done, resume interrupting counters */ if ( isHardware ) { our_context=(hwd_context_t *) master->context[cidx]; errno = vperfctr_iresume( our_context->perfctr ); if ( errno < 0 ) { PAPIERROR( "vperfctr_iresume errno %d", errno ); } } }
int _papi_hwd_stop( hwd_context_t * ctx, hwd_control_state_t * state ) { if ( state->rvperfctr != NULL ) { if ( rvperfctr_stop( ( struct rvperfctr * ) ctx->perfctr ) < 0 ) { PAPIERROR( RCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); } if ( vperfctr_stop( ctx->perfctr ) < 0 ) { PAPIERROR( VCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); }
int mpx_check( int EventSet ) { /* Currently, there is only the need for one mpx check: if * running on POWER6/perfctr platform, the domain must * include user, kernel, and supervisor, since the scale * event uses the dedicated counter #6, PM_RUN_CYC, which * cannot be controlled on a domain level. */ EventSetInfo_t *ESI = _papi_hwi_lookup_EventSet( EventSet ); if (ESI==NULL) return PAPI_EBUG; if ( strstr( _papi_hwd[ESI->CmpIdx]->cmp_info.name, "perfctr.c" ) == NULL ) return PAPI_OK; if ( strcmp( _papi_hwi_system_info.hw_info.model_string, "POWER6" ) == 0 ) { unsigned int chk_domain = PAPI_DOM_USER + PAPI_DOM_KERNEL + PAPI_DOM_SUPERVISOR; if ( ( ESI->domain.domain & chk_domain ) != chk_domain ) { PAPIERROR ( "This platform requires PAPI_DOM_USER+PAPI_DOM_KERNEL+PAPI_DOM_SUPERVISOR\n" "to be set in the domain when using multiplexing. Instead, found %#x\n", ESI->domain.domain ); return ( PAPI_EINVAL_DOM ); } } return PAPI_OK; }
static char* make_ib_event_description(const char* input_str, int extended) { int i, len; char *desc = 0; if (! input_str) return (0); desc = (char*) papi_calloc(PAPI_MAX_STR_LEN, 1); if (desc == 0) { PAPIERROR("cannot allocate memory for event description"); return (0); } len = strlen(input_str); snprintf(desc, PAPI_MAX_STR_LEN, "%s (%s).", input_str, (extended ? "free-running 64bit counter" : "overflowing, auto-resetting counter")); desc[0] = toupper(desc[0]); for (i=0 ; i<len ; ++i) if (desc[i] == '_') desc[i] = ' '; return (desc); }
/** Remove events that are not used any longer from the run * list of events to multiplex by the handler * MUST BE CALLED WITH THE SIGNAL HANDLER DISABLED */ static void mpx_remove_unused( MasterEvent ** head ) { MasterEvent *mev, *lastmev = NULL, *nextmev; Threadlist *thr = ( *head == NULL ) ? NULL : ( *head )->mythr; int retval; /* Clean up and remove unused master events. */ for ( mev = *head; mev != NULL; mev = nextmev ) { nextmev = mev->next; /* get link before mev is freed */ if ( !mev->uses ) { if ( lastmev == NULL ) { /* this was the head event */ *head = nextmev; } else { lastmev->next = nextmev; } retval=PAPI_cleanup_eventset( mev->papi_event ); retval=PAPI_destroy_eventset( &( mev->papi_event ) ); if (retval!=PAPI_OK) PAPIERROR("Error destroying event\n"); papi_free( mev ); } else { lastmev = mev; } } /* Always be sure the head master event points to the thread */ if ( *head != NULL ) { ( *head )->mythr = thr; } }
static int setup_preset_term(int *native, pfmlib_event_t *event) { /* It seems this could be greatly simplified. If impl_cnt is non-zero, the event lives on a counter. Therefore the entire routine could be: if (impl_cnt!= 0) encode_native_event. Am I wrong? */ pfmlib_regmask_t impl_cnt, evnt_cnt; unsigned int n; int j, ret; /* find out which counters it lives on */ if ((ret = pfm_get_event_counters(event->event,&evnt_cnt)) != PFMLIB_SUCCESS) { PAPIERROR("pfm_get_event_counters(%d,%p): %s",event->event,&evnt_cnt,pfm_strerror(ret)); return(PAPI_EBUG); } if ((ret = pfm_get_impl_counters(&impl_cnt)) != PFMLIB_SUCCESS) { PAPIERROR("pfm_get_impl_counters(%p): %s", &impl_cnt, pfm_strerror(ret)); return(PAPI_EBUG); } /* Make sure this event lives on some counter, if so, put in the description. If not, BUG */ if ((ret = pfm_get_num_counters(&n)) != PFMLIB_SUCCESS) { PAPIERROR("pfm_get_num_counters(%d): %s", n, pfm_strerror(ret)); return(PAPI_EBUG); } for (j=0;n;j++) { if (pfm_regmask_isset(&impl_cnt, j)) { n--; if (pfm_regmask_isset(&evnt_cnt,j)) { *native = encode_native_event(event->event,event->num_masks,event->unit_masks); return(PAPI_OK); } } } PAPIERROR("PAPI preset 0x%08x PFM event %d did not have any available counters", event->event, j); return(PAPI_ENOEVNT); }
int get_temperature_value( ) { char txt[256]; char *p; int v, fd; static FILE *f = NULL; static int old_acpi = 0; if ( !f ) { if ( !( f = fopen_first( "/proc/acpi/thermal_zone", "temperature", "r" ) ) ) { if ( !( f = fopen_first( "/proc/acpi/thermal", "status", "r" ) ) ) { SUBDBG( "Unable to open ACPI temperature file." ); goto fail; } old_acpi = 1; } } if ( !( p = fgets( txt, sizeof ( txt ), f ) ) ) { SUBDBG( "Unable to read data from ACPI temperature file." ); goto fail; } fd = dup( fileno( f ) ); if (fd<0) goto fail; fclose( f ); f = fdopen( fd, "r" ); assert( f ); fseek( f, 0, SEEK_SET ); if ( !old_acpi ) { if ( strlen( p ) > 20 ) v = atoi( p + 20 ); else v = 0; } else { if ( strlen( p ) > 15 ) v = atoi( p + 15 ); else v = 0; v = ( ( v - 2732 ) / 10 ); /* convert from deciKelvin to degrees Celcius */ } if (( v > 100 ) || ( v < 0 )) PAPIERROR("Unexpected temperature value.\n"); return v; fail: if ( f ) { fclose( f ); f = NULL; } return INVALID_VALUE; }
static void mpx_restore_signal( void ) { MPXDBG( "restore signal\n" ); if ( _papi_os_info.itimer_sig != PAPI_NULL ) { if ( signal( _papi_os_info.itimer_sig, SIG_IGN ) == SIG_ERR ) PAPIERROR( "sigaction stop errno %d", errno ); } }
static void mpx_shutdown_itimer( void ) { MPXDBG( "setitimer off\n" ); if ( _papi_os_info.itimer_num != PAPI_NULL ) { if ( setitimer( _papi_os_info.itimer_num, ( struct itimerval * ) &itimestop, NULL ) == -1 ) PAPIERROR( "setitimer stop errno %d", errno ); } }
int _papi_libpfm_ntv_enum_events( unsigned int *EventCode, int modifier ) { unsigned int event, umask, num_masks; int ret; if ( modifier == PAPI_ENUM_FIRST ) { *EventCode = PAPI_NATIVE_MASK; /* assumes first native event is always 0x4000000 */ return ( PAPI_OK ); } if ( _pfm_decode_native_event( *EventCode, &event, &umask ) != PAPI_OK ) return ( PAPI_ENOEVNT ); ret = pfm_get_num_event_masks( event, &num_masks ); if ( ret != PFMLIB_SUCCESS ) { PAPIERROR( "pfm_get_num_event_masks(%d,%p): %s", event, &num_masks, pfm_strerror( ret ) ); return ( PAPI_ENOEVNT ); } if ( num_masks > PAPI_NATIVE_UMASK_MAX ) num_masks = PAPI_NATIVE_UMASK_MAX; SUBDBG( "This is umask %d of %d\n", umask, num_masks ); if ( modifier == PAPI_ENUM_EVENTS ) { if ( event < ( unsigned int ) num_native_events - 1 ) { *EventCode = ( unsigned int ) encode_native_event_raw( event + 1, 0 ); return ( PAPI_OK ); } return ( PAPI_ENOEVNT ); } else if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) { if ( umask + 1 < ( unsigned int ) ( 1 << num_masks ) ) { *EventCode = ( unsigned int ) encode_native_event_raw( event, umask + 1 ); return ( PAPI_OK ); } return ( PAPI_ENOEVNT ); } else if ( modifier == PAPI_NTV_ENUM_UMASKS ) { int thisbit = ffs( ( int ) umask ); SUBDBG( "First bit is %d in %08x\b\n", thisbit - 1, umask ); thisbit = 1 << thisbit; if ( thisbit & ( ( 1 << num_masks ) - 1 ) ) { *EventCode = ( unsigned int ) encode_native_event_raw( event, ( unsigned int ) thisbit ); return ( PAPI_OK ); } return ( PAPI_ENOEVNT ); } else return ( PAPI_EINVAL ); }
static int _x86_stop( hwd_context_t * ctx, hwd_control_state_t * state ) { int error; if ( state->rvperfctr != NULL ) { if ( rvperfctr_stop( ( struct rvperfctr * ) ctx->perfctr ) < 0 ) { PAPIERROR( RCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); } error = vperfctr_stop( ctx->perfctr ); if ( error < 0 ) { SUBDBG( "vperfctr_stop returns: %d\n", error ); PAPIERROR( VCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); }
int _papi_hwd_init( hwd_context_t * ctx ) { /* Initialize our thread/process pointer. */ if ( ( ctx->self = pmc_dev = pmc_open( ) ) == NULL ) { PAPIERROR( "pmc_open() returned NULL" ); return ( PAPI_ESYS ); } SUBDBG( "_papi_hwd_init pmc_open() = %p\n", ctx->self ); /* Linux makes sure that each thread has a virtualized TSC here. This makes no sense on Windows, since the counters aren't saved at context switch. */ return ( PAPI_OK ); }
static ib_device_t* add_ib_device(const char* name, int port) { ib_device_t *new_dev = (ib_device_t*) papi_calloc(sizeof(ib_device_t), 1); if (new_dev == 0) { PAPIERROR("cannot allocate memory for new IB device structure"); return (0); } new_dev->dev_name = strdup(name); new_dev->dev_port = port; if (new_dev->dev_name==0) { PAPIERROR("cannot allocate memory for device internal fields"); papi_free(new_dev); return (0); } // prepend the new device to the device list new_dev->next = root_device; root_device = new_dev; return (new_dev); }
static int mpx_startup_itimer( void ) { struct sigaction sigact; /* Set up the signal handler and the timer that triggers it */ MPXDBG( "PID %d\n", getpid( ) ); memset( &sigact, 0, sizeof ( sigact ) ); sigact.sa_flags = SA_RESTART; sigact.sa_handler = mpx_handler; if ( sigaction( _papi_os_info.itimer_sig, &sigact, NULL ) == -1 ) { PAPIERROR( "sigaction start errno %d", errno ); return PAPI_ESYS; } if ( setitimer( _papi_os_info.itimer_num, &itime, NULL ) == -1 ) { sigaction( _papi_os_info.itimer_sig, &oaction, NULL ); PAPIERROR( "setitimer start errno %d", errno ); return PAPI_ESYS; } return ( PAPI_OK ); }
int _papi_hwd_start( hwd_context_t * ctx, hwd_control_state_t * state ) { int error; /* clear_unused_pmcsel_bits(this_state); moved to update_control_state */ #ifdef DEBUG print_control( &state->control.cpu_control ); #endif if ( state->rvperfctr != NULL ) { if ( ( error = rvperfctr_control( state->rvperfctr, &state->control ) ) < 0 ) { SUBDBG( "rvperfctr_control returns: %d\n", error ); PAPIERROR( RCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); } if ( ( error = vperfctr_control( ctx->perfctr, &state->control ) ) < 0 ) { SUBDBG( "vperfctr_control returns: %d\n", error ); PAPIERROR( VCNTRL_ERROR ); return ( PAPI_ESYS ); } return ( PAPI_OK ); }
static int x86_get_memory_info( PAPI_hw_info_t *hw_info ) { int retval = PAPI_OK; switch ( hw_info->vendor ) { case PAPI_VENDOR_AMD: case PAPI_VENDOR_INTEL: retval = _x86_cache_info( &hw_info->mem_hierarchy ); break; default: PAPIERROR( "Unknown vendor in memory information call for x86." ); return PAPI_ENOIMPL; } return retval; }
static int _papi_hwd_fixup_vec( void ) { char table_name[PAPI_MIN_STR_LEN] = "Intel Pentium4 VEC "; char *str = getenv( "PAPI_PENTIUM4_VEC" ); /* if the env variable isn't set, use the default */ if ( ( str == NULL ) || ( strlen( str ) == 0 ) ) { strcat( table_name, P4_VEC ); } else { strcat( table_name, str ); } if ( ( _papi_libpfm_setup_presets( table_name, 0 ) ) != PAPI_OK ) { PAPIERROR ( "Improper usage of PAPI_PENTIUM4_VEC environment variable.\nUse either SSE or MMX" ); return ( PAPI_ESBSTR ); } return ( PAPI_OK ); }
static long long read_ib_counter_value(int index) { char ev_file[128]; long long value = 0ll; infiniband_native_event_entry_t *iter = &infiniband_native_events[index]; snprintf(ev_file, sizeof(ev_file), "%s/%s/ports/%d/counters%s/%s", ib_dir_path, iter->device->dev_name, iter->device->dev_port, (iter->extended?"_ext":""), iter->file_name); if (pscanf(ev_file, "%lld", &value) != 1) { PAPIERROR("cannot read value for counter '%s'\n", iter->name); } else { SUBDBG("Counter '%s': %lld\n", iter->name, value); } return (value); }
/* convert the mask values in a pfm event structure into a PAPI unit mask */ static inline unsigned int convert_pfm_masks( pfmlib_event_t * gete ) { int ret; unsigned int i, code, tmp = 0; for ( i = 0; i < gete->num_masks; i++ ) { if ( ( ret = pfm_get_event_mask_code( gete->event, gete->unit_masks[i], &code ) ) == PFMLIB_SUCCESS ) { SUBDBG( "Mask value is 0x%08x\n", code ); tmp |= code; } else { PAPIERROR( "pfm_get_event_mask_code(%#x,%d,%p): %s", gete->event, i, &code, pfm_strerror( ret ) ); } } return ( tmp ); }
static int lookup_and_set_thread_symbols( void ) { #if defined(ANY_THREAD_GETS_SIGNAL) int retval; char *error_ptc = NULL, *error_ptk = NULL; void *symbol_ptc = NULL, *symbol_ptk = NULL, *handle = NULL; handle = dlopen( NULL, RTLD_LAZY ); if ( handle == NULL ) { PAPIERROR( "Error from dlopen(NULL, RTLD_LAZY): %d %s", errno, dlerror( ) ); return ( PAPI_ESYS ); } symbol_ptc = dlsym( handle, "pthread_self" ); if ( symbol_ptc == NULL ) { error_ptc = dlerror( ); THRDBG( "dlsym(%p,pthread_self) returned NULL: %s\n", ( error_ptc ? error_ptc : "No error, NULL symbol!" ) ); } symbol_ptk = dlsym( handle, "pthread_kill" ); if ( symbol_ptk == NULL ) { error_ptk = dlerror( ); THRDBG( "dlsym(%p,pthread_kill) returned NULL: %s\n", ( error_ptk ? error_ptk : "No error, NULL symbol!" ) ); } dlclose( handle ); if ( !( ( _papi_hwi_thread_kill_fn && _papi_hwi_thread_id_fn ) || ( !_papi_hwi_thread_kill_fn && !_papi_hwi_thread_id_fn ) ) ) return ( PAPI_EMISC ); _papi_hwi_thread_kill_fn = ( int ( * )( int, int ) ) symbol_ptk; _papi_hwi_thread_id_fn = ( unsigned long ( * )( void ) ) symbol_ptc; #endif return ( PAPI_OK ); }
/* Collected wisdom indicates that each call to pmc_set_control will write 0's into the hardware counters, effecting a reset operation. */ int _papi_hwd_start( hwd_context_t * ctx, hwd_control_state_t * spc ) { int error; struct pmc_control *ctl = ( struct pmc_control * ) ( spc->control.cpu_control.evntsel ); /* clear the accumulating counter values */ memset( ( void * ) spc->state.sum.pmc, 0, _papi_hwi_system_info.num_cntrs * sizeof ( long long ) ); if ( ( error = pmc_set_control( ctx->self, ctl ) ) < 0 ) { SUBDBG( "pmc_set_control returns: %d\n", error ); { PAPIERROR( "pmc_set_control() returned < 0" ); return ( PAPI_ESYS ); } } #ifdef DEBUG print_control( &spc->control.cpu_control ); #endif return ( PAPI_OK ); }
static int _papi_hwd_fixup_fp( char *name ) { char table_name[PAPI_MIN_STR_LEN]; char *str = getenv( "PAPI_OPTERON_FP" ); /* if the env variable isn't set, return the defaults */ strcpy( table_name, name ); strcat( table_name, " FPU " ); if ( ( str == NULL ) || ( strlen( str ) == 0 ) ) { strcat( table_name, AMD_FPU ); } else { strcat( table_name, str ); } if ( ( _papi_libpfm_setup_presets( table_name, 0 ) ) != PAPI_OK ) { PAPIERROR ( "Improper usage of PAPI_OPTERON_FP environment variable.\nUse one of RETIRED, SPECULATIVE, SSE_SP, SSE_DP" ); return ( PAPI_ESBSTR ); } return ( PAPI_OK ); }
static int _papi_p4_hwd_fixup_fp( void ) { char table_name[PAPI_MIN_STR_LEN] = "Intel Pentium4 FPU"; char *str = getenv( "PAPI_PENTIUM4_FP" ); /* if the env variable isn't set, use the default */ if ( ( str == NULL ) || ( strlen( str ) == 0 ) ) { strcat( table_name, P4_FPU ); } else { if ( strstr( str, "X87" ) ) strcat( table_name, " X87" ); if ( strstr( str, "SSE_SP" ) ) strcat( table_name, " SSE_SP" ); if ( strstr( str, "SSE_DP" ) ) strcat( table_name, " SSE_DP" ); } if ( ( _papi_libpfm_setup_presets( table_name, 0 ) ) != PAPI_OK ) { PAPIERROR ( "Improper usage of PAPI_PENTIUM4_FP environment variable.\nUse one or two of X87,SSE_SP,SSE_DP" ); return ( PAPI_ESBSTR ); } return ( PAPI_OK ); }
int _papi_libpfm_ntv_code_to_name( unsigned int EventCode, char *ntv_name, int len ) { int ret; unsigned int event, umask; pfmlib_event_t gete; memset( &gete, 0, sizeof ( gete ) ); if ( _pfm_decode_native_event( EventCode, &event, &umask ) != PAPI_OK ) return ( PAPI_ENOEVNT ); gete.event = event; gete.num_masks = ( unsigned int ) prepare_umask( umask, gete.unit_masks ); if ( gete.num_masks == 0 ) ret = pfm_get_event_name( gete.event, ntv_name, ( size_t ) len ); else ret = pfm_get_full_event_name( &gete, ntv_name, ( size_t ) len ); if ( ret != PFMLIB_SUCCESS ) { char tmp[PAPI_2MAX_STR_LEN]; pfm_get_event_name( gete.event, tmp, sizeof ( tmp ) ); /* Skip error message if event is not supported by host cpu; * we don't need to give this info away for papi_native_avail util */ if ( ret != PFMLIB_ERR_BADHOST ) PAPIERROR ( "pfm_get_full_event_name(%p(event %d,%s,%d masks),%p,%d): %d -- %s", &gete, gete.event, tmp, gete.num_masks, ntv_name, len, ret, pfm_strerror( ret ) ); if ( ret == PFMLIB_ERR_FULL ) { return PAPI_EBUF; } return PAPI_EMISC; } return PAPI_OK; }
/* * user_signal_handler * * This function is used when hardware overflows are working or when * software overflows are forced */ void user_signal_handler_IOUNIT( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext ) { #ifdef DEBUG_BGQ printf( "user_signal_handler_IOUNIT\n" ); #endif int retval, i; int isHardware = 1; int cidx = _IOunit_vector.cmp_info.CmpIdx; long_long overflow_bit = 0; caddr_t address1; _papi_hwi_context_t ctx; ctx.ucontext = ( hwd_ucontext_t * ) pContext; ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 ); EventSetInfo_t *ESI; ESI = thread->running_eventset[cidx]; // Get the indices of all events which have overflowed. unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS]; unsigned len = BGPM_MAX_OVERFLOW_EVENTS; retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len ); if ( retval < 0 ) { #ifdef DEBUG_BGPM printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n", retval ); #endif return; } if ( thread == NULL ) { PAPIERROR( "thread == NULL in user_signal_handler!" ); return; } if ( ESI == NULL ) { PAPIERROR( "ESI == NULL in user_signal_handler!"); return; } if ( ESI->overflow.flags == 0 ) { PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!"); return; } for ( i = 0; i < len; i++ ) { uint64_t hProf; Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf ); if ( hProf ) { overflow_bit ^= 1 << ovfIdxs[i]; break; } } if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) { #ifdef DEBUG_BGQ printf("OVERFLOW_SOFTWARE\n"); #endif address1 = GET_OVERFLOW_ADDRESS( ctx ); _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx ); return; } else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) { #ifdef DEBUG_BGQ printf("OVERFLOW_HARDWARE\n"); #endif address1 = GET_OVERFLOW_ADDRESS( ctx ); _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx ); } else { #ifdef DEBUG_BGQ printf("OVERFLOW_NONE\n"); #endif PAPIERROR( "ESI->overflow.flags is set to something other than PAPI_OVERFLOW_HARDWARE or PAPI_OVERFLOW_FORCE_SW (%x)", thread->running_eventset[cidx]->overflow.flags); } }