PAPI  5.0.1.0
solaris-common.c
Go to the documentation of this file.
00001 #include "papi.h"
00002 #include "papi_internal.h"
00003 #include "papi_vector.h"
00004 #include "papi_memory.h"
00005 
00006 #include "solaris-common.h"
00007 
00008 #include <sys/utsname.h>
00009 
00010 
00011 #if 0
00012 /* once the bug in dladdr is fixed by SUN, (now dladdr caused deadlock when
00013    used with pthreads) this function can be used again */
00014 int
00015 _solaris_update_shlib_info( papi_mdi_t *mdi )
00016 {
00017     char fname[80], name[PAPI_HUGE_STR_LEN];
00018     prmap_t newp;
00019     int count, t_index;
00020     FILE *map_f;
00021     void *vaddr;
00022     Dl_info dlip;
00023     PAPI_address_map_t *tmp = NULL;
00024 
00025     sprintf( fname, "/proc/%d/map", getpid(  ) );
00026     map_f = fopen( fname, "r" );
00027     if ( !map_f ) {
00028         PAPIERROR( "fopen(%s) returned < 0", fname );
00029         return ( PAPI_OK );
00030     }
00031 
00032     /* count the entries we need */
00033     count = 0;
00034     t_index = 0;
00035     while ( fread( &newp, sizeof ( prmap_t ), 1, map_f ) > 0 ) {
00036         vaddr = ( void * ) ( 1 + ( newp.pr_vaddr ) );   // map base address 
00037         if ( dladdr( vaddr, &dlip ) > 0 ) {
00038             count++;
00039             if ( ( newp.pr_mflags & MA_EXEC ) && ( newp.pr_mflags & MA_READ ) ) {
00040                 if ( !( newp.pr_mflags & MA_WRITE ) )
00041                     t_index++;
00042             }
00043             strcpy( name, dlip.dli_fname );
00044             if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name,
00045                          basename( name ) ) == 0 ) {
00046                 if ( ( newp.pr_mflags & MA_EXEC ) &&
00047                      ( newp.pr_mflags & MA_READ ) ) {
00048                     if ( !( newp.pr_mflags & MA_WRITE ) ) {
00049                         _papi_hwi_system_info.exe_info.address_info.text_start =
00050                             ( caddr_t ) newp.pr_vaddr;
00051                         _papi_hwi_system_info.exe_info.address_info.text_end =
00052                             ( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
00053                     } else {
00054                         _papi_hwi_system_info.exe_info.address_info.data_start =
00055                             ( caddr_t ) newp.pr_vaddr;
00056                         _papi_hwi_system_info.exe_info.address_info.data_end =
00057                             ( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
00058                     }
00059                 }
00060             }
00061         }
00062 
00063     }
00064     rewind( map_f );
00065     tmp =
00066         ( PAPI_address_map_t * ) papi_calloc( t_index - 1,
00067                                               sizeof ( PAPI_address_map_t ) );
00068 
00069     if ( tmp == NULL ) {
00070         PAPIERROR( "Error allocating shared library address map" );
00071         return ( PAPI_ENOMEM );
00072     }
00073     t_index = -1;
00074     while ( fread( &newp, sizeof ( prmap_t ), 1, map_f ) > 0 ) {
00075         vaddr = ( void * ) ( 1 + ( newp.pr_vaddr ) );   // map base address
00076         if ( dladdr( vaddr, &dlip ) > 0 ) { // valid name
00077             strcpy( name, dlip.dli_fname );
00078             if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name,
00079                          basename( name ) ) == 0 )
00080                 continue;
00081             if ( ( newp.pr_mflags & MA_EXEC ) && ( newp.pr_mflags & MA_READ ) ) {
00082                 if ( !( newp.pr_mflags & MA_WRITE ) ) {
00083                     t_index++;
00084                     tmp[t_index].text_start = ( caddr_t ) newp.pr_vaddr;
00085                     tmp[t_index].text_end =
00086                         ( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
00087                     strncpy( tmp[t_index].name, dlip.dli_fname,
00088                              PAPI_HUGE_STR_LEN - 1 );
00089                     tmp[t_index].name[PAPI_HUGE_STR_LEN - 1] = '\0';
00090                 } else {
00091                     if ( t_index < 0 )
00092                         continue;
00093                     tmp[t_index].data_start = ( caddr_t ) newp.pr_vaddr;
00094                     tmp[t_index].data_end =
00095                         ( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
00096                 }
00097             }
00098         }
00099     }
00100 
00101     fclose( map_f );
00102 
00103     if ( _papi_hwi_system_info.shlib_info.map )
00104         papi_free( _papi_hwi_system_info.shlib_info.map );
00105     _papi_hwi_system_info.shlib_info.map = tmp;
00106     _papi_hwi_system_info.shlib_info.count = t_index + 1;
00107 
00108     return PAPI_OK;
00109 }
00110 #endif
00111 
00112 
00113 int
00114 _papi_hwi_init_os(void) {
00115 
00116   struct utsname uname_buffer;
00117 
00118   uname(&uname_buffer);
00119 
00120   strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);
00121 
00122   strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
00123 
00124   _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
00125   _papi_os_info.itimer_num = PAPI_INT_ITIMER;
00126   _papi_os_info.itimer_ns = PAPI_INT_MPX_DEF_US * 1000;
00127   _papi_os_info.itimer_res_ns = 1;
00128 
00129   return PAPI_OK;
00130 }
00131 
00132 #if 0
00133 int
00134 _ultra_hwd_update_shlib_info( papi_mdi_t *mdi )
00135 {
00136     /*??? system call takes very long */
00137 
00138     char cmd_line[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], fname[L_tmpnam];
00139     char line[256];
00140     char address[16], size[10], flags[64], objname[256];
00141     PAPI_address_map_t *tmp = NULL;
00142 
00143     FILE *f = NULL;
00144     int t_index = 0, i;
00145     struct map_record
00146     {
00147         long address;
00148         int size;
00149         int flags;
00150         char objname[256];
00151         struct map_record *next;
00152     } *tmpr, *head, *curr;
00153 
00154     tmpnam( fname );
00155     SUBDBG( "Temporary name %s\n", fname );
00156 
00157     sprintf( cmd_line, "/bin/pmap %d > %s", ( int ) getpid(  ), fname );
00158     if ( system( cmd_line ) != 0 ) {
00159         PAPIERROR( "Could not run %s to get shared library address map",
00160                    cmd_line );
00161         return ( PAPI_OK );
00162     }
00163 
00164     f = fopen( fname, "r" );
00165     if ( f == NULL ) {
00166         PAPIERROR( "fopen(%s) returned < 0", fname );
00167         remove( fname );
00168         return ( PAPI_OK );
00169     }
00170 
00171     /* ignore the first line */
00172     fgets( line, 256, f );
00173     head = curr = NULL;
00174     while ( fgets( line, 256, f ) != NULL ) {
00175         /* discard the last line */
00176         if ( strncmp( line, " total", 6 ) != 0 ) {
00177             sscanf( line, "%s %s %s %s", address, size, flags, objname );
00178             if ( objname[0] == '/' ) {
00179                 tmpr =
00180                     ( struct map_record * )
00181                     papi_malloc( sizeof ( struct map_record ) );
00182                 if ( tmpr == NULL )
00183                     return ( -1 );
00184                 tmpr->next = NULL;
00185                 if ( curr ) {
00186                     curr->next = tmpr;
00187                     curr = tmpr;
00188                 }
00189                 if ( head == NULL ) {
00190                     curr = head = tmpr;
00191                 }
00192 
00193                 SUBDBG( "%s\n", objname );
00194 
00195                 if ( ( strstr( flags, "read" ) && strstr( flags, "exec" ) ) ||
00196                      ( strstr( flags, "r" ) && strstr( flags, "x" ) ) ) {
00197                     if ( !( strstr( flags, "write" ) || strstr( flags, "w" ) ) ) {  /* text segment */
00198                         t_index++;
00199                         tmpr->flags = 1;
00200                     } else {
00201                         tmpr->flags = 0;
00202                     }
00203                     sscanf( address, "%lx", &tmpr->address );
00204                     sscanf( size, "%d", &tmpr->size );
00205                     tmpr->size *= 1024;
00206                     strcpy( tmpr->objname, objname );
00207                 }
00208 
00209             }
00210 
00211         }
00212     }
00213     tmp =
00214         ( PAPI_address_map_t * ) papi_calloc( t_index - 1,
00215                                               sizeof ( PAPI_address_map_t ) );
00216 
00217     if ( tmp == NULL ) {
00218         PAPIERROR( "Error allocating shared library address map" );
00219         return ( PAPI_ENOMEM );
00220     }
00221 
00222     t_index = -1;
00223     tmpr = curr = head;
00224     i = 0;
00225     while ( curr != NULL ) {
00226         if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name,
00227                      basename( curr->objname ) ) == 0 ) {
00228             if ( curr->flags ) {
00229                 _papi_hwi_system_info.exe_info.address_info.text_start =
00230                     ( caddr_t ) curr->address;
00231                 _papi_hwi_system_info.exe_info.address_info.text_end =
00232                     ( caddr_t ) ( curr->address + curr->size );
00233             } else {
00234                 _papi_hwi_system_info.exe_info.address_info.data_start =
00235                     ( caddr_t ) curr->address;
00236                 _papi_hwi_system_info.exe_info.address_info.data_end =
00237                     ( caddr_t ) ( curr->address + curr->size );
00238             }
00239         } else {
00240             if ( curr->flags ) {
00241                 t_index++;
00242                 tmp[t_index].text_start = ( caddr_t ) curr->address;
00243                 tmp[t_index].text_end =
00244                     ( caddr_t ) ( curr->address + curr->size );
00245                 strncpy( tmp[t_index].name, curr->objname,
00246                          PAPI_HUGE_STR_LEN - 1 );
00247                 tmp[t_index].name[PAPI_HUGE_STR_LEN - 1] = '\0';
00248             } else {
00249                 if ( t_index < 0 )
00250                     continue;
00251                 tmp[t_index].data_start = ( caddr_t ) curr->address;
00252                 tmp[t_index].data_end =
00253                     ( caddr_t ) ( curr->address + curr->size );
00254             }
00255         }
00256         tmpr = curr->next;
00257         /* free the temporary allocated memory */
00258         papi_free( curr );
00259         curr = tmpr;
00260     }                        /* end of while */
00261 
00262     remove( fname );
00263     fclose( f );
00264     if ( _papi_hwi_system_info.shlib_info.map )
00265         papi_free( _papi_hwi_system_info.shlib_info.map );
00266     _papi_hwi_system_info.shlib_info.map = tmp;
00267     _papi_hwi_system_info.shlib_info.count = t_index + 1;
00268 
00269     return ( PAPI_OK );
00270 
00271 }
00272 
00273 #endif
00274 
00275 /* From niagara2 code */
00276 int
00277 _solaris_update_shlib_info( papi_mdi_t *mdi )
00278 {
00279     char *file = "/proc/self/map";
00280     char *resolve_pattern = "/proc/self/path/%s";
00281 
00282     char lastobject[PRMAPSZ];
00283     char link[PAPI_HUGE_STR_LEN];
00284     char path[PAPI_HUGE_STR_LEN];
00285 
00286     prmap_t mapping;
00287 
00288     int fd, count = 0, total = 0, position = -1, first = 1;
00289     caddr_t t_min, t_max, d_min, d_max;
00290 
00291     PAPI_address_map_t *pam, *cur;
00292 
00293 #ifdef DEBUG
00294     SUBDBG( "ENTERING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
00295             __LINE__ );
00296 #endif
00297 
00298     fd = open( file, O_RDONLY );
00299 
00300     if ( fd == -1 ) {
00301         return PAPI_ESYS;
00302     }
00303 
00304     memset( lastobject, 0, PRMAPSZ );
00305 
00306 #ifdef DEBUG
00307     SUBDBG( " -> %s: Preprocessing memory maps from procfs\n", __func__ );
00308 #endif
00309 
00310     /* Search through the list of mappings in order to identify a) how many
00311        mappings are available and b) how many unique mappings are available. */
00312     while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
00313 #ifdef DEBUG
00314         SUBDBG( " -> %s: Found a new memory map entry\n", __func__ );
00315 #endif
00316         /* Another entry found, just the total count of entries. */
00317         total++;
00318 
00319         /* Is the mapping accessible and not anonymous? */
00320         if ( mapping.pr_mflags & ( MA_READ | MA_WRITE | MA_EXEC ) &&
00321              !( mapping.pr_mflags & MA_ANON ) ) {
00322             /* Test if a new library has been found. If a new library has been
00323                found a new entry needs to be counted. */
00324             if ( strcmp( lastobject, mapping.pr_mapname ) != 0 ) {
00325                 strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
00326                 count++;
00327 
00328 #ifdef DEBUG
00329                 SUBDBG( " -> %s: Memory mapping entry valid for %s\n", __func__,
00330                         mapping.pr_mapname );
00331 #endif
00332             }
00333         }
00334     }
00335 #ifdef DEBUG
00336     SUBDBG( " -> %s: Preprocessing done, starting to analyze\n", __func__ );
00337 #endif
00338 
00339 
00340     /* Start from the beginning, now fill in the found mappings */
00341     if ( lseek( fd, 0, SEEK_SET ) == -1 ) {
00342         return PAPI_ESYS;
00343     }
00344 
00345     memset( lastobject, 0, PRMAPSZ );
00346 
00347     /* Allocate memory */
00348     pam =
00349         ( PAPI_address_map_t * ) papi_calloc( count,
00350                                               sizeof ( PAPI_address_map_t ) );
00351 
00352     while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
00353 
00354         if ( mapping.pr_mflags & MA_ANON ) {
00355 #ifdef DEBUG
00356             SUBDBG
00357                 ( " -> %s: Anonymous mapping (MA_ANON) found for %s, skipping\n",
00358                   __func__, mapping.pr_mapname );
00359 #endif
00360             continue;
00361         }
00362 
00363         /* Check for a new entry */
00364         if ( strcmp( mapping.pr_mapname, lastobject ) != 0 ) {
00365 #ifdef DEBUG
00366             SUBDBG( " -> %s: Analyzing mapping for %s\n", __func__,
00367                     mapping.pr_mapname );
00368 #endif
00369             cur = &( pam[++position] );
00370             strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
00371             snprintf( link, PAPI_HUGE_STR_LEN, resolve_pattern, lastobject );
00372             memset( path, 0, PAPI_HUGE_STR_LEN );
00373             readlink( link, path, PAPI_HUGE_STR_LEN );
00374             strncpy( cur->name, path, PAPI_HUGE_STR_LEN );
00375 #ifdef DEBUG
00376             SUBDBG( " -> %s: Resolved name for %s: %s\n", __func__,
00377                     mapping.pr_mapname, cur->name );
00378 #endif
00379         }
00380 
00381         if ( mapping.pr_mflags & MA_READ ) {
00382             /* Data (MA_WRITE) or text (MA_READ) segment? */
00383             if ( mapping.pr_mflags & MA_WRITE ) {
00384                 cur->data_start = ( caddr_t ) mapping.pr_vaddr;
00385                 cur->data_end =
00386                     ( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
00387 
00388                 if ( strcmp
00389                      ( cur->name,
00390                        _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
00391                     _papi_hwi_system_info.exe_info.address_info.data_start =
00392                         cur->data_start;
00393                     _papi_hwi_system_info.exe_info.address_info.data_end =
00394                         cur->data_end;
00395                 }
00396 
00397                 if ( first )
00398                     d_min = cur->data_start;
00399                 if ( first )
00400                     d_max = cur->data_end;
00401 
00402                 if ( cur->data_start < d_min ) {
00403                     d_min = cur->data_start;
00404                 }
00405 
00406                 if ( cur->data_end > d_max ) {
00407                     d_max = cur->data_end;
00408                 }
00409             } else if ( mapping.pr_mflags & MA_EXEC ) {
00410                 cur->text_start = ( caddr_t ) mapping.pr_vaddr;
00411                 cur->text_end =
00412                     ( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
00413 
00414                 if ( strcmp
00415                      ( cur->name,
00416                        _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
00417                     _papi_hwi_system_info.exe_info.address_info.text_start =
00418                         cur->text_start;
00419                     _papi_hwi_system_info.exe_info.address_info.text_end =
00420                         cur->text_end;
00421                 }
00422 
00423                 if ( first )
00424                     t_min = cur->text_start;
00425                 if ( first )
00426                     t_max = cur->text_end;
00427 
00428                 if ( cur->text_start < t_min ) {
00429                     t_min = cur->text_start;
00430                 }
00431 
00432                 if ( cur->text_end > t_max ) {
00433                     t_max = cur->text_end;
00434                 }
00435             }
00436         }
00437 
00438         first = 0;
00439     }
00440 
00441     close( fd );
00442 
00443     /* During the walk of shared objects the upper and lower bound of the
00444        segments could be discovered. The bounds are stored in the PAPI info
00445        structure. The information is important for the profiling functions of
00446        PAPI. */
00447 
00448 /* This variant would pass the addresses of all text and data segments 
00449   _papi_hwi_system_info.exe_info.address_info.text_start = t_min;
00450   _papi_hwi_system_info.exe_info.address_info.text_end = t_max;
00451   _papi_hwi_system_info.exe_info.address_info.data_start = d_min;
00452   _papi_hwi_system_info.exe_info.address_info.data_end = d_max;
00453 */
00454 
00455 #ifdef DEBUG
00456     SUBDBG( " -> %s: Analysis of memory maps done, results:\n", __func__ );
00457     SUBDBG( " -> %s: text_start=%x, text_end=%x, text_size=%lld\n", __func__,
00458             _papi_hwi_system_info.exe_info.address_info.text_start,
00459             _papi_hwi_system_info.exe_info.address_info.text_end,
00460             _papi_hwi_system_info.exe_info.address_info.text_end
00461             - _papi_hwi_system_info.exe_info.address_info.text_start );
00462     SUBDBG( " -> %s: data_start=%x, data_end=%x, data_size=%lld\n", __func__,
00463             _papi_hwi_system_info.exe_info.address_info.data_start,
00464             _papi_hwi_system_info.exe_info.address_info.data_end,
00465             _papi_hwi_system_info.exe_info.address_info.data_end
00466             - _papi_hwi_system_info.exe_info.address_info.data_start );
00467 #endif
00468 
00469     /* Store the map read and the total count of shlibs found */
00470     _papi_hwi_system_info.shlib_info.map = pam;
00471     _papi_hwi_system_info.shlib_info.count = count;
00472 
00473 #ifdef DEBUG
00474     SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
00475             __LINE__ );
00476 #endif
00477 
00478     return PAPI_OK;
00479 }
00480 
00481 #if 0
00482 int
00483 _niagara2_get_system_info( papi_mdi_t *mdi )
00484 {
00485     // Used for evaluating return values
00486     int retval = 0;
00487     // Check for process settings
00488     pstatus_t *proc_status;
00489     psinfo_t *proc_info;
00490     // Used for string truncating
00491     char *c_ptr;
00492     // For retrieving the executable full name
00493     char exec_name[PAPI_HUGE_STR_LEN];
00494     // For retrieving processor information
00495     __sol_processor_information_t cpus;
00496 
00497 #ifdef DEBUG
00498     SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
00499             __LINE__ );
00500 #endif
00501 
00502     /* Get and set pid */
00503     pid = getpid(  );
00504 
00505     /* Check for microstate accounting */
00506     proc_status = __sol_get_proc_status( pid );
00507 
00508     if ( proc_status->pr_flags & PR_MSACCT == 0 ||
00509          proc_status->pr_flags & PR_MSFORK == 0 ) {
00510         /* Solaris 10 should have microstate accounting always activated */
00511         return PAPI_ECMP;
00512     }
00513 
00514     /* Fill _papi_hwi_system_info.exe_info.fullname */
00515     proc_info = __sol_get_proc_info( pid );
00516 
00517     // If there are arguments, trim the string to the executable name.
00518     if ( proc_info->pr_argc > 1 ) {
00519         c_ptr = strchr( proc_info->pr_psargs, ' ' );
00520         if ( c_ptr != NULL )
00521             c_ptr = '\0';
00522     }
00523 
00524     /* If the path can be qualified, use the full path, otherwise the trimmed
00525        name. */
00526     if ( realpath( proc_info->pr_psargs, exec_name ) != NULL ) {
00527         strncpy( _papi_hwi_system_info.exe_info.fullname, exec_name,
00528                  PAPI_HUGE_STR_LEN );
00529     } else {
00530         strncpy( _papi_hwi_system_info.exe_info.fullname, proc_info->pr_psargs,
00531                  PAPI_HUGE_STR_LEN );
00532     }
00533 
00534     /* Fill _papi_hwi_system_info.exe_info.address_info */
00535     // Taken from the old component
00536     strncpy( _papi_hwi_system_info.exe_info.address_info.name,
00537              basename( _papi_hwi_system_info.exe_info.fullname ),
00538              PAPI_HUGE_STR_LEN );
00539     __CHECK_ERR_PAPI( _niagara2_update_shlib_info( &_papi_hwi_system_info ) );
00540 
00541     /* Fill _papi_hwi_system_info.hw_info */
00542 
00543     // Taken from the old component
00544     _papi_hwi_system_info.hw_info.ncpu = sysconf( _SC_NPROCESSORS_ONLN );
00545     _papi_hwi_system_info.hw_info.nnodes = 1;
00546     _papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_SUN;
00547     strcpy( _papi_hwi_system_info.hw_info.vendor_string, "SUN" );
00548     _papi_hwi_system_info.hw_info.totalcpus = sysconf( _SC_NPROCESSORS_CONF );
00549     _papi_hwi_system_info.hw_info.model = 1;
00550     strcpy( _papi_hwi_system_info.hw_info.model_string, cpc_cciname( cpc ) );
00551 
00552     /* The field sparc-version is no longer in prtconf -pv */
00553     _papi_hwi_system_info.hw_info.revision = 1;
00554 
00555     /* Clock speed */
00556     _papi_hwi_system_info.hw_info.mhz = ( float ) __sol_get_processor_clock(  );
00557     _papi_hwi_system_info.hw_info.clock_mhz = __sol_get_processor_clock(  );
00558     _papi_hwi_system_info.hw_info.cpu_max_mhz = __sol_get_processor_clock(  );
00559     _papi_hwi_system_info.hw_info.cpu_min_mhz = __sol_get_processor_clock(  );
00560 
00561     /* Fill _niagara2_vector.cmp_info.mem_hierarchy */
00562 
00563     _niagara2_get_memory_info( &_papi_hwi_system_info.hw_info, 0 );
00564 
00565     /* Fill _papi_hwi_system_info.sub_info */
00566     strcpy( _niagara2_vector.cmp_info.name, "SunNiagara2" );
00567     strcpy( _niagara2_vector.cmp_info.version, "ALPHA" );
00568     strcpy( _niagara2_vector.cmp_info.support_version, "libcpc2" );
00569     strcpy( _niagara2_vector.cmp_info.kernel_version, "libcpc2" );
00570 
00571     /* libcpc2 uses SIGEMT using real hardware signals, no sw emu */
00572 
00573 #ifdef DEBUG
00574     SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
00575             __LINE__ );
00576 #endif
00577 
00578     return PAPI_OK;
00579 }
00580 
00581 #endif
00582 
00583 int
00584 _solaris_get_system_info( papi_mdi_t *mdi )
00585 {
00586     int retval;
00587     pid_t pid;
00588     char maxargs[PAPI_MAX_STR_LEN] = "<none>";
00589     psinfo_t psi;
00590     int fd;
00591     int hz, version;
00592     char cpuname[PAPI_MAX_STR_LEN], pname[PAPI_HUGE_STR_LEN];
00593 
00594     /* Check counter access */
00595 
00596     if ( cpc_version( CPC_VER_CURRENT ) != CPC_VER_CURRENT )
00597         return PAPI_ECMP;
00598     SUBDBG( "CPC version %d successfully opened\n", CPC_VER_CURRENT );
00599 
00600     if ( cpc_access(  ) == -1 )
00601         return PAPI_ECMP;
00602 
00603     /* Global variable cpuver */
00604 
00605     cpuver = cpc_getcpuver(  );
00606     SUBDBG( "Got %d from cpc_getcpuver()\n", cpuver );
00607     if ( cpuver == -1 )
00608         return PAPI_ECMP;
00609 
00610 #ifdef DEBUG
00611     {
00612         if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
00613             const char *name;
00614             int i;
00615 
00616             name = cpc_getcpuref( cpuver );
00617             if ( name ) {
00618                 SUBDBG( "CPC CPU reference: %s\n", name );
00619             }
00620             else {
00621                 SUBDBG( "Could not get a CPC CPU reference\n" );
00622             }
00623 
00624             for ( i = 0; i < cpc_getnpic( cpuver ); i++ ) {
00625                 SUBDBG( "\n%6s %-40s %8s\n", "Reg", "Symbolic name", "Code" );
00626                 cpc_walk_names( cpuver, i, "%6d %-40s %02x\n",
00627                                 print_walk_names );
00628             }
00629             SUBDBG( "\n" );
00630         }
00631     }
00632 #endif
00633 
00634 
00635     /* Initialize other globals */
00636 
00637     if ( ( retval = build_tables(  ) ) != PAPI_OK )
00638         return retval;
00639 
00640     preset_search_map = preset_table;
00641     if ( cpuver <= CPC_ULTRA2 ) {
00642         SUBDBG( "cpuver (==%d) <= CPC_ULTRA2 (==%d)\n", cpuver, CPC_ULTRA2 );
00643         pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
00644         pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
00645     } else if ( cpuver <= LASTULTRA3 ) {
00646         SUBDBG( "cpuver (==%d) <= CPC_ULTRA3x (==%d)\n", cpuver, LASTULTRA3 );
00647         pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
00648         pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
00649         _solaris_vector.cmp_info.hardware_intr = 1;
00650         _solaris_vector.cmp_info.hardware_intr_sig = SIGEMT;
00651     } else
00652         return PAPI_ECMP;
00653 
00654     /* Path and args */
00655 
00656     pid = getpid(  );
00657     if ( pid == -1 )
00658         return ( PAPI_ESYS );
00659 
00660     /* Turn on microstate accounting for this process and any LWPs. */
00661 
00662     sprintf( maxargs, "/proc/%d/ctl", ( int ) pid );
00663     if ( ( fd = open( maxargs, O_WRONLY ) ) == -1 )
00664         return ( PAPI_ESYS );
00665     {
00666         int retval;
00667         struct
00668         {
00669             long cmd;
00670             long flags;
00671         } cmd;
00672         cmd.cmd = PCSET;
00673         cmd.flags = PR_MSACCT | PR_MSFORK;
00674         retval = write( fd, &cmd, sizeof ( cmd ) );
00675         close( fd );
00676         SUBDBG( "Write PCSET returned %d\n", retval );
00677         if ( retval != sizeof ( cmd ) )
00678             return ( PAPI_ESYS );
00679     }
00680 
00681     /* Get executable info */
00682 
00683     sprintf( maxargs, "/proc/%d/psinfo", ( int ) pid );
00684     if ( ( fd = open( maxargs, O_RDONLY ) ) == -1 )
00685         return ( PAPI_ESYS );
00686     read( fd, &psi, sizeof ( psi ) );
00687     close( fd );
00688 
00689     /* Cut off any arguments to exe */
00690     {
00691         char *tmp;
00692         tmp = strchr( psi.pr_psargs, ' ' );
00693         if ( tmp != NULL )
00694             *tmp = '\0';
00695     }
00696 
00697     if ( realpath( psi.pr_psargs, pname ) )
00698         strncpy( _papi_hwi_system_info.exe_info.fullname, pname,
00699                  PAPI_HUGE_STR_LEN );
00700     else
00701         strncpy( _papi_hwi_system_info.exe_info.fullname, psi.pr_psargs,
00702                  PAPI_HUGE_STR_LEN );
00703 
00704     /* please don't use pr_fname here, because it can only store less that 
00705        16 characters */
00706     strcpy( _papi_hwi_system_info.exe_info.address_info.name,
00707             basename( _papi_hwi_system_info.exe_info.fullname ) );
00708 
00709     SUBDBG( "Full Executable is %s\n",
00710             _papi_hwi_system_info.exe_info.fullname );
00711 
00712     /* Executable regions, reading /proc/pid/maps file */
00713     retval = _ultra_hwd_update_shlib_info( &_papi_hwi_system_info );
00714 
00715     /* Hardware info */
00716 
00717     _papi_hwi_system_info.hw_info.ncpu = sysconf( _SC_NPROCESSORS_ONLN );
00718     _papi_hwi_system_info.hw_info.nnodes = 1;
00719     _papi_hwi_system_info.hw_info.totalcpus = sysconf( _SC_NPROCESSORS_CONF );
00720 
00721     retval = scan_prtconf( cpuname, PAPI_MAX_STR_LEN, &hz, &version );
00722     if ( retval == -1 )
00723         return PAPI_ECMP;
00724 
00725     strcpy( _papi_hwi_system_info.hw_info.model_string,
00726             cpc_getcciname( cpuver ) );
00727     _papi_hwi_system_info.hw_info.model = cpuver;
00728     strcpy( _papi_hwi_system_info.hw_info.vendor_string, "SUN" );
00729     _papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_SUN;
00730     _papi_hwi_system_info.hw_info.revision = version;
00731 
00732     _papi_hwi_system_info.hw_info.mhz = ( ( float ) hz / 1.0e6 );
00733     SUBDBG( "hw_info.mhz = %f\n", _papi_hwi_system_info.hw_info.mhz );
00734 
00735     _papi_hwi_system_info.hw_info.cpu_max_mhz = _papi_hwi_system_info.hw_info.mhz;
00736     _papi_hwi_system_info.hw_info.cpu_min_mhz = _papi_hwi_system_info.hw_info.mhz;
00737 
00738 
00739     /* Number of PMCs */
00740 
00741     retval = cpc_getnpic( cpuver );
00742     if ( retval < 0 )
00743         return PAPI_ECMP;
00744 
00745     _solaris_vector.cmp_info.num_cntrs = retval;
00746     _solaris_vector.cmp_info.fast_real_timer = 1;
00747     _solaris_vector.cmp_info.fast_virtual_timer = 1;
00748     _solaris_vector.cmp_info.default_domain = PAPI_DOM_USER;
00749     _solaris_vector.cmp_info.available_domains =
00750         PAPI_DOM_USER | PAPI_DOM_KERNEL;
00751 
00752     /* Setup presets */
00753 
00754     retval = _papi_hwi_setup_all_presets( preset_search_map, NULL );
00755     if ( retval )
00756         return ( retval );
00757 
00758     return ( PAPI_OK );
00759 }
00760 
00761 
00762 long long
00763 _solaris_get_real_usec( void )
00764 {
00765     return ( ( long long ) gethrtime(  ) / ( long long ) 1000 );
00766 }
00767 
00768 long long
00769 _solaris_get_real_cycles( void )
00770 {
00771     return ( _ultra_hwd_get_real_usec(  ) *
00772              ( long long ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
00773 }
00774 
00775 long long
00776 _solaris_get_virt_usec( void )
00777 {
00778     return ( ( long long ) gethrvtime(  ) / ( long long ) 1000 );
00779 }
00780 
00781 
00782 
00783 
00784 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines