void _papi_cleanup_user_events() { unsigned int i; user_defined_event_t *t; list_t *a,*b; for ( i = 0; i < _papi_user_events_count; i++ ) { t = _papi_user_events + i; if ( t->short_desc != NULL ) free(t->short_desc); if ( t->long_desc != NULL ) free(t->long_desc); } if ( _papi_user_events != NULL ) papi_free( _papi_user_events ); _papi_user_events = NULL; _papi_user_events_count = 0; /* cleanup the defines list too */ for ( a = defines.next; a != NULL; ) { b=a->next; papi_free(a); a = b; } }
int _papi_hwi_cleanup_all_presets( void ) { int preset_index,cidx; unsigned int j; for ( preset_index = 0; preset_index < PAPI_MAX_PRESET_EVENTS; preset_index++ ) { if ( _papi_hwi_presets[preset_index].postfix != NULL ) { papi_free( _papi_hwi_presets[preset_index].postfix ); _papi_hwi_presets[preset_index].postfix = NULL; } if ( _papi_hwi_presets[preset_index].note != NULL ) { papi_free( _papi_hwi_presets[preset_index].note ); _papi_hwi_presets[preset_index].note = NULL; } for(j=0; j<_papi_hwi_presets[preset_index].count;j++) { papi_free(_papi_hwi_presets[preset_index].name[j]); } } for(cidx=0;cidx<papi_num_components;cidx++) { _papi_hwd[cidx]->cmp_info.num_preset_events = 0; } #if defined(ITANIUM2) || defined(ITANIUM3) /* NOTE: This memory may need to be freed for BG/P builds as well */ if ( preset_search_map != NULL ) { papi_free( preset_search_map ); preset_search_map = NULL; } #endif return PAPI_OK; }
static void deallocate_infiniband_resources() { int i; if (infiniband_native_events) { for (i=0 ; i<num_events ; ++i) { if (infiniband_native_events[i].name) free(infiniband_native_events[i].name); if (infiniband_native_events[i].file_name) free(infiniband_native_events[i].file_name); if (infiniband_native_events[i].description) papi_free(infiniband_native_events[i].description); } papi_free(infiniband_native_events); } ib_device_t *iter = root_device; while (iter != 0) { if (iter->dev_name) free(iter->dev_name); ib_device_t *tmp = iter; iter = iter->next; papi_free(tmp); } root_device = 0; }
static CpuInfo_t * allocate_cpu( unsigned int cpu_num ) { APIDBG("Entry: cpu_num: %d\n", cpu_num); CpuInfo_t *cpu; int i; /* Allocate new CpuInfo structure */ cpu = ( CpuInfo_t * ) papi_calloc( 1, sizeof ( CpuInfo_t ) ); if ( cpu == NULL ) { goto allocate_error; } /* identify the cpu this info structure represents */ cpu->cpu_num = cpu_num; cpu->context = ( hwd_context_t ** ) papi_calloc( ( size_t ) papi_num_components , sizeof ( hwd_context_t * ) ); if ( !cpu->context ) { goto error_free_cpu; } /* Allocate an eventset per component per cpu? Why? */ cpu->running_eventset = ( EventSetInfo_t ** ) papi_calloc(( size_t ) papi_num_components, sizeof ( EventSetInfo_t * ) ); if ( !cpu->running_eventset ) { goto error_free_context; } for ( i = 0; i < papi_num_components; i++ ) { cpu->context[i] = ( void * ) papi_calloc( 1, ( size_t ) _papi_hwd[i]->size.context ); cpu->running_eventset[i] = NULL; if ( cpu->context[i] == NULL ) { goto error_free_contexts; } } cpu->num_users=0; THRDBG( "Allocated CpuInfo: %p\n", cpu ); return cpu; error_free_contexts: for ( i--; i >= 0; i-- ) papi_free( cpu->context[i] ); error_free_context: papi_free( cpu->context ); error_free_cpu: papi_free( cpu ); allocate_error: return NULL; }
static void free_cpu( CpuInfo_t **cpu ) { APIDBG( "Entry: *cpu: %p, cpu_num: %d, cpu_users: %d\n", *cpu, ( *cpu )->cpu_num, (*cpu)->num_users); int i,users,retval; _papi_hwi_lock( CPUS_LOCK ); (*cpu)->num_users--; users=(*cpu)->num_users; /* Remove from linked list if no users */ if (!users) remove_cpu( *cpu ); _papi_hwi_unlock( CPUS_LOCK ); /* Exit early if still users of this CPU */ if (users!=0) return; THRDBG( "Shutting down cpu %d at %p\n", (*cpu)->cpu_num, cpu ); for ( i = 0; i < papi_num_components; i++ ) { if (_papi_hwd[i]->cmp_info.disabled) continue; retval = _papi_hwd[i]->shutdown_thread( (*cpu)->context[i] ); if ( retval != PAPI_OK ) { // failure = retval; } } for ( i = 0; i < papi_num_components; i++ ) { if ( ( *cpu )->context[i] ) { papi_free( ( *cpu )->context[i] ); } } if ( ( *cpu )->context ) { papi_free( ( *cpu )->context ); } if ( ( *cpu )->running_eventset ) { papi_free( ( *cpu )->running_eventset ); } /* why do we clear this? */ memset( *cpu, 0x00, sizeof ( CpuInfo_t ) ); papi_free( *cpu ); *cpu = NULL; }
void _papi_hwi_shutdown_highlevel(){ HighLevelInfo *state = NULL; if ( PAPI_get_thr_specific(PAPI_HIGH_LEVEL_TLS, (void *) &state)==PAPI_OK){ if ( state ) papi_free(state); } }
/** 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; } }
int MPX_cleanup( MPX_EventSet ** mpx_events ) { #ifdef PTHREADS int retval; #endif if ( mpx_events == NULL ) return PAPI_EINVAL; if ( *mpx_events == NULL ) return PAPI_OK; if (( *mpx_events )->status == MPX_RUNNING ) return PAPI_EINVAL; mpx_hold( ); /* Remove master events from this event set and from * the master list, if necessary. */ mpx_delete_events( *mpx_events ); mpx_release( ); /* Free all the memory */ papi_free( *mpx_events ); *mpx_events = NULL; return PAPI_OK; }
/** Triggered by PAPI_shutdown() */ int _papi_nvml_shutdown_substrate() { SUBDBG( "nvml_shutdown_substrate..." ); papi_free(nvml_native_table); papi_free(devices); nvmlShutdown(); device_count = 0; num_events = 0; return PAPI_OK; }
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); }
int _lustre_shutdown_component( void ) { host_finalize( ); papi_free( lustre_native_table ); return PAPI_OK; }
/* * Clean up what was setup in net_init_substrate(). */ int _net_shutdown_substrate( void ) { if ( is_initialized ) { is_initialized = 0; papi_free(_net_native_events); _net_native_events = NULL; } return PAPI_OK; }
static void free_cpu( CpuInfo_t ** cpu ) { THRDBG( "Entry: *cpu: %p, cpu_num: 0x%x\n", *cpu, ( *cpu )->cpu_num); int i; for ( i = 0; i < papi_num_components; i++ ) { if ( ( *cpu )->context[i] ) papi_free( ( *cpu )->context[i] ); } if ( ( *cpu )->context ) papi_free( ( *cpu )->context ); if ( ( *cpu )->running_eventset ) papi_free( ( *cpu )->running_eventset ); memset( *cpu, 0x00, sizeof ( CpuInfo_t ) ); papi_free( *cpu ); *cpu = NULL; }
/** Triggered by PAPI_shutdown() */ int coretemp_shutdown (hwd_context_t * ctx) { UNREFERENCED(ctx); SUBDBG( "coretemp_shutdown... %p\n", ctx ); /* Last chance to clean up */ papi_free (coretemp_native_table); return PAPI_OK; }
static void free_thread( ThreadInfo_t ** thread ) { int i; THRDBG( "Freeing thread %ld at %p\n", ( *thread )->tid, *thread ); for ( i = 0; i < papi_num_components; i++ ) { if ( ( *thread )->context[i] ) papi_free( ( *thread )->context[i] ); } if ( ( *thread )->context ) papi_free( ( *thread )->context ); if ( ( *thread )->running_eventset ) papi_free( ( *thread )->running_eventset ); memset( *thread, 0x00, sizeof ( ThreadInfo_t ) ); papi_free( *thread ); *thread = NULL; }
int _papi_hwi_cleanup_all_presets(void) { int preset_index; for (preset_index = 0; preset_index < PAPI_MAX_PRESET_EVENTS; preset_index++) { /* There's currently a debate over the use of papi_xxx memory functions. One camp says they should always be used; the other says they're only for debug. Meanwhile, our code had better not rely on their function... */ #ifndef PAPI_NO_MEMORY_MANAGEMENT /* free the names and descriptions only if they were malloc'd by PAPI * Generally, this info is statically allocated at compile time. * However, it is possible to override existing info, or append new * info to the table. In these cases, papi_valid_free can prevent * pointers from being stranded. */ #ifdef PAPI_MOD_EVENTS /* this can only happen if events are modifiable */ if (papi_valid_free(_papi_hwi_presets.info[preset_index].symbol)) _papi_hwi_presets.info[preset_index].symbol = NULL; if (papi_valid_free(_papi_hwi_presets.info[preset_index].long_descr)) _papi_hwi_presets.info[preset_index].long_descr = NULL; if (papi_valid_free(_papi_hwi_presets.info[preset_index].short_descr)) _papi_hwi_presets.info[preset_index].short_descr = NULL; #endif #endif /* free the data and or note string if they exist */ if (_papi_hwi_presets.data[preset_index] != NULL) { papi_free(_papi_hwi_presets.data[preset_index]); _papi_hwi_presets.data[preset_index] = NULL; } if (_papi_hwi_presets.dev_note[preset_index] != NULL) { papi_free(_papi_hwi_presets.dev_note[preset_index]); _papi_hwi_presets.dev_note[preset_index] = NULL; } } /* xxxx right now presets are only cpu, component 0 */ _papi_hwd[0]->cmp_info.num_preset_events = 0; return (PAPI_OK); }
// update tokens in formula referring to index "old_index" with tokens referring to index "new_index". static void update_ops_string(char **formula, int old_index, int new_index) { INTDBG("ENTER: *formula: %s, old_index: %d, new_index: %d\n", *formula?*formula:"NULL", old_index, new_index); int cur_index; char *newFormula; char *subtoken; char *tok_save_ptr=NULL; // if formula is null just return if (*formula == NULL) { INTDBG("EXIT: Null pointer to formula passed in\n"); return; } // get some space for the new formula we are going to create newFormula = papi_calloc(strlen(*formula) + 20, 1); // replace the specified "replace" tokens in the new original formula with the new insertion formula newFormula[0] = '\0'; subtoken = strtok_r(*formula, "|", &tok_save_ptr); while ( subtoken != NULL) { // INTDBG("subtoken: %s, newFormula: %s\n", subtoken, newFormula); char work[10]; // if this is the token we want to replace with the new token index, do it now if ((subtoken[0] == 'N') && (isdigit(subtoken[1]))) { cur_index = atoi(&subtoken[1]); // if matches old index, use the new one if (cur_index == old_index) { sprintf (work, "N%d", new_index); strcat (newFormula, work); } else if (cur_index > old_index) { // current token greater than old index, make it one less than what it was sprintf (work, "N%d", cur_index-1); strcat (newFormula, work); } else { // current token less than old index, copy this part of the original formula into the new formula strcat(newFormula, subtoken); } } else { // copy this part of the original formula into the new formula strcat(newFormula, subtoken); } strcat (newFormula, "|"); subtoken = strtok_r(NULL, "|", &tok_save_ptr); } papi_free (*formula); *formula = newFormula; INTDBG("EXIT: newFormula: %s\n", newFormula); return; }
/****************************************************************************** ******** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT ******** *****************************************************************************/ static int resize_native_table() { counter_info** new_table; int new_size = table_size*2; new_table = (counter_info**)papi_malloc(sizeof(counter_info*) * new_size); if (NULL==new_table) return PAPI_ENOMEM; if ( lustre_native_table) { memcpy(new_table, lustre_native_table, sizeof(counter_info*) * table_size ); papi_free(lustre_native_table); } lustre_native_table = new_table; table_size*=2; return PAPI_OK; }
/* Initialize hardware counters, setup the function vector table * and get hardware information, this routine is called when the * PAPI process is initialized (IE PAPI_library_init) */ int _net_init_component( int cidx ) { int i = 0; struct temp_event *t, *last; if ( is_initialized ) return PAPI_OK; memset(_net_register_start, 0, NET_MAX_COUNTERS*sizeof(_net_register_start[0])); memset(_net_register_current, 0, NET_MAX_COUNTERS*sizeof(_net_register_current[0])); is_initialized = 1; /* The network interfaces are listed in /proc/net/dev */ num_events = generateNetEventList(); if ( num_events < 0 ) /* PAPI errors */ return num_events; if ( num_events == 0 ) /* No network interfaces found */ return PAPI_OK; t = root; _net_native_events = (NET_native_event_entry_t*) papi_malloc(sizeof(NET_native_event_entry_t) * num_events); do { strncpy(_net_native_events[i].name, t->name, PAPI_MAX_STR_LEN-1); _net_native_events[i].name[PAPI_MAX_STR_LEN-1] = '\0'; strncpy(_net_native_events[i].description, t->description, PAPI_MAX_STR_LEN-1); _net_native_events[i].description[PAPI_MAX_STR_LEN-1] = '\0'; _net_native_events[i].resources.selector = i + 1; last = t; t = t->next; papi_free(last); i++; } while (t != NULL); root = NULL; /* Export the total number of events available */ _net_vector.cmp_info.num_native_events = num_events; /* Export the component id */ _net_vector.cmp_info.CmpIdx = cidx; return PAPI_OK; }
static void vector_print_routine( void *func, char *fname, int pfunc ) { void *ptr = NULL; char *buf = NULL; ptr = vector_find_dummy( func, &buf ); if ( ptr ) { printf( "DUMMY: %s is mapped to %s.\n", fname, buf ); papi_free( buf ); } else if ( ( !ptr && pfunc ) ) printf( "function: %s is mapped to %p.\n", fname, func ); }
/* * Clean up what was setup in net_init_component(). */ int _net_shutdown_component( void ) { if ( is_initialized ) { is_initialized = 0; if (_net_native_events != NULL) { papi_free(_net_native_events); _net_native_events = NULL; } } return PAPI_OK; }
void MPX_shutdown( void ) { MPXDBG( "%d\n", getpid( ) ); mpx_shutdown_itimer( ); mpx_restore_signal( ); if ( tlist ) { Threadlist *next,*t=tlist; while(t!=NULL) { next=t->next; papi_free( t ); t = next; } tlist = NULL; } }
static CpuInfo_t * allocate_cpu( unsigned int cpu_num ) { THRDBG("Entry: cpu_num: %d\n", cpu_num); CpuInfo_t *cpu; int i; cpu = ( CpuInfo_t * ) papi_malloc( sizeof ( CpuInfo_t ) ); if ( cpu == NULL ) return ( NULL ); memset( cpu, 0x00, sizeof ( CpuInfo_t ) ); /* identify the cpu this info structure represents */ cpu->cpu_num = cpu_num; cpu->context = ( hwd_context_t ** ) papi_malloc( sizeof ( hwd_context_t * ) * ( size_t ) papi_num_components ); if ( !cpu->context ) { papi_free( cpu ); return ( NULL ); } cpu->running_eventset = ( EventSetInfo_t ** ) papi_malloc( sizeof ( EventSetInfo_t * ) * ( size_t ) papi_num_components ); if ( !cpu->running_eventset ) { papi_free( cpu->context ); papi_free( cpu ); return ( NULL ); } for ( i = 0; i < papi_num_components; i++ ) { cpu->context[i] = ( void * ) papi_malloc( ( size_t ) _papi_hwd[i]->size.context ); cpu->running_eventset[i] = NULL; if ( cpu->context[i] == NULL ) { for ( i--; i >= 0; i-- ) papi_free( cpu->context[i] ); papi_free( cpu->context ); papi_free( cpu ); return ( NULL ); } memset( cpu->context[i], 0x00, ( size_t ) _papi_hwd[i]->size.context ); } THRDBG( "Allocated CpuInfo: %p\n", cpu ); return ( cpu ); }
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 find_ib_devices() { DIR *ib_dir = NULL; int result = PAPI_OK; num_events = 0; ib_dir = opendir(ib_dir_path); if (ib_dir == NULL) { SUBDBG("cannot open `%s'\n", ib_dir_path); strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband sysfs interface not found", PAPI_MAX_STR_LEN); result = PAPI_ENOSUPP; goto out; } struct dirent *hca_ent; while ((hca_ent = readdir(ib_dir)) != NULL) { char *hca = hca_ent->d_name; char ports_path[80]; DIR *ports_dir = NULL; if (hca[0] == '.') goto next_hca; snprintf(ports_path, sizeof(ports_path), "%s/%s/ports", ib_dir_path, hca); ports_dir = opendir(ports_path); if (ports_dir == NULL) { SUBDBG("cannot open `%s'\n", ports_path); goto next_hca; } struct dirent *port_ent; while ((port_ent = readdir(ports_dir)) != NULL) { int port = atoi(port_ent->d_name); if (port <= 0) continue; /* Check that port is active. .../HCA/ports/PORT/state should read "4: ACTIVE." */ int state = -1; char state_path[80]; snprintf(state_path, sizeof(state_path), "%s/%s/ports/%d/state", ib_dir_path, hca, port); if (pscanf(state_path, "%d", &state) != 1) { SUBDBG("cannot read state of IB HCA `%s' port %d\n", hca, port); continue; } if (state != 4) { SUBDBG("skipping inactive IB HCA `%s', port %d, state %d\n", hca, port, state); continue; } /* Create dev name (HCA/PORT) and get stats for dev. */ SUBDBG("Found IB device `%s', port %d\n", hca, port); ib_device_t *dev = add_ib_device(hca, port); if (!dev) continue; // do we want to check for short counters only if no extended counters found? num_events += find_ib_device_events(dev, 1); // check if we have extended (64bit) counters num_events += find_ib_device_events(dev, 0); // check also for short counters } next_hca: if (ports_dir != NULL) closedir(ports_dir); } if (root_device == 0) // no active devices found { strncpy(_infiniband_vector.cmp_info.disabled_reason, "No active Infiniband ports found", PAPI_MAX_STR_LEN); result = PAPI_ENOIMPL; } else if (num_events == 0) { strncpy(_infiniband_vector.cmp_info.disabled_reason, "No supported Infiniband events found", PAPI_MAX_STR_LEN); result = PAPI_ENOIMPL; } else { // Events are stored in a linked list, in reverse order than how I found them // Revert them again, so that they are in finding order, not that it matters. int i = num_events - 1; // now allocate memory to store the counters into the native table infiniband_native_events = (infiniband_native_event_entry_t*) papi_calloc(sizeof(infiniband_native_event_entry_t), num_events); ib_counter_t *iter = root_counter; while (iter != 0) { infiniband_native_events[i].name = iter->ev_name; infiniband_native_events[i].file_name = iter->ev_file_name; infiniband_native_events[i].device = iter->ev_device; infiniband_native_events[i].extended = iter->extended; infiniband_native_events[i].resources.selector = i + 1; infiniband_native_events[i].description = make_ib_event_description(iter->ev_file_name, iter->extended); ib_counter_t *tmp = iter; iter = iter->next; papi_free(tmp); -- i; } root_counter = 0; } out: if (ib_dir != NULL) closedir(ib_dir); return (result); }
static int build_tables( void ) { int i; int regno; int npic; einfo_t *ep; int n; int npresets; npic = cpc_getnpic( cpuver ); nctrs = 0; for ( regno = 0; regno < npic; ++regno ) { cpc_walk_names( cpuver, regno, 0, action ); } SUBDBG( "%d counters\n", nctrs ); if ( ( ctrs = papi_malloc( nctrs * sizeof ( struct ctr_info ) ) ) == 0 ) { return PAPI_ENOMEM; } nctrs = 0; for ( regno = 0; regno < npic; ++regno ) { cpc_walk_names( cpuver, regno, ( void * ) 1, action ); } SUBDBG( "%d counters\n", nctrs ); #if DEBUG if ( ISLEVEL( DEBUG_SUBSTRATE ) ) { for ( i = 0; i < nctrs; ++i ) { SUBDBG( "%s: bits (%x,%x) pics %x\n", ctrs[i].name, ctrs[i].bits[0], ctrs[i].bits[1], ctrs[i].bitmask ); } } #endif /* Build the native event table */ if ( ( native_table = papi_malloc( nctrs * sizeof ( native_info_t ) ) ) == 0 ) { papi_free( ctrs ); return PAPI_ENOMEM; } for ( i = 0; i < nctrs; ++i ) { native_table[i].name[39] = 0; strncpy( native_table[i].name, ctrs[i].name, 39 ); if ( ctrs[i].bitmask & 1 ) native_table[i].encoding[0] = ctrs[i].bits[0]; else native_table[i].encoding[0] = -1; if ( ctrs[i].bitmask & 2 ) native_table[i].encoding[1] = ctrs[i].bits[1]; else native_table[i].encoding[1] = -1; } papi_free( ctrs ); /* Build the preset table */ if ( cpuver <= CPC_ULTRA2 ) { n = sizeof ( us2info ) / sizeof ( einfo_t ); ep = us2info; } else if ( cpuver <= LASTULTRA3 ) { n = sizeof ( us3info ) / sizeof ( einfo_t ); ep = us3info; } else return PAPI_ESBSTR; preset_table = papi_malloc( ( n + 1 ) * sizeof ( hwi_search_t ) ); npresets = 0; for ( i = 0; i < n; ++i ) { add_preset( preset_table, &npresets, ep[i] ); } memset( &preset_table[npresets], 0, sizeof ( hwi_search_t ) ); #ifdef DEBUG if ( ISLEVEL( DEBUG_SUBSTRATE ) ) { SUBDBG( "Native table: %d\n", nctrs ); for ( i = 0; i < nctrs; ++i ) { SUBDBG( "%40s: %8x %8x\n", native_table[i].name, native_table[i].encoding[0], native_table[i].encoding[1] ); } SUBDBG( "\nPreset table: %d\n", npresets ); for ( i = 0; preset_table[i].event_code != 0; ++i ) { SUBDBG( "%8x: op %2d e0 %8x e1 %8x\n", preset_table[i].event_code, preset_table[i].data.derived, preset_table[i].data.native[0], preset_table[i].data.native[1] ); } } #endif _solaris_vector.cmp_info.num_native_events = nctrs; return PAPI_OK; }
/* once the bug in dladdr is fixed by SUN, (now dladdr caused deadlock when used with pthreads) this function can be used again */ int _papi_hwd_update_shlib_info( papi_mdi_t *mdi ) { char fname[80], name[PAPI_HUGE_STR_LEN]; prmap_t newp; int count, t_index; FILE *map_f; void *vaddr; Dl_info dlip; PAPI_address_map_t *tmp = NULL; sprintf( fname, "/proc/%d/map", getpid( ) ); map_f = fopen( fname, "r" ); if ( !map_f ) { PAPIERROR( "fopen(%s) returned < 0", fname ); return ( PAPI_OK ); } /* count the entries we need */ count = 0; t_index = 0; while ( fread( &newp, sizeof ( prmap_t ), 1, map_f ) > 0 ) { vaddr = ( void * ) ( 1 + ( newp.pr_vaddr ) ); // map base address if ( dladdr( vaddr, &dlip ) > 0 ) { count++; if ( ( newp.pr_mflags & MA_EXEC ) && ( newp.pr_mflags & MA_READ ) ) { if ( !( newp.pr_mflags & MA_WRITE ) ) t_index++; } strcpy( name, dlip.dli_fname ); if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name, basename( name ) ) == 0 ) { if ( ( newp.pr_mflags & MA_EXEC ) && ( newp.pr_mflags & MA_READ ) ) { if ( !( newp.pr_mflags & MA_WRITE ) ) { _papi_hwi_system_info.exe_info.address_info.text_start = ( caddr_t ) newp.pr_vaddr; _papi_hwi_system_info.exe_info.address_info.text_end = ( caddr_t ) ( newp.pr_vaddr + newp.pr_size ); } else { _papi_hwi_system_info.exe_info.address_info.data_start = ( caddr_t ) newp.pr_vaddr; _papi_hwi_system_info.exe_info.address_info.data_end = ( caddr_t ) ( newp.pr_vaddr + newp.pr_size ); } } } } } rewind( map_f ); tmp = ( PAPI_address_map_t * ) papi_calloc( t_index - 1, sizeof ( PAPI_address_map_t ) ); if ( tmp == NULL ) { PAPIERROR( "Error allocating shared library address map" ); return ( PAPI_ENOMEM ); } t_index = -1; while ( fread( &newp, sizeof ( prmap_t ), 1, map_f ) > 0 ) { vaddr = ( void * ) ( 1 + ( newp.pr_vaddr ) ); // map base address if ( dladdr( vaddr, &dlip ) > 0 ) { // valid name strcpy( name, dlip.dli_fname ); if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name, basename( name ) ) == 0 ) continue; if ( ( newp.pr_mflags & MA_EXEC ) && ( newp.pr_mflags & MA_READ ) ) { if ( !( newp.pr_mflags & MA_WRITE ) ) { t_index++; tmp[t_index].text_start = ( caddr_t ) newp.pr_vaddr; tmp[t_index].text_end = ( caddr_t ) ( newp.pr_vaddr + newp.pr_size ); strncpy( tmp[t_index].name, dlip.dli_fname, PAPI_HUGE_STR_LEN - 1 ); tmp[t_index].name[PAPI_HUGE_STR_LEN - 1] = '\0'; } else { if ( t_index < 0 ) continue; tmp[t_index].data_start = ( caddr_t ) newp.pr_vaddr; tmp[t_index].data_end = ( caddr_t ) ( newp.pr_vaddr + newp.pr_size ); } } } } fclose( map_f ); if ( _papi_hwi_system_info.shlib_info.map ) papi_free( _papi_hwi_system_info.shlib_info.map ); _papi_hwi_system_info.shlib_info.map = tmp; _papi_hwi_system_info.shlib_info.count = t_index + 1; return ( PAPI_OK ); }
int _ultra_hwd_update_shlib_info( papi_mdi_t *mdi ) { /*??? system call takes very long */ char cmd_line[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], fname[L_tmpnam]; char line[256]; char address[16], size[10], flags[64], objname[256]; PAPI_address_map_t *tmp = NULL; FILE *f = NULL; int t_index = 0, i; struct map_record { long address; int size; int flags; char objname[256]; struct map_record *next; } *tmpr, *head, *curr; tmpnam( fname ); SUBDBG( "Temporary name %s\n", fname ); sprintf( cmd_line, "/bin/pmap %d > %s", ( int ) getpid( ), fname ); if ( system( cmd_line ) != 0 ) { PAPIERROR( "Could not run %s to get shared library address map", cmd_line ); return ( PAPI_OK ); } f = fopen( fname, "r" ); if ( f == NULL ) { PAPIERROR( "fopen(%s) returned < 0", fname ); remove( fname ); return ( PAPI_OK ); } /* ignore the first line */ fgets( line, 256, f ); head = curr = NULL; while ( fgets( line, 256, f ) != NULL ) { /* discard the last line */ if ( strncmp( line, " total", 6 ) != 0 ) { sscanf( line, "%s %s %s %s", address, size, flags, objname ); if ( objname[0] == '/' ) { tmpr = ( struct map_record * ) papi_malloc( sizeof ( struct map_record ) ); if ( tmpr == NULL ) return ( -1 ); tmpr->next = NULL; if ( curr ) { curr->next = tmpr; curr = tmpr; } if ( head == NULL ) { curr = head = tmpr; } SUBDBG( "%s\n", objname ); if ( ( strstr( flags, "read" ) && strstr( flags, "exec" ) ) || ( strstr( flags, "r" ) && strstr( flags, "x" ) ) ) { if ( !( strstr( flags, "write" ) || strstr( flags, "w" ) ) ) { /* text segment */ t_index++; tmpr->flags = 1; } else { tmpr->flags = 0; } sscanf( address, "%lx", &tmpr->address ); sscanf( size, "%d", &tmpr->size ); tmpr->size *= 1024; strcpy( tmpr->objname, objname ); } } } } tmp = ( PAPI_address_map_t * ) papi_calloc( t_index - 1, sizeof ( PAPI_address_map_t ) ); if ( tmp == NULL ) { PAPIERROR( "Error allocating shared library address map" ); return ( PAPI_ENOMEM ); } t_index = -1; tmpr = curr = head; i = 0; while ( curr != NULL ) { if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name, basename( curr->objname ) ) == 0 ) { if ( curr->flags ) { _papi_hwi_system_info.exe_info.address_info.text_start = ( caddr_t ) curr->address; _papi_hwi_system_info.exe_info.address_info.text_end = ( caddr_t ) ( curr->address + curr->size ); } else { _papi_hwi_system_info.exe_info.address_info.data_start = ( caddr_t ) curr->address; _papi_hwi_system_info.exe_info.address_info.data_end = ( caddr_t ) ( curr->address + curr->size ); } } else { if ( curr->flags ) { t_index++; tmp[t_index].text_start = ( caddr_t ) curr->address; tmp[t_index].text_end = ( caddr_t ) ( curr->address + curr->size ); strncpy( tmp[t_index].name, curr->objname, PAPI_HUGE_STR_LEN - 1 ); tmp[t_index].name[PAPI_HUGE_STR_LEN - 1] = '\0'; } else { if ( t_index < 0 ) continue; tmp[t_index].data_start = ( caddr_t ) curr->address; tmp[t_index].data_end = ( caddr_t ) ( curr->address + curr->size ); } } tmpr = curr->next; /* free the temporary allocated memory */ papi_free( curr ); curr = tmpr; } /* end of while */ remove( fname ); fclose( f ); if ( _papi_hwi_system_info.shlib_info.map ) papi_free( _papi_hwi_system_info.shlib_info.map ); _papi_hwi_system_info.shlib_info.map = tmp; _papi_hwi_system_info.shlib_info.count = t_index + 1; return ( PAPI_OK ); }
/** Initialize hardware counters, setup the function vector table * and get hardware information, this routine is called when the * PAPI process is initialized (IE PAPI_library_init) */ int _papi_nvml_init_substrate( int cidx ) { nvmlReturn_t ret; cudaError_t cuerr; int cuda_count = 0; unsigned int nvml_count = 0; ret = nvmlInit(); if ( NVML_SUCCESS != ret ) { strcpy(_nvml_vector.cmp_info.disabled_reason, "The NVIDIA managament library failed to initialize."); goto disable; } cuerr = cuInit( 0 ); if ( CUDA_SUCCESS != cuerr ) { strcpy(_nvml_vector.cmp_info.disabled_reason, "The CUDA library failed to initialize."); goto disable; } /* Figure out the number of CUDA devices in the system */ ret = nvmlDeviceGetCount( &nvml_count ); if ( NVML_SUCCESS != ret ) { strcpy(_nvml_vector.cmp_info.disabled_reason, "Unable to get a count of devices from the NVIDIA managament library."); goto disable; } cuerr = cudaGetDeviceCount( &cuda_count ); if ( CUDA_SUCCESS != cuerr ) { strcpy(_nvml_vector.cmp_info.disabled_reason, "Unable to get a device count from CUDA."); goto disable; } /* We can probably recover from this, when we're clever */ if ( nvml_count != cuda_count ) { strcpy(_nvml_vector.cmp_info.disabled_reason, "Cuda and the NVIDIA managament library have different device counts."); goto disable; } device_count = cuda_count; /* A per device representation of what events are present */ features = (int*)papi_malloc(sizeof(int) * device_count ); /* Handles to each device */ devices = (nvmlDevice_t*)papi_malloc(sizeof(nvmlDevice_t) * device_count); /* Figure out what events are supported on each card. */ if ( (papi_errorcode = detectDevices( ) ) != PAPI_OK ) { papi_free(features); papi_free(devices); sprintf(_nvml_vector.cmp_info.disabled_reason, "An error occured in device feature detection, please check your NVIDIA Management Library and CUDA install." ); goto disable; } /* The assumption is that if everything went swimmingly in detectDevices, all nvml calls here should be fine. */ createNativeEvents( ); /* Export the total number of events available */ _nvml_vector.cmp_info.num_native_events = num_events; /* Export the component id */ _nvml_vector.cmp_info.CmpIdx = cidx; /* Export the number of 'counters' */ _nvml_vector.cmp_info.num_cntrs = num_events; return PAPI_OK; disable: _nvml_vector.cmp_info.num_cntrs = 0; return PAPI_OK; }
int mpx_add_event( MPX_EventSet ** mpx_events, int EventCode, int domain, int granularity ) { MPX_EventSet *newset = *mpx_events; int retval, alloced_newset = 0; Threadlist *t; /* Get the global list of threads */ MPXDBG("Adding %p %#x\n",newset,EventCode); _papi_hwi_lock( MULTIPLEX_LOCK ); t = tlist; /* If there are no threads in the list at all, then allocate the new Threadlist */ if ( t == NULL ) { new_thread: t = ( Threadlist * ) papi_malloc( sizeof ( Threadlist ) ); if ( t == NULL ) { _papi_hwi_unlock( MULTIPLEX_LOCK ); return ( PAPI_ENOMEM ); } /* If we're actually threaded, fill the * field with the thread_id otherwise * use getpid() as a placeholder. */ if ( _papi_hwi_thread_id_fn ) { MPXDBG( "New thread at %p\n", t ); t->tid = _papi_hwi_thread_id_fn( ); } else { MPXDBG( "New process at %p\n", t ); t->tid = ( unsigned long ) getpid( ); } /* Fill in the fields */ t->head = NULL; t->cur_event = NULL; t->next = tlist; tlist = t; MPXDBG( "New head is at %p(%lu).\n", tlist, ( long unsigned ) tlist->tid ); /* alloced_thread = 1; */ } else if ( _papi_hwi_thread_id_fn ) { /* If we are threaded, AND there exists threads in the list, * then try to find our thread in the list. */ unsigned long tid = _papi_hwi_thread_id_fn( ); while ( t ) { if ( t->tid == tid ) { MPXDBG( "Found thread %#lx\n", t->tid ); break; } t = t->next; } /* Our thread is not in the list, so make a new * thread entry. */ if ( t == NULL ) { MPXDBG( "New thread %lx\n", tid ); goto new_thread; } } /* Now t & tlist points to our thread, also at the head of the list */ /* Allocate a the MPX_EventSet if necessary */ if ( newset == NULL ) { newset = mpx_malloc( t ); if ( newset == NULL ) { _papi_hwi_unlock( MULTIPLEX_LOCK ); return ( PAPI_ENOMEM ); } alloced_newset = 1; } /* Now we're finished playing with the thread list */ _papi_hwi_unlock( MULTIPLEX_LOCK ); /* Removed newset->num_events++, moved to mpx_insert_events() */ mpx_hold( ); /* Create PAPI events (if they don't already exist) and link * the new event set to them, add them to the master list for the thread, reset master event list for this thread */ retval = mpx_insert_events( newset, &EventCode, 1, domain, granularity ); if ( retval != PAPI_OK ) { if ( alloced_newset ) { papi_free( newset ); newset = NULL; } } mpx_release( ); /* Output the new or existing EventSet */ *mpx_events = newset; return retval; }