PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-memory.c File Reference
Include dependency graph for linux-memory.c:

Go to the source code of this file.

Functions

int generic_get_memory_info (PAPI_hw_info_t *hw_info)
 
int _linux_get_dmem_info (PAPI_dmem_info_t *d)
 
int _linux_get_memory_info (PAPI_hw_info_t *hwinfo, int cpu_type)
 
int _linux_update_shlib_info (papi_mdi_t *mdi)
 

Function Documentation

◆ _linux_get_dmem_info()

int _linux_get_dmem_info ( PAPI_dmem_info_t d)

Definition at line 50 of file linux-memory.c.

51{
52 char fn[PATH_MAX], tmp[PATH_MAX];
53 FILE *f;
54 int ret;
55 long long sz = 0, lck = 0, res = 0, shr = 0, stk = 0, txt = 0, dat =
56 0, dum = 0, lib = 0, hwm = 0;
57
58 sprintf( fn, "/proc/%ld/status", ( long ) getpid( ) );
59 f = fopen( fn, "r" );
60 if ( f == NULL ) {
61 PAPIERROR( "fopen(%s): %s\n", fn, strerror( errno ) );
62 return PAPI_ESYS;
63 }
64 while ( 1 ) {
65 if ( fgets( tmp, PATH_MAX, f ) == NULL )
66 break;
67 if ( strspn( tmp, "VmSize:" ) == strlen( "VmSize:" ) ) {
68 sscanf( tmp + strlen( "VmSize:" ), "%lld", &sz );
69 d->size = sz;
70 continue;
71 }
72 if ( strspn( tmp, "VmHWM:" ) == strlen( "VmHWM:" ) ) {
73 sscanf( tmp + strlen( "VmHWM:" ), "%lld", &hwm );
74 d->high_water_mark = hwm;
75 continue;
76 }
77 if ( strspn( tmp, "VmLck:" ) == strlen( "VmLck:" ) ) {
78 sscanf( tmp + strlen( "VmLck:" ), "%lld", &lck );
79 d->locked = lck;
80 continue;
81 }
82 if ( strspn( tmp, "VmRSS:" ) == strlen( "VmRSS:" ) ) {
83 sscanf( tmp + strlen( "VmRSS:" ), "%lld", &res );
84 d->resident = res;
85 continue;
86 }
87 if ( strspn( tmp, "VmData:" ) == strlen( "VmData:" ) ) {
88 sscanf( tmp + strlen( "VmData:" ), "%lld", &dat );
89 d->heap = dat;
90 continue;
91 }
92 if ( strspn( tmp, "VmStk:" ) == strlen( "VmStk:" ) ) {
93 sscanf( tmp + strlen( "VmStk:" ), "%lld", &stk );
94 d->stack = stk;
95 continue;
96 }
97 if ( strspn( tmp, "VmExe:" ) == strlen( "VmExe:" ) ) {
98 sscanf( tmp + strlen( "VmExe:" ), "%lld", &txt );
99 d->text = txt;
100 continue;
101 }
102 if ( strspn( tmp, "VmLib:" ) == strlen( "VmLib:" ) ) {
103 sscanf( tmp + strlen( "VmLib:" ), "%lld", &lib );
104 d->library = lib;
105 continue;
106 }
107 }
108 fclose( f );
109
110 sprintf( fn, "/proc/%ld/statm", ( long ) getpid( ) );
111 f = fopen( fn, "r" );
112 if ( f == NULL ) {
113 PAPIERROR( "fopen(%s): %s\n", fn, strerror( errno ) );
114 return PAPI_ESYS;
115 }
116 ret =
117 fscanf( f, "%lld %lld %lld %lld %lld %lld %lld", &dum, &dum, &shr, &dum,
118 &dum, &dat, &dum );
119 if ( ret != 7 ) {
120 PAPIERROR( "fscanf(7 items): %d\n", ret );
121 fclose(f);
122 return PAPI_ESYS;
123 }
124 d->pagesize = getpagesize( );
125 d->shared = ( shr * d->pagesize ) / 1024;
126 fclose( f );
127
128 return PAPI_OK;
129}
double tmp
int errno
double f(double a)
Definition: cpi.c:23
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ESYS
Definition: f90papi.h:136
int fclose(FILE *__stream)
void PAPIERROR(char *format,...)
long long locked
Definition: papi.h:874
long long shared
Definition: papi.h:870
long long text
Definition: papi.h:871
long long heap
Definition: papi.h:873
long long size
Definition: papi.h:867
long long library
Definition: papi.h:872
long long stack
Definition: papi.h:875
long long pagesize
Definition: papi.h:876
long long high_water_mark
Definition: papi.h:869
long long resident
Definition: papi.h:868
Here is the call graph for this function:

