mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-25 07:50:40 +01:00
[v1.03][PPC] Fix bug where /sys/devices/system/cpu/cpu*/topology/physical_package_id contains -1 by adding a new way of finding the number of sockets. This happened in #178 and most probably in #153 too
This commit is contained in:
@@ -278,3 +278,99 @@ int get_num_caches_by_level(struct cpuInfo* cpu, uint32_t level) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This function is very similar to get_num_caches_from_files,
|
||||||
|
// refactoring should be considered
|
||||||
|
int get_num_sockets_from_files(char** paths, int num_paths) {
|
||||||
|
int filelen;
|
||||||
|
char* buf;
|
||||||
|
char* tmpbuf;
|
||||||
|
|
||||||
|
// 1. Count the number of bitmasks per file
|
||||||
|
if((buf = read_file(paths[0], &filelen)) == NULL) {
|
||||||
|
printWarn("Could not open '%s'", paths[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int num_bitmasks = 1;
|
||||||
|
for(int i=0; buf[i]; i++) {
|
||||||
|
num_bitmasks += (buf[i] == ',');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Read package_cpus from every core
|
||||||
|
uint32_t** package_cpus = emalloc(sizeof(uint32_t *) * num_paths);
|
||||||
|
for(int i=0; i < num_paths; i++) {
|
||||||
|
package_cpus[i] = emalloc(sizeof(uint32_t) * num_bitmasks);
|
||||||
|
|
||||||
|
if((buf = read_file(paths[i], &filelen)) == NULL) {
|
||||||
|
printWarn("Could not open '%s'", paths[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int j=0; j < num_bitmasks; j++) {
|
||||||
|
char* end;
|
||||||
|
tmpbuf = emalloc(sizeof(char) * (strlen(buf) + 1));
|
||||||
|
char* commaend = strstr(buf, ",");
|
||||||
|
if(commaend == NULL) {
|
||||||
|
strcpy(tmpbuf, buf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strncpy(tmpbuf, buf, commaend-buf);
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
long ret = strtol(tmpbuf, &end, 16);
|
||||||
|
if(errno != 0) {
|
||||||
|
printf("strtol: %s", strerror(errno));
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
package_cpus[i][j] = (uint32_t) ret;
|
||||||
|
buf = commaend + 1;
|
||||||
|
free(tmpbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Count number of different packages; this is the number of sockets
|
||||||
|
int num_sockets = 0;
|
||||||
|
bool found = false;
|
||||||
|
uint32_t** unique_package_cpu = emalloc(sizeof(uint32_t *) * num_paths);
|
||||||
|
for(int i=0; i < num_paths; i++) {
|
||||||
|
unique_package_cpu[i] = emalloc(sizeof(uint32_t) * num_bitmasks);
|
||||||
|
for(int j=0; j < num_bitmasks; j++) {
|
||||||
|
unique_package_cpu[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i < num_paths; i++) {
|
||||||
|
for(int j=0; j < num_paths && !found; j++) {
|
||||||
|
if(maps_equal(package_cpus[i], unique_package_cpu[j], num_bitmasks)) found = true;
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
add_shared_map(package_cpus, i, unique_package_cpu, num_sockets, num_bitmasks);
|
||||||
|
num_sockets++;
|
||||||
|
}
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_sockets;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_num_sockets_package_cpus(struct topology* topo) {
|
||||||
|
// Get number of sockets using
|
||||||
|
// /sys/devices/system/cpu/cpu*/topology/package_cpus
|
||||||
|
|
||||||
|
char** paths = emalloc(sizeof(char *) * topo->total_cores);
|
||||||
|
|
||||||
|
for(int i=0; i < topo->total_cores; i++) {
|
||||||
|
paths[i] = emalloc(sizeof(char) * _PATH_PACKAGE_MAX_LEN);
|
||||||
|
sprintf(paths[i], "%s%s/cpu%d%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, i, _PATH_TOPO_PACKAGE_CPUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = get_num_sockets_from_files(paths, topo->total_cores);
|
||||||
|
|
||||||
|
for(int i=0; i < topo->total_cores; i++)
|
||||||
|
free(paths[i]);
|
||||||
|
free(paths);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,9 +24,11 @@
|
|||||||
#define _PATH_CACHE_SIZE "/size"
|
#define _PATH_CACHE_SIZE "/size"
|
||||||
#define _PATH_CACHE_SHARED_MAP "/shared_cpu_map"
|
#define _PATH_CACHE_SHARED_MAP "/shared_cpu_map"
|
||||||
#define _PATH_CPUS_PRESENT _PATH_SYS_SYSTEM _PATH_SYS_CPU "/present"
|
#define _PATH_CPUS_PRESENT _PATH_SYS_SYSTEM _PATH_SYS_CPU "/present"
|
||||||
|
#define _PATH_TOPO_PACKAGE_CPUS "/topology/package_cpus"
|
||||||
|
|
||||||
#define _PATH_FREQUENCY_MAX_LEN 100
|
#define _PATH_FREQUENCY_MAX_LEN 100
|
||||||
#define _PATH_CACHE_MAX_LEN 200
|
#define _PATH_CACHE_MAX_LEN 200
|
||||||
|
#define _PATH_PACKAGE_MAX_LEN 200
|
||||||
|
|
||||||
char* read_file(char* path, int* len);
|
char* read_file(char* path, int* len);
|
||||||
long get_max_freq_from_file(uint32_t core);
|
long get_max_freq_from_file(uint32_t core);
|
||||||
@@ -36,6 +38,7 @@ long get_l1d_cache_size(uint32_t core);
|
|||||||
long get_l2_cache_size(uint32_t core);
|
long get_l2_cache_size(uint32_t core);
|
||||||
long get_l3_cache_size(uint32_t core);
|
long get_l3_cache_size(uint32_t core);
|
||||||
int get_num_caches_by_level(struct cpuInfo* cpu, uint32_t level);
|
int get_num_caches_by_level(struct cpuInfo* cpu, uint32_t level);
|
||||||
|
int get_num_sockets_package_cpus(struct topology* topo);
|
||||||
int get_ncores_from_cpuinfo(void);
|
int get_ncores_from_cpuinfo(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,17 +44,6 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
|
|||||||
return cach;
|
return cach;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_package_ids_integrity(int* package_ids, int total_cores) {
|
|
||||||
for(int i=0; i < total_cores; i++) {
|
|
||||||
if(package_ids[i] >= total_cores || package_ids[i] < 0) {
|
|
||||||
printBug("check_package_ids_integrity: package_ids[%d]=%d", i, package_ids[i]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct topology* get_topology_info(struct cache* cach) {
|
struct topology* get_topology_info(struct cache* cach) {
|
||||||
struct topology* topo = emalloc(sizeof(struct topology));
|
struct topology* topo = emalloc(sizeof(struct topology));
|
||||||
init_topology_struct(topo, cach);
|
init_topology_struct(topo, cach);
|
||||||
@@ -74,16 +63,17 @@ struct topology* get_topology_info(struct cache* cach) {
|
|||||||
printWarn("fill_core_ids_from_sys failed, output may be incomplete/invalid");
|
printWarn("fill_core_ids_from_sys failed, output may be incomplete/invalid");
|
||||||
for(int i=0; i < topo->total_cores; i++) core_ids[i] = 0;
|
for(int i=0; i < topo->total_cores; i++) core_ids[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fill_package_ids_from_sys(package_ids, topo->total_cores)) {
|
if(!fill_package_ids_from_sys(package_ids, topo->total_cores)) {
|
||||||
printWarn("fill_package_ids_from_sys failed, output may be incomplete/invalid");
|
printWarn("fill_package_ids_from_sys failed, output may be incomplete/invalid");
|
||||||
for(int i=0; i < topo->total_cores; i++) package_ids[i] = 0;
|
for(int i=0; i < topo->total_cores; i++) package_ids[i] = 0;
|
||||||
|
// fill_package_ids_from_sys failed, use a
|
||||||
|
// more sophisticated wat to find the number of sockets
|
||||||
|
topo->sockets = get_num_sockets_package_cpus(topo);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if(!check_package_ids_integrity(package_ids, topo->total_cores)) {
|
// fill_package_ids_from_sys succeeded, use the
|
||||||
return NULL;
|
// traditional socket detection algorithm
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Socket detection
|
|
||||||
int *package_ids_count = emalloc(sizeof(int) * topo->total_cores);
|
int *package_ids_count = emalloc(sizeof(int) * topo->total_cores);
|
||||||
for(int i=0; i < topo->total_cores; i++) {
|
for(int i=0; i < topo->total_cores; i++) {
|
||||||
package_ids_count[i] = 0;
|
package_ids_count[i] = 0;
|
||||||
@@ -96,6 +86,8 @@ struct topology* get_topology_info(struct cache* cach) {
|
|||||||
topo->sockets++;
|
topo->sockets++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(package_ids_count);
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Physical cores detection
|
// 3. Physical cores detection
|
||||||
int *core_ids_unified = emalloc(sizeof(int) * topo->total_cores);
|
int *core_ids_unified = emalloc(sizeof(int) * topo->total_cores);
|
||||||
@@ -120,7 +112,6 @@ struct topology* get_topology_info(struct cache* cach) {
|
|||||||
|
|
||||||
free(core_ids);
|
free(core_ids);
|
||||||
free(package_ids);
|
free(package_ids);
|
||||||
free(package_ids_count);
|
|
||||||
free(core_ids_unified);
|
free(core_ids_unified);
|
||||||
|
|
||||||
return topo;
|
return topo;
|
||||||
@@ -187,7 +178,9 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
char* path = emalloc(sizeof(char) * (strlen(_PATH_DT) + strlen(_PATH_DT_PART) + 1));
|
char* path = emalloc(sizeof(char) * (strlen(_PATH_DT) + strlen(_PATH_DT_PART) + 1));
|
||||||
sprintf(path, "%s%s", _PATH_DT, _PATH_DT_PART);
|
sprintf(path, "%s%s", _PATH_DT, _PATH_DT_PART);
|
||||||
|
|
||||||
cpu->cpu_name = read_file(path, &len);
|
if((cpu->cpu_name = read_file(path, &len)) == NULL) {
|
||||||
|
printWarn("Could not open '%s'", path);
|
||||||
|
}
|
||||||
cpu->pvr = mfpvr();
|
cpu->pvr = mfpvr();
|
||||||
cpu->arch = get_cpu_uarch(cpu);
|
cpu->arch = get_cpu_uarch(cpu);
|
||||||
cpu->freq = get_frequency_info();
|
cpu->freq = get_frequency_info();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "../common/udev.h"
|
||||||
#include "../common/global.h"
|
#include "../common/global.h"
|
||||||
#include "udev.h"
|
#include "udev.h"
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ bool fill_array_from_sys(int *core_ids, int total_cores, char* SYS_PATH) {
|
|||||||
char* buf;
|
char* buf;
|
||||||
char* end;
|
char* end;
|
||||||
char path[128];
|
char path[128];
|
||||||
|
memset(path, 0, 128);
|
||||||
|
|
||||||
for(int i=0; i < total_cores; i++) {
|
for(int i=0; i < total_cores; i++) {
|
||||||
sprintf(path, "%s%s/cpu%d/%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, i, SYS_PATH);
|
sprintf(path, "%s%s/cpu%d/%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, i, SYS_PATH);
|
||||||
@@ -36,5 +38,22 @@ bool fill_core_ids_from_sys(int *core_ids, int total_cores) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool fill_package_ids_from_sys(int* package_ids, int total_cores) {
|
bool fill_package_ids_from_sys(int* package_ids, int total_cores) {
|
||||||
return fill_array_from_sys(package_ids, total_cores, _PATH_TOPO_PACKAGE_ID);
|
bool status = fill_array_from_sys(package_ids, total_cores, _PATH_TOPO_PACKAGE_ID);
|
||||||
|
if(status) {
|
||||||
|
// fill_array_from_sys completed successfully, but we
|
||||||
|
// must to check the integrity of the package_ids array
|
||||||
|
for(int i=0; i < total_cores; i++) {
|
||||||
|
if(package_ids[i] == -1) {
|
||||||
|
printWarn("fill_package_ids_from_sys: package_ids[%d] = -1", i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(package_ids[i] >= total_cores || package_ids[i] < 0) {
|
||||||
|
printBug("fill_package_ids_from_sys: package_ids[%d] = %d", i, package_ids[i]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,6 @@
|
|||||||
|
|
||||||
bool fill_core_ids_from_sys(int *core_ids, int total_cores);
|
bool fill_core_ids_from_sys(int *core_ids, int total_cores);
|
||||||
bool fill_package_ids_from_sys(int* package_ids, int total_cores);
|
bool fill_package_ids_from_sys(int* package_ids, int total_cores);
|
||||||
|
int get_num_sockets_package_cpus(struct topology* topo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user