/* * (C) 2004-2009 Dominik Brodowski * * Licensed under the terms of the GNU GPL License version 2. */ #include #include #include #include #include #include #include #include "cpupower.h" #include "cpupower_intern.h" unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) { int fd; ssize_t numread; fd = open(path, O_RDONLY); if (fd == -1) return 0; numread = read(fd, buf, buflen - 1); if (numread < 1) { close(fd); return 0; } buf[numread] = '\0'; close(fd); return (unsigned int) numread; } /* * Detect whether a CPU is online * * Returns: * 1 -> if CPU is online * 0 -> if CPU is offline * negative errno values in error case */ int cpupower_is_cpu_online(unsigned int cpu) { char path[SYSFS_PATH_MAX]; int fd; ssize_t numread; unsigned long long value; char linebuf[MAX_LINE_LEN]; char *endp; struct stat statbuf; snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu); if (stat(path, &statbuf) != 0) return 0; /* * kernel without CONFIG_HOTPLUG_CPU * -> cpuX directory exists, but not cpuX/online file */ snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu); if (stat(path, &statbuf) != 0) return 1; fd = open(path, O_RDONLY); if (fd == -1) return -errno; numread = read(fd, linebuf, MAX_LINE_LEN - 1); if (numread < 1) { close(fd); return -EIO; } linebuf[numread] = '\0'; close(fd); value = strtoull(linebuf, &endp, 0); if (value > 1) return -EINVAL; return value; } /* returns -1 on failure, 0 on success */ static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *result) { char linebuf[MAX_LINE_LEN]; char *endp; char path[SYSFS_PATH_MAX]; snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", cpu, fname); if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0) return -1; *result = strtol(linebuf, &endp, 0); if (endp == linebuf || errno == ERANGE) return -1; return 0; } static int __compare(const void *t1, const void *t2) { struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1; struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2; if (top1->pkg < top2->pkg) return -1; else if (top1->pkg > top2->pkg) return 1; else if (top1->core < top2->core) return -1; else if (top1->core > top2->core) return 1; else if (top1->cpu < top2->cpu) return -1; else if (top1->cpu > top2->cpu) return 1; else return 0; } /* * Returns amount of cpus, negative on error, cpu_top must be * passed to cpu_topology_release to free resources * * Array is sorted after ->pkg, ->core, then ->cpu */ int get_cpu_topology(struct cpupower_topology *cpu_top) { int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF); cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus); if (cpu_top->core_info == NULL) return -ENOMEM; cpu_top->pkgs = cpu_top->cores = 0; for (cpu = 0; cpu < cpus; cpu++) { cpu_top->core_info[cpu].cpu = cpu; cpu_top->core_info[cpu].is_online = cpupower_is_cpu_online(cpu); if(sysfs_topology_read_file( cpu, "physical_package_id", &(cpu_top->core_info[cpu].pkg)) < 0) { cpu_top->core_info[cpu].pkg = -1; cpu_top->core_info[cpu].core = -1; continue; } if(sysfs_topology_read_file( cpu, "core_id", &(cpu_top->core_info[cpu].core)) < 0) { cpu_top->core_info[cpu].pkg = -1; cpu_top->core_info[cpu].core = -1; continue; } } qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), __compare); /* Count the number of distinct pkgs values. This works because the primary sort of the core_info struct was just done by pkg value. */ last_pkg = cpu_top->core_info[0].pkg; for(cpu = 1; cpu < cpus; cpu++) { if (cpu_top->core_info[cpu].pkg != last_pkg && cpu_top->core_info[cpu].pkg != -1) { last_pkg = cpu_top->core_info[cpu].pkg; cpu_top->pkgs++; } } if (!(cpu_top->core_info[0].pkg == -1)) cpu_top->pkgs++; /* Intel's cores count is not consecutively numbered, there may * be a core_id of 3, but none of 2. Assume there always is 0 * Get amount of cores by counting duplicates in a package for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) { if (cpu_top->core_info[cpu].core == 0) cpu_top->cores++; */ return cpus; } void cpu_topology_release(struct cpupower_topology cpu_top) { free(cpu_top.core_info); } ludemode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2016-12-05 09:41:41 -0200
committerJonathan Corbet <corbet@lwn.net>2016-12-05 14:21:24 -0700
commitf15c323397f87b978f4057eb1462efcbf487493a (patch)
tree571deb44f3584bec33ab217767acdacde4123e14 /tools/build/feature/test-libunwind-debug-frame-arm.c
parent20b786eb2598ac10c9743535b65611ce808c8d71 (diff)
scripts: add a script to check if Documentation/00-INDEX is sane
It is easy to forget adding/removing entries at the Documentation/00-INDEX file. In a matter of fact, even before ReST conversion, people use to forget adding things here, as there are lots of missing stuff out there. Now that we're doing a hard work converting entries to ReST, and while this hole file is not outdated, it is good to have some tool that would help to verify that this file is kept updated. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'tools/build/feature/test-libunwind-debug-frame-arm.c')