◆ _linux_get_memory_info()

int _linux_get_memory_info ( PAPI_hw_info_t hwinfo,
int  cpu_type 
)

Definition at line 1454 of file linux-memory.c.

1455{
1456 ( void ) cpu_type; /*unused */
1457 int retval = PAPI_OK;
1458
1459#if defined(__i386__)||defined(__x86_64__)
1460 x86_get_memory_info( hwinfo );
1461#elif defined(__ia64__)
1462 ia64_get_memory_info( hwinfo );
1463#elif defined(__powerpc__)
1464 ppc64_get_memory_info( hwinfo );
1465#elif defined(__sparc__)
1466 sparc_get_memory_info( hwinfo );
1467#elif defined(__arm__)
1468 #warning "WARNING! linux_get_memory_info() does nothing on ARM32!"
1469 generic_get_memory_info (hwinfo);
1470#elif defined(__aarch64__)
1471 aarch64_get_memory_info( hwinfo );
1472#else
1473 generic_get_memory_info (hwinfo);
1474#endif
1475
1476 return retval;
1477}
int generic_get_memory_info(PAPI_hw_info_t *hw_info)
int retval
Definition: zero_fork.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _linux_update_shlib_info()

int _linux_update_shlib_info ( papi_mdi_t mdi)

Definition at line 1480 of file linux-memory.c.

