PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-memory.c
Go to the documentation of this file.
1/****************************/
2/* THIS IS OPEN SOURCE CODE */
3/****************************/
4
5/*
6* File: linux-memory.c
7* Author: Kevin London
8* london@cs.utk.edu
9* Mods: Dan Terpstra
10* terpstra@eecs.utk.edu
11* cache and TLB info exported to a separate file
12* which is not OS or driver dependent
13* Mods: Vince Weaver
14* vweaver1@eecs.utk.edu
15* Merge all of the various copies of linux-related
16* memory detection info this file.
17*/
18
19#include <dirent.h>
20#include <fcntl.h>
21#include <string.h>
22#include <errno.h>
23#include <ctype.h>
24
25#include "papi.h"
26#include "papi_internal.h"
27#include "papi_memory.h" /* papi_calloc() */
28
29#include "x86_cpuid_info.h"
30
31#include "linux-lock.h"
32
33/* 2.6.19 has this:
34VmPeak: 4588 kB
35VmSize: 4584 kB
36VmLck: 0 kB
37VmHWM: 1548 kB
38VmRSS: 1548 kB
39VmData: 312 kB
40VmStk: 88 kB
41VmExe: 684 kB
42VmLib: 1360 kB
43VmPTE: 20 kB
44*/
45
46int
48
49int
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}
130
131/*
132 * Architecture-specific cache detection code
133 */
134
135
136#if defined(__i386__)||defined(__x86_64__)
137static int
138x86_get_memory_info( PAPI_hw_info_t * hw_info )
139{
140 int retval = PAPI_OK;
141
142 switch ( hw_info->vendor ) {
143 case PAPI_VENDOR_AMD:
146 break;
147 default:
148 PAPIERROR( "Unknown vendor in memory information call for x86." );
149 return PAPI_ENOIMPL;
150 }
151 return retval;
152}
153#endif
154
155#if defined(__ia64__)
156static int
157get_number( char *buf )
158{
159 char numbers[] = "0123456789";
160 int num;
161 char *tmp, *end;
162
163 tmp = strpbrk( buf, numbers );
164 if ( tmp != NULL ) {
165 end = tmp;
166 while ( isdigit( *end ) )
167 end++;
168 *end = '\0';
169 num = atoi( tmp );
170 return num;
171 }
172
173 PAPIERROR( "Number could not be parsed from %s", buf );
174 return -1;
175}
176
177static void
178fline( FILE * fp, char *rline )
179{
180 char *tmp, *end, c;
181
182 tmp = rline;
183 end = &rline[1023];
184
185 memset( rline, '\0', 1024 );
186
187 do {
188 if ( feof( fp ) )
189 return;
190 c = getc( fp );
191 }
192 while ( isspace( c ) || c == '\n' || c == '\r' );
193
194 ungetc( c, fp );
195
196 for ( ;; ) {
197 if ( feof( fp ) ) {
198 return;
199 }
200 c = getc( fp );
201 if ( c == '\n' || c == '\r' )
202 break;
203 *tmp++ = c;
204 if ( tmp == end ) {
205 *tmp = '\0';
206 return;
207 }
208 }
209 return;
210}
211
212static int
213ia64_get_memory_info( PAPI_hw_info_t * hw_info )
214{
215 int retval = 0;
216 FILE *f;
217 int clevel = 0, cindex = -1;
218 char buf[1024];
219 int num, i, j;
222
223 f = fopen( "/proc/pal/cpu0/cache_info", "r" );
224
225 if ( !f ) {
226 PAPIERROR( "fopen(/proc/pal/cpu0/cache_info) returned < 0" );
227 return PAPI_ESYS;
228 }
229
230 while ( !feof( f ) ) {
231 fline( f, buf );
232 if ( buf[0] == '\0' )
233 break;
234 if ( !strncmp( buf, "Data Cache", 10 ) ) {
235 cindex = 1;
236 clevel = get_number( buf );
237 L[clevel - 1].cache[cindex].type = PAPI_MH_TYPE_DATA;
238 } else if ( !strncmp( buf, "Instruction Cache", 17 ) ) {
239 cindex = 0;
240 clevel = get_number( buf );
241 L[clevel - 1].cache[cindex].type = PAPI_MH_TYPE_INST;
242 } else if ( !strncmp( buf, "Data/Instruction Cache", 22 ) ) {
243 cindex = 0;
244 clevel = get_number( buf );
245 L[clevel - 1].cache[cindex].type = PAPI_MH_TYPE_UNIFIED;
246 } else {
247 if ( ( clevel == 0 || clevel > 3 ) && cindex >= 0 ) {
249 ( "Cache type could not be recognized, please send /proc/pal/cpu0/cache_info" );
250 return PAPI_EBUG;
251 }
252
253 if ( !strncmp( buf, "Size", 4 ) ) {
254 num = get_number( buf );
255 L[clevel - 1].cache[cindex].size = num;
256 } else if ( !strncmp( buf, "Associativity", 13 ) ) {
257 num = get_number( buf );
258 L[clevel - 1].cache[cindex].associativity = num;
259 } else if ( !strncmp( buf, "Line size", 9 ) ) {
260 num = get_number( buf );
261 L[clevel - 1].cache[cindex].line_size = num;
262 L[clevel - 1].cache[cindex].num_lines =
263 L[clevel - 1].cache[cindex].size / num;
264 }
265 }
266 }
267
268 fclose( f );
269
270 f = fopen( "/proc/pal/cpu0/vm_info", "r" );
271 /* No errors on fopen as I am not sure this is always on the systems */
272 if ( f != NULL ) {
273 cindex = -1;
274 clevel = 0;
275 while ( !feof( f ) ) {
276 fline( f, buf );
277 if ( buf[0] == '\0' )
278 break;
279 if ( !strncmp( buf, "Data Translation", 16 ) ) {
280 cindex = 1;
281 clevel = get_number( buf );
282 L[clevel - 1].tlb[cindex].type = PAPI_MH_TYPE_DATA;
283 } else if ( !strncmp( buf, "Instruction Translation", 23 ) ) {
284 cindex = 0;
285 clevel = get_number( buf );
286 L[clevel - 1].tlb[cindex].type = PAPI_MH_TYPE_INST;
287 } else {
288 if ( ( clevel == 0 || clevel > 2 ) && cindex >= 0 ) {
290 ( "TLB type could not be recognized, send /proc/pal/cpu0/vm_info" );
291 return PAPI_EBUG;
292 }
293
294 if ( !strncmp( buf, "Number of entries", 17 ) ) {
295 num = get_number( buf );
296 L[clevel - 1].tlb[cindex].num_entries = num;
297 } else if ( !strncmp( buf, "Associativity", 13 ) ) {
298 num = get_number( buf );
299 L[clevel - 1].tlb[cindex].associativity = num;
300 }
301 }
302 }
303 fclose( f );
304 }
305
306 /* Compute and store the number of levels of hierarchy actually used */
307 for ( i = 0; i < PAPI_MH_MAX_LEVELS; i++ ) {
308 for ( j = 0; j < 2; j++ ) {
309 if ( L[i].tlb[j].type != PAPI_MH_TYPE_EMPTY ||
310 L[i].cache[j].type != PAPI_MH_TYPE_EMPTY )
311 meminfo->levels = i + 1;
312 }
313 }
314 return retval;
315}
316#endif
317
318#if defined(__powerpc__)
319
320PAPI_mh_info_t sys_mem_info[] = {
321 {2, // 970 begin
322 {
323 { // level 1 begins
324 { // tlb's begin
325 {PAPI_MH_TYPE_UNIFIED, 1024, 4, 0}
326 ,
327 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
328 }
329 ,
330 { // caches begin
331 {PAPI_MH_TYPE_INST, 65536, 128, 512, 1}
332 ,
333 {PAPI_MH_TYPE_DATA, 32768, 128, 256, 2}
334 }
335 }
336 ,
337 { // level 2 begins
338 { // tlb's begin
339 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
340 ,
341 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
342 }
343 ,
344 { // caches begin
345 {PAPI_MH_TYPE_UNIFIED, 524288, 128, 4096, 8}
346 ,
347 {PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
348 }
349 }
350 ,
351 }
352 }
353 , // 970 end
354 {3,
355 {
356 { // level 1 begins
357 { // tlb's begin
358 {PAPI_MH_TYPE_UNIFIED, 1024, 4, 0}
359 ,
360 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
361 }
362 ,
363 { // caches begin
364 {PAPI_MH_TYPE_INST, 65536, 128, 512, 2}
365 ,
366 {PAPI_MH_TYPE_DATA, 32768, 128, 256, 4}
367 }
368 }
369 ,
370 { // level 2 begins
371 { // tlb's begin
372 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
373 ,
374 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
375 }
376 ,
377 { // caches begin
378 {PAPI_MH_TYPE_UNIFIED, 1966080, 128, 15360, 10}
379 ,
380 {PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
381 }
382 }
383 ,
384 { // level 3 begins
385 { // tlb's begin
386 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
387 ,
388 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
389 }
390 ,
391 { // caches begin
392 {PAPI_MH_TYPE_UNIFIED, 37748736, 256, 147456, 12}
393 ,
394 {PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
395 }
396 }
397 ,
398 }
399 }
400 , // POWER5 end
401 {3,
402 {
403 { // level 1 begins
404 { // tlb's begin
408 {PAPI_MH_TYPE_INST, 128, 2, 0}
409 ,
410 {PAPI_MH_TYPE_DATA, 128, 128, 0}
411 }
412 ,
413 { // caches begin
414 {PAPI_MH_TYPE_INST, 65536, 128, 512, 4}
415 ,
416 {PAPI_MH_TYPE_DATA, 65536, 128, 512, 8}
417 }
418 }
419 ,
420 { // level 2 begins
421 { // tlb's begin
422 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
423 ,
424 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
425 }
426 ,
427 { // caches begin
428 {PAPI_MH_TYPE_UNIFIED, 4194304, 128, 16384, 8}
429 ,
430 {PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
431 }
432 }
433 ,
434 { // level 3 begins
435 { // tlb's begin
436 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
437 ,
438 {PAPI_MH_TYPE_EMPTY, -1, -1, -1}
439 }
440 ,
441 { // caches begin
445 {PAPI_MH_TYPE_UNIFIED, 33554432, 128, 262144, 16}
446 ,
447 {PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
448 }
449 }
450 ,
451 }
452 }
453 , // POWER6 end
454 {3,
455 {
456 [0] = { // level 1 begins
457 .tlb = {
461 [0] = { .type = PAPI_MH_TYPE_INST,
462 .num_entries = 64, .page_size = 0, .associativity = 2 }
463 ,
464 [1] = { .type = PAPI_MH_TYPE_DATA,
465 .num_entries = 64, .page_size = 0,
466 .associativity = SHRT_MAX }
467 }
468 ,
469 .cache = { // level 1 caches begin
471 .size = 32768, .line_size = 128, .num_lines = 64,
472 .associativity = 4 }
473 ,
475 .size = 32768, .line_size = 128, .num_lines = 32,
476 .associativity = 8 }
477 }
478 }
479 ,
480 [1] = { // level 2 begins
481 .tlb = {
482 [0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
483 .page_size = -1, .associativity = -1 }
484 ,
485 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
486 .page_size = -1, .associativity = -1 }
487 }
488 ,
489 .cache = {
491 .size = 524288, .line_size = 128, .num_lines = 256,
492 .associativity = 8 }
493 ,
494 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
495 .num_lines = -1, .associativity = -1 }
496 }
497 }
498 ,
499 [2] = { // level 3 begins
500 .tlb = {
501 [0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
502 .page_size = -1, .associativity = -1 }
503 ,
504 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
505 .page_size = -1, .associativity = -1 }
506 }
507 ,
508 .cache = {
510 .size = 4194304, .line_size = 128, .num_lines = 4096,
511 .associativity = 8 }
512 ,
513 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
514 .num_lines = -1, .associativity = -1 }
515 }
516 }
517 ,
518 }
519 }, // POWER7 end
520 {3,
521 {
522 [0] = { // level 1 begins
523 .tlb = {
527 [0] = { .type = PAPI_MH_TYPE_INST,
528 .num_entries = 72, .page_size = 0,
529 .associativity = SHRT_MAX }
530 ,
531 [1] = { .type = PAPI_MH_TYPE_DATA,
532 .num_entries = 48, .page_size = 0,
533 .associativity = SHRT_MAX }
534 }
535 ,
536 .cache = { // level 1 caches begin
538 .size = 32768, .line_size = 128, .num_lines = 64,
539 .associativity = 8 }
540 ,
542 .size = 65536, .line_size = 128, .num_lines = 512,
543 .associativity = 8 }
544 }
545 }
546 ,
547 [1] = { // level 2 begins
548 .tlb = {
549 [0] = { .type = PAPI_MH_TYPE_UNIFIED, .num_entries = 2048,
550 .page_size = 0, .associativity = 4 }
551 ,
552 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
553 .page_size = -1, .associativity = -1 }
554 }
555 ,
556 .cache = {
558 .size = 262144, .line_size = 128, .num_lines = 256,
559 .associativity = 8 }
560 ,
561 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
562 .num_lines = -1, .associativity = -1 }
563 }
564 }
565 ,
566 [2] = { // level 3 begins
567 .tlb = {
568 [0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
569 .page_size = -1, .associativity = -1 }
570 ,
571 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
572 .page_size = -1, .associativity = -1 }
573 }
574 ,
575 .cache = {
577 .size = 8388608, .line_size = 128, .num_lines = 65536,
578 .associativity = 8 }
579 ,
580 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
581 .num_lines = -1, .associativity = -1 }
582 }
583 }
584 ,
585 }
586 }, // POWER8 end
587 {3,
588 {
589 [0] = { // level 1 begins
590 .tlb = {
594 [0] = { .type = PAPI_MH_TYPE_INST,
595 .num_entries = 64, .page_size = 0,
596 .associativity = SHRT_MAX }
597 ,
598 [1] = { .type = PAPI_MH_TYPE_DATA,
599 .num_entries = 64, .page_size = 0,
600 .associativity = SHRT_MAX }
601 }
602 ,
603 .cache = { // level 1 caches begin
605 .size = 32768, .line_size = 128, .num_lines = 256,
606 .associativity = 8 }
607 ,
609 .size = 32768, .line_size = 128, .num_lines = 256,
610 .associativity = 8 }
611 }
612 }
613 ,
614 [1] = { // level 2 begins
615 .tlb = {
616 [0] = { .type = PAPI_MH_TYPE_UNIFIED, .num_entries = 1024,
617 .page_size = 0, .associativity = 4 }
618 ,
619 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
620 .page_size = -1, .associativity = -1 }
621 }
622 ,
623 .cache = {
625 .size = 524288, .line_size = 128, .num_lines = 4096,
626 .associativity = 8 }
627 ,
628 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
629 .num_lines = -1, .associativity = -1 }
630 }
631 }
632 ,
633 [2] = { // level 3 begins
634 .tlb = {
635 [0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
636 .page_size = -1, .associativity = -1 }
637 ,
638 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
639 .page_size = -1, .associativity = -1 }
640 }
641 ,
642 .cache = {
644 .size = 10485760, .line_size = 128, .num_lines = 81920,
645 .associativity = 20 }
646 ,
647 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
648 .num_lines = -1, .associativity = -1 }
649 }
650 }
651 ,
652 }
653 },
654 {3,
655 {
656 [0] = { // level 1 begins
657 .tlb = {
661 [0] = { .type = PAPI_MH_TYPE_INST,
662 .num_entries = 64, .page_size = 0,
663 .associativity = SHRT_MAX }
664 ,
665 [1] = { .type = PAPI_MH_TYPE_DATA,
666 .num_entries = 64, .page_size = 0,
667 .associativity = SHRT_MAX }
668 }
669 ,
670 .cache = { // level 1 caches begin
672 .size = 49152, .line_size = 128, .num_lines = 384,
673 .associativity = 6 }
674 ,
676 .size = 32768, .line_size = 128, .num_lines = 256,
677 .associativity = 8 }
678 }
679 }
680 ,
681 [1] = { // level 2 begins
682 .tlb = {
683 [0] = { .type = PAPI_MH_TYPE_UNIFIED, .num_entries = 4096,
684 .page_size = 0, .associativity = 4 }
685 ,
686 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
687 .page_size = -1, .associativity = -1 }
688 }
689 ,
690 .cache = {
692 .size = 1048576, .line_size = 128, .num_lines = 8192,
693 .associativity = 8 }
694 ,
695 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
696 .num_lines = -1, .associativity = -1 }
697 }
698 }
699 ,
700 [2] = { // level 3 begins
701 .tlb = {
702 [0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
703 .page_size = -1, .associativity = -1 }
704 ,
705 [1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
706 .page_size = -1, .associativity = -1 }
707 }
708 ,
709 .cache = {
711 .size = 4194304, .line_size = 128, .num_lines = 32768,
712 .associativity = 16 }
713 ,
714 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
715 .num_lines = -1, .associativity = -1 }
716 }
717 }
718 ,
719 }
720 } // POWER10 end
721};
722
723#define SPRN_PVR 0x11F /* Processor Version Register */
724#define PVR_PROCESSOR_SHIFT 16
725static unsigned int
726mfpvr( void )
727{
728 unsigned long pvr;
729
730 asm( "mfspr %0,%1": "=r"( pvr ):"i"( SPRN_PVR ) );
731 return pvr;
732
733}
734
735int
736ppc64_get_memory_info( PAPI_hw_info_t * hw_info )
737{
738 unsigned int pvr = mfpvr( ) >> PVR_PROCESSOR_SHIFT;
739
740 int index;
741 switch ( pvr ) {
742 case 0x39: /* PPC970 */
743 case 0x3C: /* PPC970FX */
744 case 0x44: /* PPC970MP */
745 case 0x45: /* PPC970GX */
746 index = 0;
747 break;
748 case 0x3A: /* POWER5 */
749 case 0x3B: /* POWER5+ */
750 index = 1;
751 break;
752 case 0x3E: /* POWER6 */
753 index = 2;
754 break;
755 case 0x3F: /* POWER7 */
756 index = 3;
757 break;
758 case 0x4b: /* POWER8 */
759 index = 4;
760 break;
761 case 0x4e: /* POWER9 */
762 index = 5;
763 break;
764 case 0x80: /* POWER10 */
765 index = 6;
766 break;
767 default:
768 index = -1;
770 break;
771 }
772
773 if ( index != -1 ) {
774 int cache_level;
775 PAPI_mh_info_t sys_mh_inf = sys_mem_info[index];
777 mh_inf->levels = sys_mh_inf.levels;
778 PAPI_mh_level_t *level = mh_inf->level;
779 PAPI_mh_level_t sys_mh_level;
780 for ( cache_level = 0; cache_level < sys_mh_inf.levels; cache_level++ ) {
781 sys_mh_level = sys_mh_inf.level[cache_level];
782 int cache_idx;
783 for ( cache_idx = 0; cache_idx < 2; cache_idx++ ) {
784 // process TLB info
785 PAPI_mh_tlb_info_t curr_tlb = sys_mh_level.tlb[cache_idx];
786 int type = curr_tlb.type;
787 if ( type != PAPI_MH_TYPE_EMPTY ) {
788 level[cache_level].tlb[cache_idx].type = type;
789 level[cache_level].tlb[cache_idx].associativity =
790 curr_tlb.associativity;
791 level[cache_level].tlb[cache_idx].num_entries =
792 curr_tlb.num_entries;
793 }
794 }
795 for ( cache_idx = 0; cache_idx < 2; cache_idx++ ) {
796 // process cache info
797 PAPI_mh_cache_info_t curr_cache = sys_mh_level.cache[cache_idx];
798 int type = curr_cache.type;
799 if ( type != PAPI_MH_TYPE_EMPTY ) {
800 level[cache_level].cache[cache_idx].type = type;
801 level[cache_level].cache[cache_idx].associativity =
802 curr_cache.associativity;
803 level[cache_level].cache[cache_idx].size = curr_cache.size;
804 level[cache_level].cache[cache_idx].line_size =
805 curr_cache.line_size;
806 level[cache_level].cache[cache_idx].num_lines =
807 curr_cache.num_lines;
808 }
809 }
810 }
811 }
812 return 0;
813}
814#endif
815
816
817
818#if defined(__sparc__)
819static int
820sparc_sysfs_cpu_attr( char *name, char **result )
821{
822 const char *path_base = "/sys/devices/system/cpu/";
823 char path_buf[PATH_MAX];
824 char val_buf[32];
825 DIR *sys_cpu;
826
827 sys_cpu = opendir( path_base );
828 if ( sys_cpu ) {
829 struct dirent *cpu;
830
831 while ( ( cpu = readdir( sys_cpu ) ) != NULL ) {
832 int fd;
833
834 if ( strncmp( "cpu", cpu->d_name, 3 ) )
835 continue;
836 strcpy( path_buf, path_base );
837 strcat( path_buf, cpu->d_name );
838 strcat( path_buf, "/" );
839 strcat( path_buf, name );
840
841 fd = open( path_buf, O_RDONLY );
842 if ( fd < 0 )
843 continue;
844
845 if ( read( fd, val_buf, 32 ) < 0 )
846 continue;
847 close( fd );
848
849 *result = strdup( val_buf );
850 return 0;
851 }
852 }
853 closedir( sys_cpu );
854 return -1;
855}
856
857static int
858sparc_cpu_attr( char *name, unsigned long long *val )
859{
860 char *buf;
861 int r;
862
863 r = sparc_sysfs_cpu_attr( name, &buf );
864 if ( r == -1 )
865 return -1;
866
867 sscanf( buf, "%llu", val );
868
869 free( buf );
870
871 return 0;
872}
873
874static char *
875search_cpu_info( FILE * f, char *search_str, char *line )
876{
877 /* This code courtesy of our friends in Germany. Thanks Rudolph Berrend\
878 orf! */
879 /* See the home page for the German version of PAPI. */
880
881 char *s;
882
883 while ( fgets( line, 256, f ) != NULL ) {
884 if ( strstr( line, search_str ) != NULL ) {
885 /* ignore all characters in line up to : */
886 for ( s = line; *s && ( *s != ':' ); ++s );
887 if ( *s )
888 return s;
889 }
890 }
891 return NULL;
892
893 /* End stolen code */
894}
895
896
897static int
898sparc_get_memory_info( PAPI_hw_info_t * hw_info )
899{
900 unsigned long long cache_size, cache_line_size;
901 /* unsigned long long cycles_per_second; */
902 char maxargs[PAPI_HUGE_STR_LEN];
903 /* PAPI_mh_tlb_info_t *tlb; */
904 PAPI_mh_level_t *level;
905 char *s, *t;
906 FILE *f;
907
908 /* First, fix up the cpu vendor/model/etc. values */
909 strcpy( hw_info->vendor_string, "Sun" );
911
912 f = fopen( "/proc/cpuinfo", "r" );
913 if ( !f )
914 return PAPI_ESYS;
915
916 rewind( f );
917 s = search_cpu_info( f, "cpu", maxargs );
918 if ( !s ) {
919 fclose( f );
920 return PAPI_ESYS;
921 }
922
923 t = strchr( s + 2, '\n' );
924 if ( !t ) {
925 fclose( f );
926 return PAPI_ESYS;
927 }
928
929 *t = '\0';
930 strcpy( hw_info->model_string, s + 2 );
931
932 fclose( f );
933
934 /*
935 if ( sparc_sysfs_cpu_attr( "clock_tick", &s ) == -1 )
936 return PAPI_ESYS;
937
938 sscanf( s, "%llu", &cycles_per_second );
939 free( s );
940
941 hw_info->mhz = cycles_per_second / 1000000;
942 hw_info->clock_mhz = hw_info->mhz;
943 */
944
945 /* Now fetch the cache info */
947
948 level = &hw_info->mem_hierarchy.level[0];
949
950 sparc_cpu_attr( "l1_icache_size", &cache_size );
951 sparc_cpu_attr( "l1_icache_line_size", &cache_line_size );
952 level[0].cache[0].type = PAPI_MH_TYPE_INST;
953 level[0].cache[0].size = cache_size;
954 level[0].cache[0].line_size = cache_line_size;
955 level[0].cache[0].num_lines = cache_size / cache_line_size;
956 level[0].cache[0].associativity = 1;
957
958 sparc_cpu_attr( "l1_dcache_size", &cache_size );
959 sparc_cpu_attr( "l1_dcache_line_size", &cache_line_size );
961 level[0].cache[1].size = cache_size;
962 level[0].cache[1].line_size = cache_line_size;
963 level[0].cache[1].num_lines = cache_size / cache_line_size;
964 level[0].cache[1].associativity = 1;
965
966 sparc_cpu_attr( "l2_cache_size", &cache_size );
967 sparc_cpu_attr( "l2_cache_line_size", &cache_line_size );
969 level[1].cache[0].size = cache_size;
970 level[1].cache[0].line_size = cache_line_size;
971 level[1].cache[0].num_lines = cache_size / cache_line_size;
972 level[1].cache[0].associativity = 1;
973
974#if 0
975 tlb = &hw_info->mem_hierarchy.level[0].tlb[0];
976 switch ( _perfmon2_pfm_pmu_type ) {
979 tlb[0].num_entries = 64;
980 tlb[0].associativity = SHRT_MAX;
982 tlb[1].num_entries = 64;
983 tlb[1].associativity = SHRT_MAX;
984 break;
985
990 level[0].cache[0].associativity = 4;
991 level[0].cache[1].associativity = 4;
992 level[1].cache[0].associativity = 4;
993
995 tlb[0].num_entries = 16;
996 tlb[0].associativity = SHRT_MAX;
998 tlb[1].num_entries = 16;
999 tlb[1].associativity = SHRT_MAX;
1000 tlb[2].type = PAPI_MH_TYPE_DATA;
1001 tlb[2].num_entries = 1024;
1002 tlb[2].associativity = 2;
1003 tlb[3].type = PAPI_MH_TYPE_INST;
1004 tlb[3].num_entries = 128;
1005 tlb[3].associativity = 2;
1006 break;
1007
1008 case PFMLIB_SPARC_NIAGARA1:
1009 level[0].cache[0].associativity = 4;
1010 level[0].cache[1].associativity = 4;
1011 level[1].cache[0].associativity = 12;
1012
1014 tlb[0].num_entries = 64;
1015 tlb[0].associativity = SHRT_MAX;
1017 tlb[1].num_entries = 64;
1018 tlb[1].associativity = SHRT_MAX;
1019 break;
1020
1021 case PFMLIB_SPARC_NIAGARA2:
1022 level[0].cache[0].associativity = 8;
1023 level[0].cache[1].associativity = 4;
1024 level[1].cache[0].associativity = 16;
1025
1027 tlb[0].num_entries = 64;
1028 tlb[0].associativity = SHRT_MAX;
1030 tlb[1].num_entries = 128;
1031 tlb[1].associativity = SHRT_MAX;
1032 break;
1033 }
1034#endif
1035 return 0;
1036}
1037#endif
1038
1039
1040#if defined(__aarch64__)
1041
1042PAPI_mh_info_t sys_mem_info[] = {
1043 {2, // Fujitsu A64FX begin
1044 {
1045 [0] = { // level 1 begins
1046 .tlb = {
1047 [0] = { .type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_FIFO,
1048 .num_entries = 16, .page_size = 65536,
1049 .associativity = SHRT_MAX }
1050 ,
1051 [1] = { .type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_FIFO,
1052 .num_entries = 16, .page_size = 65536,
1053 .associativity = SHRT_MAX }
1054 }
1055 ,
1056 .cache = { // level 1 caches begin
1057 [0] = { .type = PAPI_MH_TYPE_INST,
1058 .size = 65536, .line_size = 256, .num_lines = 64,
1059 .associativity = 4 }
1060 ,
1061 [1] = { .type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_WB,
1062 .size = 65536, .line_size = 256, .num_lines = 64,
1063 .associativity = 4 }
1064 }
1065 }
1066 ,
1067 [1] = { // level 2 begins
1068 .tlb = {
1069 [0] = { .type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_LRU, .num_entries = 1024,
1070 .page_size = 65536, .associativity = 4 }
1071 ,
1072 [1] = { .type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_LRU, .num_entries = 1024,
1073 .page_size = 65536, .associativity = 4 }
1074 }
1075 ,
1076 .cache = {
1077 [0] = { .type = PAPI_MH_TYPE_UNIFIED | PAPI_MH_TYPE_WB,
1078 .size = 8388608, .line_size = 256, .num_lines = 2048,
1079 .associativity = 16 }
1080 ,
1081 [1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
1082 .num_lines = -1, .associativity = -1 }
1083 }
1084 }
1085 ,
1086 }
1087 } // Fujitsu A64FX end
1088};
1089
1090#define IMPLEMENTER_FUJITSU 0x46
1091#define PARTNUM_FUJITSU_A64FX 0x001
1092
1093int
1094aarch64_get_memory_info( PAPI_hw_info_t * hw_info )
1095{
1096 unsigned int implementer, partnum;
1097
1098 implementer = hw_info->vendor;
1099 partnum = hw_info->cpuid_model;
1100
1101 int index = -1;
1102 switch ( implementer ) {
1103 case IMPLEMENTER_FUJITSU:
1104 switch ( partnum ) {
1105 case PARTNUM_FUJITSU_A64FX: /* Fujitsu A64FX */
1106 index = 0;
1107 break;
1108 default:
1110 return 0;
1111 }
1112 break;
1113 default:
1115 return 0;
1116 }
1117
1118 if ( index != -1 ) {
1119 int cache_level;
1120 PAPI_mh_info_t sys_mh_inf = sys_mem_info[index];
1122 mh_inf->levels = sys_mh_inf.levels;
1123 PAPI_mh_level_t *level = mh_inf->level;
1124 PAPI_mh_level_t sys_mh_level;
1125 for ( cache_level = 0; cache_level < sys_mh_inf.levels; cache_level++ ) {
1126 sys_mh_level = sys_mh_inf.level[cache_level];
1127 int cache_idx;
1128 for ( cache_idx = 0; cache_idx < 2; cache_idx++ ) {
1129 // process TLB info
1130 PAPI_mh_tlb_info_t curr_tlb = sys_mh_level.tlb[cache_idx];
1131 int type = curr_tlb.type;
1132 if ( type != PAPI_MH_TYPE_EMPTY ) {
1133 level[cache_level].tlb[cache_idx].type = type;
1134 level[cache_level].tlb[cache_idx].associativity =
1135 curr_tlb.associativity;
1136 level[cache_level].tlb[cache_idx].num_entries =
1137 curr_tlb.num_entries;
1138 }
1139 }
1140 for ( cache_idx = 0; cache_idx < 2; cache_idx++ ) {
1141 // process cache info
1142 PAPI_mh_cache_info_t curr_cache = sys_mh_level.cache[cache_idx];
1143 int type = curr_cache.type;
1144 if ( type != PAPI_MH_TYPE_EMPTY ) {
1145 level[cache_level].cache[cache_idx].type = type;
1146 level[cache_level].cache[cache_idx].associativity =
1147 curr_cache.associativity;
1148 level[cache_level].cache[cache_idx].size = curr_cache.size;
1149 level[cache_level].cache[cache_idx].line_size =
1150 curr_cache.line_size;
1151 level[cache_level].cache[cache_idx].num_lines =
1152 curr_cache.num_lines;
1153 }
1154 }
1155 }
1156 }
1157 return 0;
1158}
1159#endif
1160
1161
1162/* Fallback Linux code to read the cache info from /sys */
1163int
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}
1451
1452
1453int
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}
1478
1479int
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 result
double tmp
int i
int open(const char *pathname, int flags, mode_t mode)
Definition: appio.c:188
int close(int fd)
Definition: appio.c:179
int errno
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:229
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:28
double s
Definition: byte_profile.c:36
double f(double a)
Definition: cpi.c:23
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_EBUG
Definition: f90papi.h:176
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_VENDOR_SUN
Definition: f90papi.h:65
#define PAPI_VENDOR_INTEL
Definition: f90papi.h:275
#define PAPI_VENDOR_AMD
Definition: f90papi.h:230
#define PAPI_MAX_MEM_HIERARCHY_LEVELS
Definition: f90papi.h:103
#define PAPI_ESYS
Definition: f90papi.h:136
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_ENOIMPL
Definition: f90papi.h:219
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
FILE * fff[MAX_EVENTS]
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
int _linux_get_memory_info(PAPI_hw_info_t *hwinfo, int cpu_type)
int generic_get_memory_info(PAPI_hw_info_t *hw_info)
int _linux_update_shlib_info(papi_mdi_t *mdi)
int _linux_get_dmem_info(PAPI_dmem_info_t *d)
Definition: linux-memory.c:50
uint16_t type
static _sysdetect_cache_level_info_t clevel[PAPI_MAX_MEM_HIERARCHY_LEVELS]
Return codes and api definitions.
#define PAPI_MH_TYPE_DATA
Definition: papi.h:720
#define PAPI_MH_TYPE_RW_ALLOC
Definition: papi.h:737
#define PAPI_MH_TYPE_LRU
Definition: papi.h:729
#define PAPI_MH_MAX_LEVELS
Definition: papi.h:739
#define PAPI_MH_TYPE_PSEUDO_LRU
Definition: papi.h:730
#define PAPI_MH_TYPE_FIFO
Definition: papi.h:731
#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
void * vptr_t
Definition: papi.h:576
#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
int fclose(FILE *__stream)
void PAPIERROR(char *format,...)
#define papi_calloc(a, b)
Definition: papi_memory.h:37
#define papi_free(a)
Definition: papi_memory.h:35
static FILE * fp
static char * search_cpu_info(FILE *f, char *search_str, char *line)
static int _perfmon2_pfm_pmu_type
#define PFMLIB_SPARC_ULTRA3I_PMU
Definition: pfmlib.h:274
#define PFMLIB_SPARC_ULTRA12_PMU
Definition: pfmlib.h:272
#define PFMLIB_SPARC_ULTRA3PLUS_PMU
Definition: pfmlib.h:275
#define PFMLIB_SPARC_ULTRA3_PMU
Definition: pfmlib.h:273
#define PFMLIB_SPARC_ULTRA4PLUS_PMU
Definition: pfmlib.h:276
static unsigned int mfpvr(void)
#define PVR_PROCESSOR_SHIFT
#define SPRN_PVR
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
A pointer to the following is passed to PAPI_get_dmem_info()
Definition: papi.h:865
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
char fullname[PAPI_HUGE_STR_LEN]
Definition: papi.h:697
PAPI_address_map_t address_info
Definition: papi.h:698
Hardware info structure.
Definition: papi.h:774
char vendor_string[PAPI_MAX_STR_LEN]
Definition: papi.h:782
int cpuid_model
Definition: papi.h:787
PAPI_mh_info_t mem_hierarchy
Definition: papi.h:793
int vendor
Definition: papi.h:781
char model_string[PAPI_MAX_STR_LEN]
Definition: papi.h:784
mh for mem hierarchy maybe?
Definition: papi.h:767
int levels
Definition: papi.h:768
PAPI_mh_level_t level[PAPI_MAX_MEM_HIERARCHY_LEVELS]
Definition: papi.h:769
PAPI_mh_tlb_info_t tlb[PAPI_MH_MAX_LEVELS]
Definition: papi.h:761
PAPI_mh_cache_info_t cache[PAPI_MH_MAX_LEVELS]
Definition: papi.h:762
int associativity
Definition: papi.h:747
PAPI_address_map_t * map
Definition: papi.h:703
PAPI_exe_info_t exe_info
PAPI_shlib_info_t shlib_info
int _x86_cache_info(PAPI_mh_info_t *mh_info)
int retval
Definition: zero_fork.c:53