ppc64_events.c File Reference

Include dependency graph for ppc64_events.c:

Go to the source code of this file.

Functions

void perfctr_initialize_native_table ()
void perfctr_ppc64_setup_gps (int total, ntv_event_group_info_t *group_info)
int perfctr_ppc64_setup_native_table ()
int check_native_name ()
static FILE * open_file (const char *fname)
static ntv_event_tcopy_buffer (ntv_event_t events[], int maxevents)
static ntv_event_info_tparse_eventfile (FILE *evfile)
static int any_counter_invalid (int event_id[], int size)
static ntv_event_group_info_tparse_groupfile (FILE *grp_file)
ntv_event_info_tperfctr_get_native_evt_info (void)
ntv_event_group_info_tperfctr_get_native_group_info (void)

Variables

hwd_groups_t group_map [MAX_GROUPS]
native_event_entry_t native_table [PAPI_MAX_NATIVE_EVENTS]

Function Documentation

static int any_counter_invalid ( int  event_id[],
int  size 
) [static]

Definition at line 395 of file ppc64_events.c.

00396 {
00397     int j;
00398     for ( j = 0; j < size; j++ ) {
00399         if ( event_id[j] >= PAPI_MAX_NATIVE_EVENTS )
00400             return 1;
00401     }
00402     return 0;
00403 }

Here is the caller graph for this function:

int check_native_name (  ) 

Definition at line 168 of file ppc64_events.c.

00169 {
00170     enum native_name foo;
00171     int itemCount = 0;
00172     int i;
00173 
00174     /* This should ensure that the cardinality of native_name is the same
00175        as that of native_name_map which may be true iff native_name 
00176        expresses the same data as native_name_map and there is a 1:1 
00177        mapping from one onto the other, though there is no guarantee of 
00178        order. */
00179     if ( ( NATNAME_GUARD - PAPI_NATIVE_MASK ) != MAX_NATNAME_MAP_INDEX ) {
00180         SUBDBG( "%i is the number of elements apparently in native_name, "
00181                 "but really should be %i, according to native_name_map.\n",
00182                 ( NATNAME_GUARD - PAPI_NATIVE_MASK ), MAX_NATNAME_MAP_INDEX );
00183         PAPIERROR
00184             ( "Inconsistent cardinality between native_name and native_name_map "
00185               "detected in preliminary check\n" );
00186         return PAPI_EBUG;
00187     }
00188 
00189     /* The following is sanity checking only.  It attempts to verify some level
00190        of consistency between native_name and native_name_map and native_table.
00191        This should imply that native_name is a subset of native_name_map. */
00192     for ( foo = PAPI_NATIVE_MASK; foo < NATNAME_GUARD; foo++ ) {
00193         for ( i = 0; i < MAX_NATNAME_MAP_INDEX; i++ ) {
00194             /* Now, if the event we are on is the native event we seek... */
00195             if ( ( native_name_map[i].index | PAPI_NATIVE_MASK ) == foo ) {
00196                 itemCount++;
00197                 break;
00198             }
00199         }
00200     }
00201     if ( itemCount != MAX_NATNAME_MAP_INDEX ) {
00202         SUBDBG( "Inconsistency between native_name_map and native_name.  "
00203                 "%i events matched, but really should be %i\n", itemCount,
00204                 MAX_NATNAME_MAP_INDEX );
00205         PAPIERROR
00206             ( "Inconsistent cardinality between native_name and native_name_map\n" );
00207         return PAPI_EBUG;
00208     }
00209 
00210     return PAPI_OK;
00211 }

Here is the call graph for this function:

Here is the caller graph for this function:

static ntv_event_t* copy_buffer ( ntv_event_t  events[],
int  maxevents 
) [static]

Definition at line 279 of file ppc64_events.c.

00280 {
00281     ntv_event_t *cur_wev, *start_wev;
00282     start_wev = ( ntv_event_t * ) malloc( sizeof ( ntv_event_t ) * maxevents );
00283     cur_wev = start_wev;
00284 
00285     int cnt;
00286     for ( cnt = 0; cnt < maxevents; cnt++, cur_wev++ ) {
00287         cur_wev->event_num = events[cnt].event_num;
00288         strcpy( cur_wev->symbol, events[cnt].symbol );
00289         cur_wev->short_description =
00290             ( char * ) malloc( strlen( events[cnt].short_description ) );
00291         strcpy( cur_wev->short_description, events[cnt].short_description );
00292         cur_wev->description =
00293             ( char * ) malloc( strlen( events[cnt].description ) );
00294         strcpy( cur_wev->description, events[cnt].description );
00295     }
00296     return start_wev;
00297 }