1481{
1482
1483 char fname[PAPI_HUGE_STR_LEN];
1484 unsigned long t_index = 0, d_index = 0, b_index = 0, counting = 1;
1485 char buf[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], perm[5], dev[16];
1486 char mapname[PAPI_HUGE_STR_LEN], lastmapname[PAPI_HUGE_STR_LEN];
1487 unsigned long begin = 0, end = 0, size = 0, inode = 0, foo = 0;
1488 PAPI_address_map_t *tmp = NULL;
1489 FILE *f;
1490
1491 memset( fname, 0x0, sizeof ( fname ) );
1492 memset( buf, 0x0, sizeof ( buf ) );
1493 memset( perm, 0x0, sizeof ( perm ) );
1494 memset( dev, 0x0, sizeof ( dev ) );
1495 memset( mapname, 0x0, sizeof ( mapname ) );
1496 memset( lastmapname, 0x0, sizeof ( lastmapname ) );
1497
1498 sprintf( fname, "/proc/%ld/maps", ( long ) mdi->pid );
1499 f = fopen( fname, "r" );
1500
1501 if ( !f ) {
1502 PAPIERROR( "fopen(%s) returned < 0", fname );
1503 return PAPI_OK;
1504 }
1505
1506 again:
1507 while ( !feof( f ) ) {
1508 begin = end = size = inode = foo = 0;
1509 if ( fgets( buf, sizeof ( buf ), f ) == 0 )
1510 break;
1511 /* If mapname is null in the string to be scanned, we need to detect that */
1512 if ( strlen( mapname ) )
1513 strcpy( lastmapname, mapname );
1514 else
1515 lastmapname[0] = '\0';
1516 /* If mapname is null in the string to be scanned, we need to detect that */
1517 mapname[0] = '\0';
1518 sscanf( buf, "%lx-%lx %4s %lx %s %ld %s", &begin, &end, perm, &foo, dev,
1519 &inode, mapname );
1520 size = end - begin;
1521
1522 /* the permission string looks like "rwxp", where each character can
1523 * be either the letter, or a hyphen. The final character is either
1524 * p for private or s for shared. */
1525
1526 if ( counting ) {
1527 if ( ( perm[2] == 'x' ) && ( perm[0] == 'r' ) && ( inode != 0 ) ) {
1528 if ( strcmp( mdi->exe_info.fullname, mapname )
1529 == 0 ) {
1531 ( vptr_t ) begin;
1533 ( vptr_t ) ( begin + size );
1534 }
1535 t_index++;
1536 } else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
1537 ( inode != 0 )
1538 &&
1539 ( strcmp
1540 ( mdi->exe_info.fullname,
1541 mapname ) == 0 ) ) {
1543 ( vptr_t ) begin;
1545 ( vptr_t ) ( begin + size );
1546 d_index++;
1547 } else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
1548 ( inode == 0 )
1549 &&
1550 ( strcmp
1551 ( mdi->exe_info.fullname,
1552 lastmapname ) == 0 ) ) {
1554 ( vptr_t ) begin;
1556 ( vptr_t ) ( begin + size );
1557 b_index++;
1558 }
1559 } else if ( !counting ) {
1560 if ( ( perm[2] == 'x' ) && ( perm[0] == 'r' ) && ( inode != 0 ) ) {
1561 if ( strcmp( mdi->exe_info.fullname, mapname )
1562 != 0 ) {
1563 t_index++;
1564 tmp[t_index - 1].text_start = ( vptr_t ) begin;
1565 tmp[t_index - 1].text_end = ( vptr_t ) ( begin + size );
1566 strncpy( tmp[t_index - 1].name, mapname, PAPI_HUGE_STR_LEN );
1567 tmp[t_index - 1].name[PAPI_HUGE_STR_LEN-1]=0;
1568 }
1569 } else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
1570 ( inode != 0 ) ) {
1571 if ( ( strcmp
1572 ( mdi->exe_info.fullname,
1573 mapname ) != 0 )
1574 && ( t_index > 0 ) &&
1575 ( tmp[t_index - 1].data_start == 0 ) ) {
1576 tmp[t_index - 1].data_start = ( vptr_t ) begin;
1577 tmp[t_index - 1].data_end = ( vptr_t ) ( begin + size );
1578 }
1579 } else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
1580 ( inode == 0 ) ) {
1581 if ( ( t_index > 0 ) && ( tmp[t_index - 1].bss_start == 0 ) ) {
1582 tmp[t_index - 1].bss_start = ( vptr_t ) begin;
1583 tmp[t_index - 1].bss_end = ( vptr_t ) ( begin + size );
1584 }
1585 }
1586 }
1587 }
1588
1589 if ( counting ) {
1590 /* When we get here, we have counted the number of entries in the map
1591 for us to allocate */
1592
1593 tmp =
1594 ( PAPI_address_map_t * ) papi_calloc( t_index,
1595 sizeof
1596 ( PAPI_address_map_t ) );
1597 if ( tmp == NULL ) {
1598 PAPIERROR( "Error allocating shared library address map" );
1599 fclose(f);
1600 return PAPI_ENOMEM;
1601 }
1602 t_index = 0;
1603 rewind( f );
1604 counting = 0;
1605 goto again;
1606 } else {
1607 if ( mdi->shlib_info.map )
1608 papi_free( mdi->shlib_info.map );
1609 mdi->shlib_info.map = tmp;
1610 mdi->shlib_info.count = t_index;
1611
1612 fclose( f );
1613 }
1614
1615 return PAPI_OK;
1616}
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
Definition: do_loops.c:12
int perm(int n, int k)
Definition: main.c:789
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
void * vptr_t
Definition: papi.h:576
#define papi_calloc(a, b)
Definition: papi_memory.h:37
#define papi_free(a)
Definition: papi_memory.h:35
const char * name
Definition: rocs.c:225
get the executable's address space info
Definition: papi.h:684
vptr_t text_start
Definition: papi.h:686
vptr_t text_end
Definition: papi.h:687
vptr_t bss_start
Definition: papi.h:690
vptr_t data_end
Definition: papi.h:689
vptr_t data_start
Definition: papi.h:688
vptr_t bss_end
Definition: papi.h:691
char fullname[PAPI_HUGE_STR_LEN]
Definition: papi.h:697
PAPI_address_map_t address_info
Definition: papi.h:698
PAPI_address_map_t * map
Definition: papi.h:703
PAPI_exe_info_t exe_info
PAPI_shlib_info_t shlib_info
Here is the call graph for this function:
Here is the caller graph for this function:

