mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-24 23:40:39 +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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,12 @@
|
||||
#define _PATH_CACHE_L3 "/cache/index3"
|
||||
#define _PATH_CACHE_SIZE "/size"
|
||||
#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_CACHE_MAX_LEN 200
|
||||
#define _PATH_PACKAGE_MAX_LEN 200
|
||||
|
||||
char* read_file(char* path, int* len);
|
||||
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_l3_cache_size(uint32_t core);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,17 +44,6 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
|
||||
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* topo = emalloc(sizeof(struct topology));
|
||||
init_topology_struct(topo, cach);
|
||||
@@ -74,27 +63,30 @@ struct topology* get_topology_info(struct cache* cach) {
|
||||
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;
|
||||
}
|
||||
|
||||
if(!fill_package_ids_from_sys(package_ids, topo->total_cores)) {
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
if(!check_package_ids_integrity(package_ids, topo->total_cores)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 2. Socket detection
|
||||
int *package_ids_count = emalloc(sizeof(int) * topo->total_cores);
|
||||
for(int i=0; i < topo->total_cores; i++) {
|
||||
package_ids_count[i] = 0;
|
||||
}
|
||||
for(int i=0; i < topo->total_cores; i++) {
|
||||
package_ids_count[package_ids[i]]++;
|
||||
}
|
||||
for(int i=0; i < topo->total_cores; i++) {
|
||||
if(package_ids_count[i] != 0) {
|
||||
topo->sockets++;
|
||||
else {
|
||||
// fill_package_ids_from_sys succeeded, use the
|
||||
// traditional socket detection algorithm
|
||||
int *package_ids_count = emalloc(sizeof(int) * topo->total_cores);
|
||||
for(int i=0; i < topo->total_cores; i++) {
|
||||
package_ids_count[i] = 0;
|
||||
}
|
||||
for(int i=0; i < topo->total_cores; i++) {
|
||||
package_ids_count[package_ids[i]]++;
|
||||
}
|
||||
for(int i=0; i < topo->total_cores; i++) {
|
||||
if(package_ids_count[i] != 0) {
|
||||
topo->sockets++;
|
||||
}
|
||||
}
|
||||
free(package_ids_count);
|
||||
}
|
||||
|
||||
// 3. Physical cores detection
|
||||
@@ -120,7 +112,6 @@ struct topology* get_topology_info(struct cache* cach) {
|
||||
|
||||
free(core_ids);
|
||||
free(package_ids);
|
||||
free(package_ids_count);
|
||||
free(core_ids_unified);
|
||||
|
||||
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));
|
||||
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->arch = get_cpu_uarch(cpu);
|
||||
cpu->freq = get_frequency_info();
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "../common/udev.h"
|
||||
#include "../common/global.h"
|
||||
#include "udev.h"
|
||||
|
||||
#define _PATH_TOPO_CORE_ID "topology/core_id"
|
||||
#define _PATH_TOPO_PACKAGE_ID "topology/physical_package_id"
|
||||
#define _PATH_TOPO_CORE_ID "topology/core_id"
|
||||
#define _PATH_TOPO_PACKAGE_ID "topology/physical_package_id"
|
||||
|
||||
bool fill_array_from_sys(int *core_ids, int total_cores, char* SYS_PATH) {
|
||||
int filelen;
|
||||
char* buf;
|
||||
char* end;
|
||||
char path[128];
|
||||
memset(path, 0, 128);
|
||||
|
||||
for(int i=0; i < total_cores; i++) {
|
||||
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) {
|
||||
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_package_ids_from_sys(int* package_ids, int total_cores);
|
||||
int get_num_sockets_package_cpus(struct topology* topo);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user