Here is the caller graph for this function:

static FILE* open_file ( const char *  fname  )  [static]

Definition at line 214 of file ppc64_events.c.

00215 {
00216     char *cpu;
00217     char *dot = ".";
00218     char *dot_dot = "..";
00219 #ifdef _POWER5p
00220     cpu = "power5+";
00221 #elif defined(_POWER5)
00222     cpu = "power5";
00223 #elif defined(_PPC970)
00224     cpu = "ppc970";
00225 #else
00226     cpu = "";
00227 #endif
00228     char *dir = ( char * ) getenv( "PAPI_EVENTFILE_PATH" );
00229 #ifdef PAPI_DATADIR
00230     if ( dir == NULL ) {
00231         dir = PAPI_DATADIR;
00232     }
00233 #endif
00234     /* If dir is still NULL, assume current dir holds event_data dir */
00235     if ( dir == NULL )
00236         dir = dot;
00237 
00238     char *relative_pathname = ( char * ) malloc( strlen( "/" ) +
00239                                                  strlen( "event_data" ) +
00240                                                  strlen( "/" ) + strlen( cpu ) +
00241                                                  strlen( "/" ) +
00242                                                  strlen( fname ) + 1 );
00243     strcpy( relative_pathname, "/" );
00244     strcat( relative_pathname, "event_data" );
00245     strcat( relative_pathname, "/" );
00246     strcat( relative_pathname, cpu );
00247     strcat( relative_pathname, "/" );
00248     strcat( relative_pathname, fname );
00249     /* Add a little extra space to the malloc for the case where dir = "." since
00250      * we may be trying dir = ".." later on. */
00251     char *pathname =
00252         ( char * ) malloc( strlen( dir ) + strlen( relative_pathname ) + 4 );
00253     int keep_trying;
00254     if ( strcmp( dir, dot ) == 0 )
00255         keep_trying = 2;
00256     else
00257         keep_trying = 3;
00258     FILE *file = NULL;
00259     while ( file == NULL && keep_trying-- ) {
00260         strcpy( pathname, dir );
00261         strcat( pathname, relative_pathname );
00262         file = fopen( pathname, "r" );
00263         if ( strcmp( dir, dot ) == 0 ) {
00264             dir = dot_dot;
00265         } else {
00266             dir = dot;
00267         }
00268         SUBDBG( "Attempt to open event data file %s %s successful.\n", pathname,
00269                 ( file == NULL ) ? "was not" : "was" );
00270         memset( pathname, '\0', sizeof ( pathname ) );
00271     }
00272 
00273     free( pathname );
00274     free( relative_pathname );
00275     return ( file );
00276 }

Here is the call graph for this function:

Here is the caller graph for this function:

static ntv_event_info_t* parse_eventfile ( FILE *  evfile  )  [static]

Definition at line 300 of file ppc64_events.c.