◆ generic_get_memory_info()

int generic_get_memory_info ( PAPI_hw_info_t hw_info)

Definition at line 1164 of file linux-memory.c.

1165{
1166
1167 int type=0,level,result;
1168 int size,line_size,associativity,sets;
1169 int write_policy,allocation_policy;
1170 DIR *dir;
1171 FILE *fff;
1172 char filename[BUFSIZ],type_string[BUFSIZ];
1173 char *str_result;
1174 char write_policy_string[BUFSIZ],allocation_policy_string[BUFSIZ];
1175 struct dirent *d;
1176 int max_level=0;
1177 int level_count,level_index;
1178
1180
1181 /* open Linux cache dir */
1182 /* assume all CPUs same as cpu0. */
1183 /* Not necessarily a good assumption */
1184
1185 dir=opendir("/sys/devices/system/cpu/cpu0/cache");
1186 if (dir==NULL) {
1187 goto unrecoverable_error;
1188 }
1189
1190 for (level_index=0; level_index < PAPI_MAX_MEM_HIERARCHY_LEVELS; ++level_index) {
1191 for (level_count = 0; level_count < PAPI_MH_MAX_LEVELS; ++level_count) {
1192 L[level_index].cache[level_count].type = PAPI_MH_TYPE_EMPTY;
1193 }
1194 }
1195
1196 while(1) {
1197 d = readdir(dir);
1198 if (d==NULL) break;
1199
1200 if (strncmp(d->d_name, "index", 5)) continue;
1201
1202 MEMDBG("Found %s\n",d->d_name);
1203
1204 /*************/
1205 /* Get level */
1206 /*************/
1207 sprintf(filename,
1208 "/sys/devices/system/cpu/cpu0/cache/%s/level",
1209 d->d_name);
1210 fff=fopen(filename,"r");
1211 if (fff==NULL) {
1212 MEMDBG("Cannot open level.\n");
1213 goto unrecoverable_error;
1214 }
1215
1216 result=fscanf(fff,"%d",&level);
1217 fclose(fff);
1218 if (result!=1) {
1219 MEMDBG("Could not read cache level\n");
1220 goto unrecoverable_error;
1221 }
1222
1223 /* Index arrays from 0 */
1224 level_index=level-1;
1225
1226 level_count = 0;
1227 while (L[level_index].cache[level_count].type != PAPI_MH_TYPE_EMPTY) {
1228 level_count++;
1229 if (level_count>=PAPI_MH_MAX_LEVELS) {
1230 break;
1231 }
1232 }
1233
1234 if (level_count>=PAPI_MH_MAX_LEVELS) {
1235 MEMDBG("Exceeded maximum levels %d\n",
1237 break;
1238 }
1239
1240 /************/
1241 /* Get type */
1242 /************/
1243 sprintf(filename,
1244 "/sys/devices/system/cpu/cpu0/cache/%s/type",d->d_name);
1245 fff=fopen(filename,"r");
1246 if (fff==NULL) {
1247 MEMDBG("Cannot open type\n");
1248 goto unrecoverable_error;
1249 }
1250 str_result=fgets(type_string, BUFSIZ, fff);
1251 fclose(fff);
1252 if (str_result==NULL) {
1253 MEMDBG("Could not read cache type\n");
1254 goto unrecoverable_error;
1255 }
1256 if (!strcmp(type_string,"Data")) {
1258 }
1259 if (!strcmp(type_string,"Instruction")) {
1261 }
1262 if (!strcmp(type_string,"Unified")) {
1264 }
1265
1266 /********************/
1267 /* Get write_policy */
1268 /********************/
1269 write_policy=0;
1270 sprintf(filename,
1271 "/sys/devices/system/cpu/cpu0/cache/%s/write_policy",d->d_name);
1272 fff=fopen(filename,"r");
1273 if (fff==NULL) {
1274 MEMDBG("Cannot open write_policy\n");
1275 goto get_allocation_policy;
1276 }
1277 str_result=fgets(write_policy_string, BUFSIZ, fff);
1278 fclose(fff);
1279 if (str_result==NULL) {
1280 MEMDBG("Could not read cache write_policy\n");
1281 goto get_allocation_policy;
1282 }
1283 if (!strcmp(write_policy_string,"WriteThrough")) {
1284 write_policy=PAPI_MH_TYPE_WT;
1285 }
1286 if (!strcmp(write_policy_string,"WriteBack")) {
1287 write_policy=PAPI_MH_TYPE_WB;
1288 }
1289
1290get_allocation_policy:
1291
1292 /*************************/
1293 /* Get allocation_policy */
1294 /*************************/
1295 allocation_policy=0;
1296 sprintf(filename,
1297 "/sys/devices/system/cpu/cpu0/cache/%s/allocation_policy",d->d_name);
1298 fff=fopen(filename,"r");
1299 if (fff==NULL) {
1300 MEMDBG("Cannot open allocation_policy\n");
1301 goto get_size;
1302 }
1303 str_result=fgets(allocation_policy_string, BUFSIZ, fff);
1304 fclose(fff);
1305 if (str_result==NULL) {
1306 MEMDBG("Could not read cache allocation_policy\n");
1307 goto get_size;
1308 }
1309 if (!strcmp(allocation_policy_string,"ReadAllocate")) {
1310 allocation_policy=PAPI_MH_TYPE_RD_ALLOC;
1311 }
1312 if (!strcmp(allocation_policy_string,"WriteAllocate")) {
1313 allocation_policy=PAPI_MH_TYPE_WR_ALLOC;
1314 }
1315 if (!strcmp(allocation_policy_string,"ReadWriteAllocate")) {
1316 allocation_policy=PAPI_MH_TYPE_RW_ALLOC;
1317 }
1318
1319get_size:
1320 L[level_index].cache[level_count].type=type | write_policy | allocation_policy;
1321
1322 /*************/
1323 /* Get Size */
1324 /*************/
1325 sprintf(filename,
1326 "/sys/devices/system/cpu/cpu0/cache/%s/size",d->d_name);
1327 fff=fopen(filename,"r");
1328 if (fff==NULL) {
1329 MEMDBG("Cannot open size\n");
1330 goto unrecoverable_error;
1331 }
1332 result=fscanf(fff,"%d",&size);
1333 fclose(fff);
1334 if (result!=1) {
1335 MEMDBG("Could not read cache size\n");
1336 goto unrecoverable_error;
1337 }
1338
1339 /* Linux reports in kB, PAPI expects in Bytes */
1340 L[level_index].cache[level_count].size=size*1024;
1341
1342 /*************/
1343 /* Line Size */
1344 /*************/
1345 L[level_index].cache[level_count].line_size=0;
1346
1347 sprintf(filename,
1348 "/sys/devices/system/cpu/cpu0/cache/%s/coherency_line_size",
1349 d->d_name);
1350 fff=fopen(filename,"r");
1351 if (fff==NULL) {
1352 MEMDBG("Cannot open linesize\n");
1353 }
1354 else {
1355 result=fscanf(fff,"%d",&line_size);
1356 fclose(fff);
1357 if (result!=1) {
1358 MEMDBG("Could not read cache line-size\n");
1359 } else {
1360 L[level_index].cache[level_count].line_size=line_size;
1361 }
1362 }
1363
1364
1365 /*********************/
1366 /* Get Associativity */
1367 /*********************/
1368 L[level_index].cache[level_count].associativity=0;
1369
1370 sprintf(filename,
1371 "/sys/devices/system/cpu/cpu0/cache/%s/ways_of_associativity",
1372 d->d_name);
1373 fff=fopen(filename,"r");
1374 if (fff==NULL) {
1375 MEMDBG("Cannot open associativity\n");
1376 }
1377 else {
1378 result=fscanf(fff,"%d",&associativity);
1379 fclose(fff);
1380 if (result!=1) {
1381 MEMDBG("Could not read cache associativity\n");
1382 }
1383 else {
1384 L[level_index].cache[level_count].associativity=associativity;
1385 }
1386 }
1387
1388 /************/
1389 /* Get Sets */
1390 /************/
1391 L[level_index].cache[level_count].num_lines=0;
1392
1393 sprintf(filename,
1394 "/sys/devices/system/cpu/cpu0/cache/%s/number_of_sets",
1395 d->d_name);
1396 fff=fopen(filename,"r");
1397 if (fff==NULL) {
1398 MEMDBG("Cannot open sets\n");
1399 }
1400 else {
1401 result=fscanf(fff,"%d",&sets);
1402 fclose(fff);
1403
1404 if (result!=1) {
1405 MEMDBG("Could not read cache sets\n");
1406 }
1407 else {
1408 L[level_index].cache[level_count].num_lines=sets;
1409 }
1410 }
1411
1412 /* Sanity check results */
1413 if ((line_size!=0) && (associativity!=0)) {
1414 if (((size*1024)/line_size/associativity)!=sets) {
1415 MEMDBG("Warning! sets %d != expected %d\n",
1416 sets,((size*1024)/line_size/associativity));
1417 }
1418 }
1419
1420 MEMDBG("\tL%d %s cache\n",level,type_string);
1421 MEMDBG("\t%d kilobytes\n",size);
1422 MEMDBG("\t%d byte linesize\n",line_size);
1423 MEMDBG("\t%d-way associative\n",associativity);
1424 MEMDBG("\t%d lines\n",sets);
1425 MEMDBG("\tUnknown inclusivity\n");
1426 MEMDBG("\tUnknown replacement algorithm\n");
1427 MEMDBG("\tUnknown if victim cache\n");
1428
1429 if (level>max_level) max_level=level;
1430
1432 MEMDBG("Exceeded maximum cache level %d\n",
1434 break;
1435 }
1436 }
1437
1438 closedir(dir);
1439 hw_info->mem_hierarchy.levels = max_level;
1440
1441 return 0;
1442
1443unrecoverable_error:
1444
1445 /* Just say we have no cache */
1447
1448 closedir(dir);
1449 return 0;
1450}
volatile int result
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:28
#define PAPI_MAX_MEM_HIERARCHY_LEVELS
Definition: f90papi.h:103
FILE * fff[MAX_EVENTS]
uint16_t type
#define PAPI_MH_TYPE_DATA
Definition: papi.h:720
#define PAPI_MH_TYPE_RW_ALLOC
Definition: papi.h:737
#define PAPI_MH_MAX_LEVELS
Definition: papi.h:739
#define PAPI_MH_TYPE_WB
Definition: papi.h:726
#define PAPI_MH_TYPE_WR_ALLOC
Definition: papi.h:736
#define PAPI_MH_TYPE_WT
Definition: papi.h:725
#define PAPI_MH_TYPE_RD_ALLOC
Definition: papi.h:735
#define PAPI_MH_TYPE_INST
Definition: papi.h:719
#define PAPI_MH_TYPE_EMPTY
Definition: papi.h:718
#define PAPI_MH_TYPE_UNIFIED
Definition: papi.h:723
#define MEMDBG(format, args...)
Definition: papi_debug.h:71
PAPI_mh_info_t mem_hierarchy
Definition: papi.h:793
int levels
Definition: papi.h:768
PAPI_mh_level_t level[PAPI_MAX_MEM_HIERARCHY_LEVELS]
Definition: papi.h:769
PAPI_mh_cache_info_t cache[PAPI_MH_MAX_LEVELS]
Definition: papi.h:762
Here is the call graph for this function:
Here is the caller graph for this function: