solaris-common.c File Reference

Include dependency graph for solaris-common.c:

Go to the source code of this file.

Functions

int _papi_hwi_init_os (void)
int _solaris_update_shlib_info (papi_mdi_t *mdi)
int _solaris_get_system_info (papi_mdi_t *mdi)
long long _solaris_get_real_usec (void)
long long _solaris_get_real_cycles (void)
long long _solaris_get_virt_usec (void)

Function Documentation

int _papi_hwi_init_os ( void   ) 

Definition at line 114 of file solaris-common.c.

00114                         {
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 }

long long _solaris_get_real_cycles ( void   ) 

Definition at line 769 of file solaris-common.c.

00770 {
00771     return ( _ultra_hwd_get_real_usec(  ) *
00772              ( long long ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
00773 }

long long _solaris_get_real_usec ( void   ) 

Definition at line 763 of file solaris-common.c.

00764 {
00765     return ( ( long long ) gethrtime(  ) / ( long long ) 1000 );
00766 }

int _solaris_get_system_info ( papi_mdi_t mdi  ) 

Definition at line 584 of file solaris-common.c.

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

long long _solaris_get_virt_usec ( void   ) 

Definition at line 776 of file solaris-common.c.

00777 {
00778     return ( ( long long ) gethrvtime(  ) / ( long long ) 1000 );
00779 }

int _solaris_update_shlib_info ( papi_mdi_t mdi  ) 

Definition at line 277 of file solaris-common.c.

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 }

Here is the call graph for this function:


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1