00301 {
00302     int counter = 0, num_events = 0;
00303     int i, len, cc;
00304     int event;
00305     int line_counter_flag = 0;
00306     char line_data[1024];
00307     ntv_event_t events[PAPI_MAX_NATIVE_EVENTS];
00308     ntv_event_info_t *ntv_evt_info =
00309         ( ntv_event_info_t * ) malloc( sizeof ( ntv_event_info_t ) );
00310     ntv_evt_info->maxpmcs = 0;
00311     char data[1024];
00312     while ( fgets( data, 1022, evfile ) ) {
00313         if ( feof( evfile ) )
00314             continue;
00315         if ( strlen( data ) < 2 )
00316             continue;
00317 
00318         if ( strncmp( data, "$$$$", 4 ) == 0 ) {
00319             line_counter_flag = 0;
00320             ntv_evt_info->maxevents[counter - 1] = num_events;
00321             ntv_evt_info->wev[counter - 1] = copy_buffer( events, num_events );
00322             ntv_event_t *temp = ntv_evt_info->wev[counter - 1];
00323             temp++;
00324         }
00325         switch ( line_counter_flag ) {
00326         case 0:
00327             if ( sscanf( data, "{ counter %u", &counter ) == 1 ) {
00328                 line_counter_flag = 1;
00329                 num_events = 0;
00330                 ntv_evt_info->maxpmcs++;
00331             }
00332             break;
00333         case 1:
00334             if ( sscanf( data, "#%u", &event ) != 1 ) {
00335                 fprintf( stderr, "EVS file format error 1 (%s)\n", data );
00336                 return NULL;
00337             }
00338             if ( event >= PAPI_MAX_NATIVE_EVENTS ) {
00339                 fprintf( stderr, "EVS file format error 1 (%s)\n", data );
00340                 return NULL;
00341             }
00342             events[num_events].event_num = event;
00343             len = strlen( data );
00344             int symb_found = 0;
00345             for ( i = cc = 0; i < len; i++ ) {
00346                 if ( data[i] == ',' )
00347                     cc++;
00348                 if ( cc == 5 && !symb_found ) {
00349                     strcpy( line_data, &data[i + 1] );
00350                     int j = 0;
00351                     while ( line_data[j] != ',' )
00352                         j++;
00353                     strncpy( events[num_events].symbol, line_data, j );
00354                     events[num_events].symbol[j] = 0;
00355                     symb_found = 1;
00356                     i += j;
00357                 } else if ( cc == 6 ) {
00358                     len = strlen( &data[i + 1] );
00359                     events[num_events].short_description =
00360                         ( char * ) malloc( len );
00361                     strcpy( events[num_events].short_description,
00362                             &data[i + 1] );
00363                     events[num_events].short_description[len - 1] = 0;
00364                     break;
00365                 }
00366             }
00367             line_counter_flag = 2;
00368             break;
00369         case 2:
00370             line_counter_flag = 3;
00371             break;
00372         case 3:
00373             len = strlen( data );
00374             events[num_events].description = ( char * ) malloc( len );
00375             strcpy( events[num_events].description, data );
00376             events[num_events].description[len - 1] = 0;
00377             line_counter_flag = 1;
00378             num_events++;
00379             break;
00380         }
00381     }
00382     if ( counter == 0 ) {
00383         free( ntv_evt_info );
00384         ntv_evt_info = NULL;
00385     }
00386     if ( counter == MAX_COUNTERS ) {
00387         ntv_evt_info->maxevents[counter - 1] = num_events;
00388         ntv_evt_info->wev[counter - 1] = copy_buffer( events, num_events );
00389     }
00390     fclose( evfile );
00391     return ntv_evt_info;
00392 }

Here is the call graph for this function:

Here is the caller graph for this function:

static ntv_event_group_info_t* parse_groupfile ( FILE *  grp_file  )  [static]

Definition at line 406 of file ppc64_events.c.

00407 {
00408     char data[1024];
00409     unsigned int mmcr0, mmcr1H, mmcr1L, mmcra;
00410     int g, state = 0;
00411     ntv_event_group_info_t *group_info =
00412         ( ntv_event_group_info_t * )
00413         malloc( sizeof ( ntv_event_group_info_t ) );
00414     group_info->maxgroups = 0;
00415     int event_num[MAX_COUNTERS];
00416     while ( fgets( data, 1022, grp_file ) ) {
00417         if ( feof( grp_file ) || ( strlen( data ) < 2 ) )
00418             continue;
00419 
00420         switch ( state ) {
00421         case 0:
00422 #if defined(_POWER5) || defined(_POWER5p)
00423             if ( sscanf
00424                  ( data, "#%u,%u,%u,%u,%u,%u,%u", &g, &event_num[0],
00425                    &event_num[1], &event_num[2], &event_num[3], &event_num[4],
00426                    &event_num[5] ) == 7 ) {
00427                 state = 1;
00428                 if ( any_counter_invalid( event_num, 6 ) ) {
00429                     fprintf( stderr, "ERROR: Maximum events exceeded\n" );
00430                     return NULL;
00431                 }
00432             }
00433 #else
00434             if ( sscanf
00435                  ( data, "#%u,%u,%u,%u,%u,%u,%u,%u,%u", &g, &event_num[0],
00436                    &event_num[1], &event_num[2], &event_num[3], &event_num[4],
00437                    &event_num[5], &event_num[6], &event_num[7] ) == 9 ) {
00438                 state = 1;
00439                 if ( any_counter_invalid( event_num, 8 ) ) {
00440                     fprintf( stderr, "ERROR: Maximum events exceeded\n" );
00441                     return NULL;
00442                 }
00443             }
00444 #endif
00445             if ( state == 1 ) {
00446                 group_info->event_groups[group_info->maxgroups] =
00447                     ( event_group_t * ) malloc( sizeof ( event_group_t ) );
00448                 group_info->event_groups[group_info->maxgroups]->group_id = g;
00449                 int j = 0;
00450                 for ( ; j < MAX_COUNTERS; j++ )
00451                     group_info->event_groups[group_info->maxgroups]->events[j] =
00452                         event_num[j];
00453             }
00454             break;
00455         case 1:
00456             // unused hex event codes
00457             state = 2;
00458             break;
00459         case 2:
00460             /* get mmcr values */
00461             if ( sscanf( data, "%#x,%#x,%#x,%#x", &mmcr0, &mmcr1H, &mmcr1L, &mmcra )
00462                  != 4 ) {
00463                 fprintf( stderr, "GPS file format error 1 (%s)\n", data );
00464                 return NULL;
00465             }
00466             state = 3;
00467             group_info->event_groups[group_info->maxgroups]->mmcr0 = mmcr0;
00468             group_info->event_groups[group_info->maxgroups]->mmcr1L = mmcr1L;
00469             group_info->event_groups[group_info->maxgroups]->mmcr1U = mmcr1H;
00470             group_info->event_groups[group_info->maxgroups]->mmcra = mmcra;
00471             group_info->maxgroups++;
00472             break;
00473         case 3:
00474             // unused group name
00475             state = 0;
00476         }
00477     }
00478     fclose( grp_file );
00479     return group_info;
00480 }

