|
PAPI
5.0.1.0
|
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