PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux_cpu_utils.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <string.h>
3#include <stdarg.h>
4#include <ctype.h>
5#include <sched.h>
6#include <unistd.h>
7#include <sys/types.h>
8#include <dirent.h>
9
10#include "sysdetect.h"
11#include "linux_cpu_utils.h"
12
13#define VENDOR_UNKNOWN -1
14#define VENDOR_UNINITED 0
15#define VENDOR_INTEL_X86 1
16#define VENDOR_AMD 2
17#define VENDOR_IBM 3
18#define VENDOR_CRAY 4
19#define VENDOR_MIPS 8
20#define VENDOR_INTEL_IA64 9
21#define VENDOR_ARM_ARM 65
22#define VENDOR_ARM_BROADCOM 66
23#define VENDOR_ARM_CAVIUM 67
24#define VENDOR_ARM_FUJITSU 70
25#define VENDOR_ARM_HISILICON 72
26#define VENDOR_ARM_APM 80
27#define VENDOR_ARM_QUALCOMM 81
28
29#define _PATH_SYS_SYSTEM "/sys/devices/system/"
30#define _PATH_SYS_CPU0 _PATH_SYS_SYSTEM "/cpu/cpu0"
31
32static int get_topology_info( const char *key, int *value );
33static int get_naming_info( const char *key, char *value );
34static int get_versioning_info( const char *key, int *value );
35static int get_cache_info( CPU_attr_e attr, int level, int *value );
36static int get_cache_level( const char *dirname, int *value );
37static int get_cache_type( const char *dirname, int *value );
38static int get_cache_size( const char *dirname, int *value );
39static int get_cache_line_size( const char *dirname, int *value );
40static int get_cache_associativity( const char *dirname, int *value );
41static int get_cache_partition_count( const char *dirname, int *value );
42static int get_cache_set_count( const char *dirname, int *value );
43static int get_mem_info( int node, int *value );
44static int get_thread_affinity( int thread, int *value );
45static int path_sibling( const char *path, ... );
46static char *search_cpu_info( FILE *fp, const char *key );
47static int path_exist( const char *path, ... );
48static void decode_vendor_string( char *s, int *vendor );
49static int get_vendor_id( void );
50
51int
52linux_cpu_get_vendor( char *vendor )
53{
54 const char *namekey_x86 = "vendor_id";
55 const char *namekey_ia64 = "vendor";
56 const char *namekey_ibm = "platform";
57 const char *namekey_mips = "system type";
58 const char *namekey_arm = "CPU implementer";
59 const char *namekey_dum = "none";
60
61 const char *namekey_ptr = NULL;
62
63 int vendor_id = get_vendor_id();
64
65 if (vendor_id == VENDOR_INTEL_X86 || vendor_id == VENDOR_AMD) {
66 namekey_ptr = namekey_x86;
67 } else if (vendor_id == VENDOR_INTEL_IA64) {
68 namekey_ptr = namekey_ia64;
69 } else if (vendor_id == VENDOR_IBM) {
70 namekey_ptr = namekey_ibm;
71 } else if (vendor_id == VENDOR_MIPS) {
72 namekey_ptr = namekey_mips;
73 } else if (vendor_id == VENDOR_ARM_ARM ||
74 vendor_id == VENDOR_ARM_BROADCOM ||
75 vendor_id == VENDOR_ARM_CAVIUM ||
76 vendor_id == VENDOR_ARM_FUJITSU ||
77 vendor_id == VENDOR_ARM_HISILICON ||
78 vendor_id == VENDOR_ARM_APM ||
79 vendor_id == VENDOR_ARM_QUALCOMM) {
80 namekey_ptr = namekey_arm;
81 } else {
82 namekey_ptr = namekey_dum;
83 }
84
85 return get_naming_info(namekey_ptr, vendor);
86}
87
88int
90{
91 const char *namekey_x86 = "model name";
92 const char *namekey_ibm = "model";
93 const char *namekey_arm = "model name";
94 const char *namekey_dum = "none";
95
96 const char *namekey_ptr = NULL;
97
98 int vendor_id = get_vendor_id();
99
100 if (vendor_id == VENDOR_INTEL_X86 || vendor_id == VENDOR_AMD) {
101 namekey_ptr = namekey_x86;
102 } else if (vendor_id == VENDOR_IBM) {
103 namekey_ptr = namekey_ibm;
104 } else if (vendor_id == VENDOR_ARM_ARM ||
105 vendor_id == VENDOR_ARM_BROADCOM ||
106 vendor_id == VENDOR_ARM_CAVIUM ||
107 vendor_id == VENDOR_ARM_FUJITSU ||
108 vendor_id == VENDOR_ARM_HISILICON ||
109 vendor_id == VENDOR_ARM_APM ||
110 vendor_id == VENDOR_ARM_QUALCOMM) {
111 namekey_ptr = namekey_arm;
112 } else {
113 namekey_ptr = namekey_dum;
114 }
115
116 return get_naming_info(namekey_ptr, name);
117}
118
119int
121{
122 int status = CPU_SUCCESS;
123
124#define TOPOKEY_NUM_KEY 4
125#define VERKEY_NUM_KEY 4
126
127 int topo_idx = TOPOKEY_NUM_KEY;
128 int ver_idx = VERKEY_NUM_KEY;
129
130 const char *topokey[TOPOKEY_NUM_KEY] = {
131 "sockets",
132 "nodes",
133 "threads",
134 "cores",
135 };
136
137 const char *verkey_x86[VERKEY_NUM_KEY] = {
138 "cpu family", /* cpuid_family */
139 "model", /* cpuid_model */
140 "stepping", /* cpuid_stepping */
141 "vendor_id", /* vendor id */
142 };
143
144 const char *verkey_ibm[VERKEY_NUM_KEY] = {
145 "none", /* cpuid_family */
146 "none", /* cpuid_model */
147 "revision", /* cpuid_stepping */
148 "vendor_id", /* vendor id */
149 };
150
151 const char *verkey_arm[VERKEY_NUM_KEY] = {
152 "CPU architecture", /* cpuid_family */
153 "CPU part", /* cpuid_model */
154 "CPU variant", /* cpuid_stepping */
155 "CPU implementer", /* vendor id */
156 };
157
158 const char *verkey_dum[VERKEY_NUM_KEY] = {
159 "none",
160 "none",
161 "none",
162 "none",
163 };
164
165 const char **verkey_ptr = NULL;
166
167 int vendor_id = get_vendor_id();
168
169 if (vendor_id == VENDOR_INTEL_X86 || vendor_id == VENDOR_AMD) {
170 verkey_ptr = verkey_x86;
171 } else if (vendor_id == VENDOR_IBM) {
172 verkey_ptr = verkey_ibm;
173 } else if (vendor_id == VENDOR_ARM_ARM ||
174 vendor_id == VENDOR_ARM_BROADCOM ||
175 vendor_id == VENDOR_ARM_CAVIUM ||
176 vendor_id == VENDOR_ARM_FUJITSU ||
177 vendor_id == VENDOR_ARM_HISILICON ||
178 vendor_id == VENDOR_ARM_APM ||
179 vendor_id == VENDOR_ARM_QUALCOMM) {
180 verkey_ptr = verkey_arm;
181 } else {
182 verkey_ptr = verkey_dum;
183 }
184
185 switch(attr) {
187 --topo_idx;
188 // fall through
190 --topo_idx;
191 // fall through
193 --topo_idx;
194 // fall through
196 --topo_idx;
197 status = get_topology_info(topokey[topo_idx], value);
198 break;
200 --ver_idx;
201 // fall through
203 --ver_idx;
204 // fall through
206 --ver_idx;
207 // fall through
209 --ver_idx;
210 status = get_versioning_info(verkey_ptr[ver_idx], value);
211 break;
214 break;
215 default:
216 status = CPU_ERROR;
217 }
218
219 return status;
220}
221
222int
223linux_cpu_get_attribute_at( CPU_attr_e attr, int loc, int *value )
224{
225 int status = CPU_SUCCESS;
226
227 switch(attr) {
243 status = get_cache_info(attr, loc, value);
244 break;
246 status = get_mem_info(loc, value);
247 break;
249 status = get_thread_affinity(loc, value);
250 break;
251 default:
252 status = CPU_ERROR;
253 }
254
255 return status;
256}
257
258int
260{
261 cpu_set_t cpuset;
262
263 CPU_ZERO(&cpuset);
264 CPU_SET(cpu, &cpuset);
265
266 return sched_setaffinity(0, sizeof(cpuset), &cpuset);
267}
268
269int
271{
272 return sysconf(_SC_NPROCESSORS_CONF);
273}
274
275static cpu_set_t saved_affinity;
276
277int
279{
280 if (!CPU_COUNT(&saved_affinity))
281 return sched_getaffinity(0, sizeof(cpu_set_t), &saved_affinity);
282
283 return CPU_SUCCESS;
284}
285
286int
288{
289 return sched_setaffinity(0, sizeof(cpu_set_t), &saved_affinity);
290}
291
292int
293get_topology_info( const char *key, int *val )
294{
295 int status = CPU_SUCCESS;
296 static int sockets, nodes, threads, cores;
297
298 if (!strcmp("sockets", key) && sockets) {
299 *val = sockets;
300 return status;
301 } else if (!strcmp("nodes", key) && nodes) {
302 *val = nodes;
303 return status;
304 } else if (!strcmp("threads", key) && threads) {
305 *val = threads;
306 return status;
307 } else if (!strcmp("cores", key) && cores) {
308 *val = cores;
309 return status;
310 }
311
312 /* Query topology information once and store results for later */
313 int totalcpus = 0;
314
315 while (path_exist(_PATH_SYS_SYSTEM "/cpu/cpu%d", totalcpus)) {
316 ++totalcpus;
317 }
318
319 if (path_exist(_PATH_SYS_CPU0 "/topology/thread_siblings")) {
320 threads = path_sibling(_PATH_SYS_CPU0 "/topology/thread_siblings");
321 }
322
323 if (path_exist(_PATH_SYS_CPU0 "/topology/core_siblings")) {
324 cores = path_sibling(_PATH_SYS_CPU0 "/topology/core_siblings") / threads;
325 }
326
327 sockets = totalcpus / cores / threads;
328
329 while (path_exist(_PATH_SYS_SYSTEM "/node/node%d", nodes))
330 ++nodes;
331
332 if (!strcmp("sockets", key)) {
333 *val = sockets;
334 } else if (!strcmp("nodes", key)) {
335 *val = (nodes == 0) ? nodes = 1 : nodes;
336 } else if (!strcmp("cores", key)) {
337 *val = cores;
338 } else if (!strcmp("threads", key)) {
339 *val = threads;
340 } else {
341 status = CPU_ERROR;
342 }
343
344 return status;
345}
346
347int
348get_naming_info( const char *key, char *val )
349{
350 if (!strcmp(key, "none")) {
351 strcpy(val, "UNKNOWN");
352 return CPU_SUCCESS;
353 }
354
355 FILE *fp = fopen("/proc/cpuinfo", "r");
356 if (fp == NULL) {
357 return CPU_ERROR;
358 }
359
360 char *str = search_cpu_info(fp, key);
361 if (str) {
362 strncpy(val, str, PAPI_MAX_STR_LEN);
363 val[PAPI_MAX_STR_LEN - 1] = 0;
364 }
365
366 fclose(fp);
367
368 return CPU_SUCCESS;
369}
370
371int
372get_versioning_info( const char *key, int *val )
373{
374 if (!strcmp(key, "none")) {
375 *val = -1;
376 return CPU_SUCCESS;
377 }
378
379 if (!strcmp(key, "vendor_id") || !strcmp(key, "CPU implementer")) {
380 *val = get_vendor_id();
381 return CPU_SUCCESS;
382 }
383
384 FILE *fp = fopen("/proc/cpuinfo", "r");
385 if (fp == NULL) {
386 return CPU_ERROR;
387 }
388
389 char *str = search_cpu_info(fp, key);
390 if (str) {
391 /* FIXME: this is a ugly hack to handle old (prior to Linux 3.19) ARM64 */
392 if (strcmp(key, "CPU architecture") == 0) {
393 /* Prior version 3.19 'CPU architecture' is always 'AArch64'
394 * so we convert it to '8', which is the value since 3.19. */
395 if (strstr(str, "AArch64"))
396 *val = 8;
397 else
398 *val = strtol(str, NULL, 10);
399
400 /* Old Fallbacks if the above didn't work (e.g. Raspberry Pi) */
401 if (*val < 0) {
402 str = search_cpu_info(fp, "Processor");
403 if (str) {
404 char *t = strchr(str, '(');
405 int tmp = *(t + 2) - '0';
406 *val = tmp;
407 } else {
408 /* Try the model name and look inside of parens */
409 str = search_cpu_info(fp, "model name");
410 if (str) {
411 char *t = strchr(str, '(');
412 int tmp = *(t + 2) - '0';
413 *val = tmp;
414 }
415 }
416 }
417 } else {
418 sscanf(str, "%x", val);
419 }
420 }
421
422 fclose(fp);
423
424 return CPU_SUCCESS;
425}
426
428
429int
430get_cache_info( CPU_attr_e attr, int level, int *val )
431{
432 int type = 0;
433 int size, line_size, associativity, sets;
434 DIR *dir;
435 struct dirent *d;
436 int max_level = 0;
437 int *level_count, level_index;
439
440 if (L) {
441 return cpu_get_cache_info(attr, level, L, val);
442 }
443
444 L = clevel;
445
446 /* open Linux cache dir */
447 /* assume all CPUs same as cpu0. */
448 /* Not necessarily a good assumption */
449
450 dir = opendir("/sys/devices/system/cpu/cpu0/cache");
451 if (dir == NULL) {
452 goto fn_fail;
453 }
454
455 while(1) {
456 d = readdir(dir);
457 if (d == NULL)
458 break;
459
460 if (strncmp(d->d_name, "index", 5))
461 continue;
462
463 if (get_cache_level(d->d_name, &level_index)) {
464 goto fn_fail;
465 }
466
467 if (get_cache_type(d->d_name, &type)) {
468 goto fn_fail;
469 }
470 level_count = &L[level_index].num_caches;
471 L[level_index].cache[*level_count].type = type;
472
473 if (get_cache_size(d->d_name, &size)) {
474 goto fn_fail;
475 }
476 /* Linux reports in kB, PAPI expects in Bytes */
477 L[level_index].cache[*level_count].size = size * 1024;
478
479 if (get_cache_line_size(d->d_name, &line_size)) {
480 goto fn_fail;
481 }
482 L[level_index].cache[*level_count].line_size = line_size;
483
484 if (get_cache_associativity(d->d_name, &associativity)) {
485 goto fn_fail;
486 }
487 L[level_index].cache[*level_count].associativity = associativity;
488
489 int partitions;
490 if (get_cache_partition_count(d->d_name, &partitions)) {
491 goto fn_fail;
492 }
493
494 if (get_cache_set_count(d->d_name, &sets)) {
495 goto fn_fail;
496 }
497 L[level_index].cache[*level_count].num_lines =
498 (sets * associativity * partitions);
499
500 if (((size * 1024) / line_size / associativity) != sets) {
501 MEMDBG("Warning! sets %d != expected %d\n",
502 sets, ((size * 1024) / line_size / associativity));
503 }
504
505 if (level > max_level) {
506 max_level = level;
507 }
508
509 if (level >= PAPI_MAX_MEM_HIERARCHY_LEVELS) {
510 MEMDBG("Exceeded maximum cache level %d\n",
512 break;
513 }
514
515 ++(*level_count);
516 }
517
518 closedir(dir);
519 return cpu_get_cache_info(attr, level, L, val);
520
521 fn_fail:
522 closedir(dir);
523 return CPU_ERROR;
524}
525
526int
527get_cache_level( const char *dirname, int *value )
528{
529 char filename[BUFSIZ];
530 int level_index;
531
532 sprintf(filename, "/sys/devices/system/cpu/cpu0/cache/%s/level",
533 dirname);
534
535 FILE *fff = fopen(filename,"r");
536 if (fff == NULL) {
537 MEMDBG("Cannot open level.\n");
538 return CPU_ERROR;
539 }
540
541 int result = fscanf(fff, "%d", &level_index);
542 fclose(fff);
543 if (result != 1) {
544 MEMDBG("Could not read cache level\n");
545 return CPU_ERROR;
546 }
547
548 /* Index arrays from 0 */
549 level_index -= 1;
550 *value = level_index;
551
552 return CPU_SUCCESS;
553}
554
555int
556get_cache_type( const char *dirname, int *value )
557{
558 char filename[BUFSIZ];
559 char type_string[BUFSIZ];
560 int type;
561
562 sprintf(filename, "/sys/devices/system/cpu/cpu0/cache/%s/type",
563 dirname);
564
565 FILE *fff = fopen(filename, "r");
566 if (fff == NULL) {
567 MEMDBG("Cannot open type\n");
568 return CPU_ERROR;
569 }
570
571 char *result = fgets(type_string, BUFSIZ, fff);
572 fclose(fff);
573 if (result == NULL) {
574 MEMDBG("Could not read cache type\n");
575 return CPU_ERROR;
576 }
577
578 if (!strcmp(type_string, "Data")) {
580 }
581
582 if (!strcmp(type_string, "Instruction")) {
584 }
585
586 if (!strcmp(type_string, "Unified")) {
588 }
589
590 *value = type;
591
592 return CPU_SUCCESS;
593}
594
595int
596get_cache_size( const char *dirname, int *value )
597{
598 char filename[BUFSIZ];
599 int size;
600
601 sprintf(filename, "/sys/devices/system/cpu/cpu0/cache/%s/size",
602 dirname);
603
604 FILE *fff = fopen(filename, "r");
605 if (fff == NULL) {
606 MEMDBG("Cannot open size\n");
607 return CPU_ERROR;
608 }
609
610 int result = fscanf(fff, "%d", &size);
611 fclose(fff);
612 if (result != 1) {
613 MEMDBG("Could not read cache size\n");
614 return CPU_ERROR;
615 }
616
617 *value = size;
618
619 return CPU_SUCCESS;
620}
621
622int
623get_cache_line_size( const char *dirname, int *value )
624{
625 char filename[BUFSIZ];
626 int line_size;
627
628 sprintf(filename, "/sys/devices/system/cpu/cpu0/cache/%s/coherency_line_size",
629 dirname);
630
631 FILE *fff = fopen(filename, "r");
632 if (fff == NULL) {
633 MEMDBG("Cannot open linesize\n");
634 return CPU_ERROR;
635 }
636
637 int result = fscanf(fff, "%d", &line_size);
638 fclose(fff);
639 if (result != 1) {
640 MEMDBG("Could not read cache line-size\n");
641 return CPU_ERROR;
642 }
643
644 *value = line_size;
645
646 return CPU_SUCCESS;
647}
648
649int
650get_cache_associativity( const char *dirname, int *value )
651{
652 char filename[BUFSIZ];
653 int associativity;
654
655 sprintf(filename, "/sys/devices/system/cpu/cpu0/cache/%s/ways_of_associativity",
656 dirname);
657
658 FILE *fff = fopen(filename, "r");
659 if (fff == NULL) {
660 MEMDBG("Cannot open associativity\n");
661 return CPU_ERROR;
662 }
663
664 int result = fscanf(fff, "%d", &associativity);
665 fclose(fff);
666 if (result != 1) {
667 MEMDBG("Could not read cache associativity\n");
668 return CPU_ERROR;
669 }
670
671 *value = associativity;
672
673 return CPU_SUCCESS;
674}
675
676int
677get_cache_partition_count( const char *dirname, int *value )
678{
679 char filename[BUFSIZ];
680 int partitions;
681
682 sprintf(filename, "/sys/devices/system/cpu/cpu0/cache/%s/physical_line_partition",
683 dirname);
684
685 FILE *fff = fopen(filename, "r");
686 if (fff == NULL) {
687 MEMDBG("Cannot open partitions\n");
688 return CPU_ERROR;
689 }
690
691 int result = fscanf(fff, "%d", &partitions);
692 fclose(fff);
693 if (result != 1) {
694 MEMDBG("Could not read partitions count\n");
695 return CPU_ERROR;
696 }
697
698 *value = partitions;
699
700 return CPU_SUCCESS;
701}
702
703int
704get_cache_set_count( const char *dirname, int *value )
705{
706 char filename[BUFSIZ];
707 int sets;
708
709 sprintf(filename, "/sys/devices/system/cpu/cpu0/cache/%s/number_of_sets",
710 dirname);
711
712 FILE *fff = fopen(filename, "r");
713 if (fff == NULL) {
714 MEMDBG("Cannot open sets\n");
715 return CPU_ERROR;
716 }
717
718 int result = fscanf(fff, "%d", &sets);
719 fclose(fff);
720 if (result != 1) {
721 MEMDBG("Could not read cache sets\n");
722 return CPU_ERROR;
723 }
724
725 *value = sets;
726
727 return CPU_SUCCESS;
728}
729
730int
731get_mem_info( int node, int *val )
732{
733 if (path_exist(_PATH_SYS_SYSTEM "/node/node%d", node)) {
734 char filename[PAPI_MAX_STR_LEN];
735 sprintf(filename, _PATH_SYS_SYSTEM "/node/node%d/meminfo", node);
736 FILE *fp = fopen(filename, "r");
737 if (!fp) {
738 return CPU_ERROR;
739 }
740
741 char search_str[PAPI_MIN_STR_LEN];
742 sprintf(search_str, "Node %d MemTotal", node);
743 char *str = search_cpu_info(fp, search_str);
744 if (str) {
745 sprintf(search_str, "%s", str);
746 int len = strlen(search_str);
747 search_str[len-3] = '\0'; /* Remove trailing "KB" */
748 *val = atoi(search_str);
749 }
750
751 fclose(fp);
752 }
753
754 return CPU_SUCCESS;
755}
756
757int
759{
760 if (!path_exist(_PATH_SYS_SYSTEM "/cpu/cpu0/node0")) {
761 *val = 0;
762 return CPU_SUCCESS;
763 }
764
765 int i = 0;
766 while (!path_exist(_PATH_SYS_SYSTEM "/cpu/cpu%d/node%d", thread, i)) {
767 ++i;
768 }
769 *val = i;
770
771 return CPU_SUCCESS;
772}
773
774static char pathbuf[PATH_MAX] = "/";
775
776FILE *
777xfopen( const char *path, const char *mode )
778{
779 FILE *fd = fopen(path, mode);
780 return fd;
781}
782
783FILE *
784path_vfopen( const char *mode, const char *path, va_list ap )
785{
786 vsnprintf( pathbuf, sizeof ( pathbuf ), path, ap );
787 return xfopen( pathbuf, mode );
788}
789
790int
791path_sibling( const char *path, ... )
792{
793 int c;
794 long n;
795 int result = CPU_SUCCESS;
796 char s[2];
797 FILE *fp;
798 va_list ap;
799 va_start( ap, path );
800 fp = path_vfopen( "r", path, ap );
801 va_end( ap );
802
803 while ((c = fgetc(fp)) != EOF) {
804 if (isxdigit(c)) {
805 s[0] = (char) c;
806 s[1] = '\0';
807 for (n = strtol(s, NULL, 16); n > 0; n /= 2) {
808 if (n % 2)
809 result++;
810 }
811 }
812 }
813
814 fclose(fp);
815 return result;
816}
817
818char *
819search_cpu_info( FILE * f, const char *search_str )
820{
821 static char line[PAPI_HUGE_STR_LEN] = "";
822 char *s, *start = NULL;
823
824 rewind(f);
825
826 while (fgets(line, PAPI_HUGE_STR_LEN,f) != NULL) {
827 s=strstr(line, search_str);
828 if (s != NULL) {
829 /* skip all characters in line up to the colon */
830 /* and then spaces */
831 s=strchr(s, ':');
832 if (s == NULL) break;
833 s++;
834 while (isspace(*s)) {
835 s++;
836 }
837 start = s;
838 /* Find and clear newline */
839 s=strrchr(start, '\n');
840 if (s != NULL) *s = 0;
841 break;
842 }
843 }
844
845 return start;
846}
847
848int
849path_exist( const char *path, ... )
850{
851 va_list ap;
852 va_start(ap, path);
853 vsnprintf(pathbuf, sizeof ( pathbuf ), path, ap);
854 va_end(ap);
855 return access(pathbuf, F_OK) == 0;
856}
857
858void
859decode_vendor_string( char *s, int *vendor )
860{
861 if (strcasecmp(s, "GenuineIntel") == 0)
862 *vendor = VENDOR_INTEL_X86;
863 else if ((strcasecmp(s, "AMD") == 0) ||
864 (strcasecmp(s, "AuthenticAMD") == 0 ))
865 *vendor = VENDOR_AMD;
866 else if (strcasecmp(s, "IBM") == 0)
867 *vendor = VENDOR_IBM;
868 else if (strcasecmp(s, "Cray") == 0)
869 *vendor = VENDOR_CRAY;
870 else if (strcasecmp(s, "ARM_ARM") == 0)
871 *vendor = VENDOR_ARM_ARM;
872 else if (strcasecmp(s, "ARM_BROADCOM") == 0)
873 *vendor = VENDOR_ARM_BROADCOM;
874 else if (strcasecmp(s, "ARM_CAVIUM") == 0)
875 *vendor = VENDOR_ARM_CAVIUM;
876 else if (strcasecmp(s, "ARM_FUJITSU") == 0)
877 *vendor = VENDOR_ARM_FUJITSU;
878 else if (strcasecmp(s, "ARM_HISILICON") == 0)
879 *vendor = VENDOR_ARM_HISILICON;
880 else if (strcasecmp(s, "ARM_APM") == 0)
881 *vendor = VENDOR_ARM_APM;
882 else if (strcasecmp(s, "ARM_QUALCOMM") == 0)
883 *vendor = VENDOR_ARM_QUALCOMM;
884 else if (strcasecmp(s, "MIPS") == 0)
885 *vendor = VENDOR_MIPS;
886 else if (strcasecmp(s, "SiCortex") == 0)
887 *vendor = VENDOR_MIPS;
888 else
889 *vendor = VENDOR_UNKNOWN;
890}
891
892int
894{
895 static int vendor_id; // VENDOR_UNINITED;
896
897 if (vendor_id != VENDOR_UNINITED)
898 return vendor_id;
899
900 FILE *fp = fopen("/proc/cpuinfo", "r");
901 if (fp == NULL) {
902 return CPU_ERROR;
903 }
904
905 char vendor_string[PAPI_MAX_STR_LEN] = "";
906 char *s = search_cpu_info(fp, "vendor_id");
907 if (s) {
908 strncpy(vendor_string, s, PAPI_MAX_STR_LEN);
909 vendor_string[PAPI_MAX_STR_LEN - 1] = 0;
910 } else {
911 s = search_cpu_info(fp, "vendor");
912 if (s) {
913 strncpy(vendor_string, s, PAPI_MAX_STR_LEN);
914 vendor_string[PAPI_MAX_STR_LEN - 1] = 0;
915 } else {
916 s = search_cpu_info(fp, "system type");
917 if (s) {
918 strncpy(vendor_string, s, PAPI_MAX_STR_LEN);
919 vendor_string[PAPI_MAX_STR_LEN - 1] = 0;
920 } else {
921 s = search_cpu_info(fp, "platform");
922 if (s) {
923 if (strcasecmp(s, "pSeries") == 0 ||
924 strcasecmp(s, "PowerNV") == 0 ||
925 strcasecmp(s, "PowerMac") == 0) {
926 strcpy(vendor_string, "IBM");
927 }
928 } else {
929 s = search_cpu_info(fp, "CPU implementer");
930 if (s) {
931 int tmp;
932 sscanf(s, "%x", &tmp);
933 switch(tmp) {
934 case VENDOR_ARM_ARM:
935 strcpy(vendor_string, "ARM_ARM");
936 break;
938 strcpy(vendor_string, "ARM_BROADCOM");
939 break;
941 strcpy(vendor_string, "ARM_CAVIUM");
942 break;
944 strcpy(vendor_string, "ARM_FUJITSU");
945 break;
947 strcpy(vendor_string, "ARM_HISILICON");
948 break;
949 case VENDOR_ARM_APM:
950 strcpy(vendor_string, "ARM_APM");
951 break;
953 strcpy(vendor_string, "ARM_QUALCOMM");
954 break;
955 default:
956 strcpy(vendor_string, "UNKNOWN");
957 }
958 }
959 }
960 }
961 }
962 }
963
964 if (strlen(vendor_string)) {
965 decode_vendor_string(vendor_string, &vendor_id);
966 }
967
968 fclose(fp);
969 return vendor_id;
970}
volatile int result
double tmp
int i
double s
Definition: byte_profile.c:36
double f(double a)
Definition: cpi.c:23
int cpu_get_cache_info(CPU_attr_e attr, int level, _sysdetect_cache_level_info_t *clevel_ptr, int *value)
Definition: cpu_utils.c:94
#define CPU_ERROR
Definition: cpu_utils.h:5
#define CPU_SUCCESS
Definition: cpu_utils.h:4
CPU_attr_e
Definition: cpu_utils.h:7
@ CPU_ATTR__CPUID_MODEL
Definition: cpu_utils.h:14
@ CPU_ATTR__CACHE_MAX_NUM_LEVELS
Definition: cpu_utils.h:17
@ CPU_ATTR__NUM_THREADS
Definition: cpu_utils.h:11
@ CPU_ATTR__CPUID_FAMILY
Definition: cpu_utils.h:13
@ CPU_ATTR__CACHE_INST_TOT_SIZE
Definition: cpu_utils.h:21
@ CPU_ATTR__HWTHREAD_NUMA_AFFINITY
Definition: cpu_utils.h:34
@ CPU_ATTR__CACHE_UNIF_TOT_SIZE
Definition: cpu_utils.h:29
@ CPU_ATTR__CACHE_DATA_ASSOCIATIVITY
Definition: cpu_utils.h:28
@ CPU_ATTR__CACHE_INST_LINE_SIZE
Definition: cpu_utils.h:22
@ CPU_ATTR__NUMA_MEM_SIZE
Definition: cpu_utils.h:36
@ CPU_ATTR__NUM_NODES
Definition: cpu_utils.h:9
@ CPU_ATTR__CACHE_UNIF_LINE_SIZE
Definition: cpu_utils.h:30
@ CPU_ATTR__CACHE_DATA_NUM_LINES
Definition: cpu_utils.h:27
@ CPU_ATTR__CACHE_UNIF_ASSOCIATIVITY
Definition: cpu_utils.h:32
@ CPU_ATTR__CPUID_STEPPING
Definition: cpu_utils.h:15
@ CPU_ATTR__CACHE_INST_PRESENT
Definition: cpu_utils.h:18
@ CPU_ATTR__NUM_CORES
Definition: cpu_utils.h:10
@ CPU_ATTR__CACHE_DATA_PRESENT
Definition: cpu_utils.h:19
@ CPU_ATTR__CACHE_DATA_LINE_SIZE
Definition: cpu_utils.h:26
@ CPU_ATTR__CACHE_INST_ASSOCIATIVITY
Definition: cpu_utils.h:24
@ CPU_ATTR__CACHE_INST_NUM_LINES
Definition: cpu_utils.h:23
@ CPU_ATTR__CACHE_UNIF_NUM_LINES
Definition: cpu_utils.h:31
@ CPU_ATTR__CACHE_DATA_TOT_SIZE
Definition: cpu_utils.h:25
@ CPU_ATTR__NUM_SOCKETS
Definition: cpu_utils.h:8
@ CPU_ATTR__VENDOR_ID
Definition: cpu_utils.h:12
@ CPU_ATTR__CACHE_UNIF_PRESENT
Definition: cpu_utils.h:20
#define PAPI_MIN_STR_LEN
Definition: f90papi.h:208
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_MAX_MEM_HIERARCHY_LEVELS
Definition: f90papi.h:103
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
FILE * fff[MAX_EVENTS]
static pthread_key_t key
static struct timeval start
void * thread(void *arg)
Definition: kufrin.c:38
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
uint16_t type
int linux_cpu_get_attribute_at(CPU_attr_e attr, int loc, int *value)
static int get_vendor_id(void)
static void decode_vendor_string(char *s, int *vendor)
static int get_topology_info(const char *key, int *value)
#define _PATH_SYS_CPU0
int linux_cpu_load_affinity(void)
int linux_cpu_get_name(char *name)
#define VENDOR_ARM_CAVIUM
static char pathbuf[PATH_MAX]
static int get_cache_type(const char *dirname, int *value)
FILE * xfopen(const char *path, const char *mode)
#define VENDOR_ARM_HISILICON
static int get_thread_affinity(int thread, int *value)
int linux_cpu_store_affinity(void)
static int get_cache_partition_count(const char *dirname, int *value)
static _sysdetect_cache_level_info_t clevel[PAPI_MAX_MEM_HIERARCHY_LEVELS]
#define VENDOR_UNINITED
static int get_cache_line_size(const char *dirname, int *value)
static int get_cache_size(const char *dirname, int *value)
#define _PATH_SYS_SYSTEM
static int get_cache_set_count(const char *dirname, int *value)
static int get_mem_info(int node, int *value)
#define VENDOR_ARM_BROADCOM
static cpu_set_t saved_affinity
#define VENDOR_INTEL_X86
#define VENDOR_ARM_ARM
#define VERKEY_NUM_KEY
int linux_cpu_get_num_supported(void)
#define VENDOR_CRAY
int linux_cpu_set_affinity(int cpu)
static int get_naming_info(const char *key, char *value)
static int path_exist(const char *path,...)
#define VENDOR_AMD
static int path_sibling(const char *path,...)
#define TOPOKEY_NUM_KEY
#define VENDOR_MIPS
#define VENDOR_UNKNOWN
int linux_cpu_get_vendor(char *vendor)
#define VENDOR_ARM_QUALCOMM
FILE * path_vfopen(const char *mode, const char *path, va_list ap)
static int get_cache_info(CPU_attr_e attr, int level, int *value)
#define VENDOR_INTEL_IA64
static int get_versioning_info(const char *key, int *value)
#define VENDOR_IBM
#define VENDOR_ARM_FUJITSU
static int get_cache_associativity(const char *dirname, int *value)
static char * search_cpu_info(FILE *fp, const char *key)
#define VENDOR_ARM_APM
static int get_cache_level(const char *dirname, int *value)
int linux_cpu_get_attribute(CPU_attr_e attr, int *value)
#define PAPI_MH_TYPE_DATA
Definition: papi.h:720
#define PAPI_MH_TYPE_INST
Definition: papi.h:719
#define PAPI_MH_TYPE_UNIFIED
Definition: papi.h:723
#define MEMDBG(format, args...)
Definition: papi_debug.h:71
__gnuc_va_list va_list
int fclose(FILE *__stream)
static FILE * fp
va_end(arg_list)
va_start(arg_list, fmt)
const char * name
Definition: rocs.c:225
PAPI_mh_cache_info_t cache[PAPI_MH_MAX_LEVELS]
Definition: sysdetect.h:57