Here is the call graph for this function:

Here is the caller graph for this function:

ntv_event_info_t* perfctr_get_native_evt_info ( void   ) 

Definition at line 483 of file ppc64_events.c.

00484 {
00485     ntv_event_info_t *evt_info = NULL;
00486     FILE *evt_file = open_file( "events" );
00487     if ( evt_file != NULL ) {
00488         evt_info = parse_eventfile( evt_file );
00489     }
00490     return evt_info;
00491 
00492 }

Here is the call graph for this function:

Here is the caller graph for this function:

ntv_event_group_info_t* perfctr_get_native_group_info ( void   ) 

Definition at line 495 of file ppc64_events.c.

00496 {
00497     ntv_event_group_info_t *groups = NULL;
00498     FILE *grp_file = NULL;
00499     if ( ( grp_file = open_file( "groups" ) ) != NULL ) {
00500         groups = parse_groupfile( grp_file );
00501     }
00502     return groups;
00503 }

Here is the call graph for this function:

Here is the caller graph for this function:

void perfctr_initialize_native_table (  ) 

Definition at line 27 of file ppc64_events.c.

00028 {
00029     int i, j;
00030     memset( native_table, 0,
00031             PAPI_MAX_NATIVE_EVENTS * sizeof ( native_event_entry_t ) );
00032     for ( i = 0; i < PAPI_MAX_NATIVE_EVENTS; i++ ) {
00033         for ( j = 0; j < MAX_COUNTERS; j++ )
00034             native_table[i].resources.counter_cmd[j] = -1;
00035     }
00036 }

Here is the caller graph for this function:

void perfctr_ppc64_setup_gps ( int  total,
ntv_event_group_info_t group_info 
)

Definition at line 41 of file ppc64_events.c.

00042 {
00043     int i, j, gnum;
00044 
00045     for ( i = 0; i < total; i++ ) {
00046         for ( j = 0; j < MAX_COUNTERS; j++ ) {
00047             if ( native_table[i].resources.selector & ( 1 << j ) ) {
00048                 for ( gnum = 0; gnum < group_info->maxgroups; gnum++ ) {
00049                     if ( native_table[i].resources.counter_cmd[j] ==
00050                          group_info->event_groups[gnum]->events[j] ) {
00051                         native_table[i].resources.group[gnum / 32] |=
00052                             1 << ( gnum % 32 );
00053                     }
00054                 }
00055             }
00056         }
00057     }
00058 
00059     for ( gnum = 0; gnum < group_info->maxgroups; gnum++ ) {
00060         group_map[gnum].mmcr0 = group_info->event_groups[gnum]->mmcr0;
00061         group_map[gnum].mmcr1L = group_info->event_groups[gnum]->mmcr1L;
00062         group_map[gnum].mmcr1U = group_info->event_groups[gnum]->mmcr1U;
00063         group_map[gnum].mmcra = group_info->event_groups[gnum]->mmcra;
00064         for ( i = 0; i < MAX_COUNTERS; i++ )
00065             group_map[gnum].counter_cmd[i] =
00066                 group_info->event_groups[gnum]->events[i];
00067     }
00068 }

Here is the caller graph for this function:

int perfctr_ppc64_setup_native_table (  ) 

Definition at line 73 of file ppc64_events.c.

00074 {
00075     int pmc, ev, i, j, index;
00076     /* This is for initialisation-testing of consistency between
00077        native_name_map and our events file */
00078     int itemCount = 0;
00079     index = 0;
00080     perfctr_initialize_native_table(  );
00081     ntv_event_info_t *info = perfctr_get_native_evt_info(  );
00082     if ( info == NULL ) {
00083         PAPIERROR( EVENT_INFO_FILE_ERROR );
00084         return PAPI_ECMP;
00085     }
00086     ntv_event_t *wevp;
00087     for ( pmc = 0; pmc < info->maxpmcs; pmc++ ) {
00088         wevp = info->wev[pmc];
00089         for ( ev = 0; ev < info->maxevents[pmc]; ev++, wevp++ ) {
00090             for ( i = 0; i < index; i++ ) {
00091                 if ( strcmp( wevp->symbol, native_table[i].name ) == 0 ) {
00092                     native_table[i].resources.selector |= 1 << pmc;
00093                     native_table[i].resources.counter_cmd[pmc] =
00094                         wevp->event_num;
00095                     break;
00096                 }
00097             }
00098             if ( i == index ) {
00099                 //native_table[i].index=i; 
00100                 native_table[i].resources.selector |= 1 << pmc;
00101                 native_table[i].resources.counter_cmd[pmc] = wevp->event_num;
00102                 native_table[i].name =
00103                     ( char * ) malloc( strlen( wevp->symbol ) + 1 );
00104                 strcpy( native_table[i].name, wevp->symbol );
00105                 native_table[i].description = wevp->description;
00106                 index++;
00107                 for ( j = 0; j < MAX_NATNAME_MAP_INDEX; j++ ) {
00108                     /* It appears that here, if I'm right, that the events
00109                        file entry matches the event from native_name_map, */
00110                     /* This here check is to ensure that native_name_map in fact
00111                        has MAX_NATNAME_MAP_INDEX elements, or rather that it never
00112                        tries to access one that has not been initialised. */
00113                     if ( native_name_map[j].name == NULL ) {
00114                         SUBDBG( "native_name_map has a NULL at position %i\n",
00115                                 j );
00116                         PAPIERROR
00117                             ( "Inconsistency between events_map file and events header." );
00118                         return PAPI_EBUG;
00119                     }
00120                     if ( strcmp( native_table[i].name, native_name_map[j].name )
00121                          == 0 ) {
00122                         native_name_map[j].index = i;
00123                         itemCount++;
00124                         break;
00125                     }
00126                 }
00127                 /* If we never set native_name_map[j], then there is an
00128                    inconsistency between native_name_map and native_table */
00129                 if ( ( !( j < MAX_NATNAME_MAP_INDEX ) ) ||
00130                      native_name_map[j].index != i ) {
00131                     SUBDBG
00132                         ( "No match found between native_name_map and native_table.  "
00133                           "Values was %s at position %i in native_table.\n",
00134                           native_table[i].name, i );
00135                     PAPIERROR
00136                         ( "Inconsistency between native_name_map and events file." );
00137                     return PAPI_EBUG;
00138                 }
00139             }
00140         }
00141     }
00142     /* given the previous evidence that native_name_map is a superset of
00143        native_table, ensuring this match in their cardinality shows them to
00144        be equivalent. */
00145     if ( itemCount != MAX_NATNAME_MAP_INDEX ) {
00146         SUBDBG( "%i events found in native_table, but really should be %i\n",
00147                 itemCount, MAX_NATNAME_MAP_INDEX );
00148         PAPIERROR
00149             ( "Inconsistent cardinality between native_name_map and events file",
00150               itemCount, MAX_NATNAME_MAP_INDEX );
00151         return PAPI_EBUG;
00152     }
00153 
00154     ntv_event_group_info_t *gp_info = perfctr_get_native_group_info(  );
00155     if ( gp_info == NULL ) {
00156         perfctr_initialize_native_table(  );
00157         PAPIERROR( EVENT_INFO_FILE_ERROR );
00158         return PAPI_ECMP;
00159     }
00160 
00161     perfctr_ppc64_setup_gps( index, gp_info );
00162     _papi_hwi_system_info.sub_info.num_native_events = index;
00163 
00164     return check_native_name(  );
00165 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

hwd_groups_t group_map[MAX_GROUPS]
Initial value:
 { {0}
, {0}
, {0}
, {0}
, {0}
}

Definition at line 17 of file ppc64_events.c.

native_event_entry_t native_table[PAPI_MAX_NATIVE_EVENTS]

Definition at line 23 of file ppc64_events.c.


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1