[v0.98] Use malloc/calloc wrapper that exits when alloc fails, as suggested by #90

This commit is contained in:
Dr-Noob
2021-08-04 09:58:00 +02:00
parent 3a636c101b
commit eac97bf721
15 changed files with 631 additions and 605 deletions

View File

@@ -16,12 +16,12 @@
#define STRING_UNKNOWN "Unknown"
void init_cache_struct(struct cache* cach) {
cach->L1i = malloc(sizeof(struct cach));
cach->L1d = malloc(sizeof(struct cach));
cach->L2 = malloc(sizeof(struct cach));
cach->L3 = malloc(sizeof(struct cach));
cach->L1i = emalloc(sizeof(struct cach));
cach->L1d = emalloc(sizeof(struct cach));
cach->L2 = emalloc(sizeof(struct cach));
cach->L3 = emalloc(sizeof(struct cach));
cach->cach_arr = malloc(sizeof(struct cach*) * 4);
cach->cach_arr = emalloc(sizeof(struct cach*) * 4);
cach->cach_arr[0] = cach->L1i;
cach->cach_arr[1] = cach->L1d;
cach->cach_arr[2] = cach->L2;
@@ -34,8 +34,8 @@ void init_cache_struct(struct cache* cach) {
cach->L3->exists = false;
}
struct cache* get_cache_info(struct cpuInfo* cpu) {
struct cache* cach = malloc(sizeof(struct cache));
struct cache* get_cache_info(struct cpuInfo* cpu) {
struct cache* cach = emalloc(sizeof(struct cache));
init_cache_struct(cach);
cach->max_cache_level = 2;
@@ -49,7 +49,7 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
}
struct frequency* get_frequency_info(uint32_t core) {
struct frequency* freq = malloc(sizeof(struct frequency));
struct frequency* freq = emalloc(sizeof(struct frequency));
freq->base = UNKNOWN_FREQ;
freq->max = get_max_freq_from_file(core, false);
@@ -58,36 +58,36 @@ struct frequency* get_frequency_info(uint32_t core) {
}
struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach, uint32_t* midr_array, int socket_idx, int ncores) {
struct topology* topo = malloc(sizeof(struct topology));
struct topology* topo = emalloc(sizeof(struct topology));
topo->cach = cach;
topo->total_cores = 0;
int sockets_seen = 0;
int first_core_idx = 0;
int currrent_core_idx = 0;
int cores_in_socket = 0;
while(socket_idx + 1 > sockets_seen) {
if(midr_array[first_core_idx] == midr_array[currrent_core_idx] && currrent_core_idx < ncores) {
currrent_core_idx++;
cores_in_socket++;
}
else {
topo->total_cores = cores_in_socket;
topo->total_cores = cores_in_socket;
cores_in_socket = 0;
first_core_idx = currrent_core_idx;
sockets_seen++;
}
}
return topo;
}
bool cores_are_equal(int c1pos, int c2pos, uint32_t* midr_array, int32_t* freq_array) {
return midr_array[c1pos] == midr_array[c2pos] && freq_array[c1pos] == freq_array[c2pos];
}
uint32_t fill_ids_from_midr(uint32_t* midr_array, int32_t* freq_array, uint32_t* ids_array, int len) {
uint32_t latest_id = 0;
bool found;
@@ -128,17 +128,17 @@ void init_cpu_info(struct cpuInfo* cpu) {
// ARM32 https://elixir.bootlin.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
// ARM64 https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/uapi/asm/hwcap.h
struct features* get_features_info() {
struct features* feat = malloc(sizeof(struct features));
struct features* feat = emalloc(sizeof(struct features));
bool *ptr = &(feat->AES);
for(uint32_t i = 0; i < sizeof(struct features)/sizeof(bool); i++, ptr++) {
*ptr = false;
}
errno = 0;
long hwcaps = getauxval(AT_HWCAP);
if(errno == ENOENT) {
printWarn("Unable to retrieve AT_HWCAP using getauxval");
printWarn("Unable to retrieve AT_HWCAP using getauxval");
}
#ifdef __aarch64__
else {
@@ -152,7 +152,7 @@ struct features* get_features_info() {
else {
feat->NEON = hwcaps & HWCAP_NEON;
}
hwcaps = getauxval(AT_HWCAP2);
if(errno == ENOENT) {
printWarn("Unable to retrieve AT_HWCAP2 using getauxval");
@@ -169,77 +169,77 @@ struct features* get_features_info() {
}
struct cpuInfo* get_cpu_info() {
struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo));
struct cpuInfo* cpu = emalloc(sizeof(struct cpuInfo));
init_cpu_info(cpu);
int ncores = get_ncores_from_cpuinfo();
bool success = false;
int32_t* freq_array = malloc(sizeof(uint32_t) * ncores);
uint32_t* midr_array = malloc(sizeof(uint32_t) * ncores);
uint32_t* ids_array = malloc(sizeof(uint32_t) * ncores);
int32_t* freq_array = emalloc(sizeof(uint32_t) * ncores);
uint32_t* midr_array = emalloc(sizeof(uint32_t) * ncores);
uint32_t* ids_array = emalloc(sizeof(uint32_t) * ncores);
for(int i=0; i < ncores; i++) {
midr_array[i] = get_midr_from_cpuinfo(i, &success);
if(!success) {
printWarn("Unable to fetch MIDR for core %d. This is probably because the core is offline", i);
midr_array[i] = midr_array[0];
}
freq_array[i] = get_max_freq_from_file(i, false);
if(freq_array[i] == UNKNOWN_FREQ) {
printWarn("Unable to fetch max frequency for core %d. This is probably because the core is offline", i);
freq_array[i] = freq_array[0];
}
}
}
uint32_t sockets = fill_ids_from_midr(midr_array, freq_array, ids_array, ncores);
struct cpuInfo* ptr = cpu;
int midr_idx = 0;
int tmp_midr_idx = 0;
for(uint32_t i=0; i < sockets; i++) {
if(i > 0) {
ptr->next_cpu = malloc(sizeof(struct cpuInfo));
ptr->next_cpu = emalloc(sizeof(struct cpuInfo));
ptr = ptr->next_cpu;
init_cpu_info(ptr);
tmp_midr_idx = midr_idx;
while(cores_are_equal(midr_idx, tmp_midr_idx, midr_array, freq_array)) tmp_midr_idx++;
midr_idx = tmp_midr_idx;
}
}
ptr->midr = midr_array[midr_idx];
ptr->arch = get_uarch_from_midr(ptr->midr, ptr);
ptr->feat = get_features_info();
ptr->freq = get_frequency_info(midr_idx);
ptr->cach = get_cache_info(ptr);
ptr->topo = get_topology_info(ptr, ptr->cach, midr_array, i, ncores);
}
cpu->num_cpus = sockets;
cpu->hv = malloc(sizeof(struct hypervisor));
cpu->hv = emalloc(sizeof(struct hypervisor));
cpu->hv->present = false;
cpu->soc = get_soc();
cpu->soc = get_soc();
return cpu;
}
char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_socket) {
uint32_t size = 3+7+1;
char* string = malloc(sizeof(char)*size);
char* string = emalloc(sizeof(char)*size);
snprintf(string, size, "%d cores", topo->total_cores);
return string;
}
char* get_str_peak_performance(struct cpuInfo* cpu) {
char* get_str_peak_performance(struct cpuInfo* cpu) {
//7 for GFLOP/s and 6 for digits,eg 412.14
uint32_t size = 7+6+1+1;
assert(strlen(STRING_UNKNOWN)+1 <= size);
char* string = malloc(sizeof(char)*size);
char* string = emalloc(sizeof(char)*size);
struct cpuInfo* ptr = cpu;
//First check we have consistent data
for(int i=0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) {
if(get_freq(ptr->freq) == UNKNOWN_FREQ) {
@@ -249,13 +249,13 @@ char* get_str_peak_performance(struct cpuInfo* cpu) {
}
double flops = 0.0;
ptr = cpu;
for(int i=0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) {
flops += ptr->topo->total_cores * (get_freq(ptr->freq) * 1000000);
}
if(cpu->feat->NEON) flops = flops * 4;
if(flops >= (double)1000000000000.0)
snprintf(string,size,"%.2f TFLOP/s",flops/1000000000000);
else if(flops >= 1000000000.0)
@@ -267,10 +267,10 @@ char* get_str_peak_performance(struct cpuInfo* cpu) {
}
char* get_str_features(struct cpuInfo* cpu) {
struct features* feat = cpu->feat;
char* string = malloc(sizeof(char) * 25);
struct features* feat = cpu->feat;
char* string = emalloc(sizeof(char) * 25);
uint32_t len = 0;
if(feat->NEON) {
strcat(string, "NEON,");
len += 5;
@@ -291,19 +291,19 @@ char* get_str_features(struct cpuInfo* cpu) {
strcat(string, "CRC32,");
len += 6;
}
if(len > 0) {
string[len-1] = '\0';
return string;
}
else
return NULL;
else
return NULL;
}
void print_debug(struct cpuInfo* cpu) {
int ncores = get_ncores_from_cpuinfo();
bool success = false;
for(int i=0; i < ncores; i++) {
printf("[Core %d] ", i);
long freq = get_max_freq_from_file(i, false);
@@ -313,16 +313,16 @@ void print_debug(struct cpuInfo* cpu) {
printf("0x%.8X ", get_midr_from_cpuinfo(0, &success));
}
else {
printf("0x%.8X ", midr);
printf("0x%.8X ", midr);
}
if(freq == UNKNOWN_FREQ) {
printWarn("Unable to fetch max frequency for core %d. This is probably because the core is offline", i);
printf("%ld MHz\n", get_max_freq_from_file(0, false));
}
else {
printf("%ld MHz\n", freq);
printf("%ld MHz\n", freq);
}
}
}
}
void free_topo_struct(struct topology* topo) {

View File

@@ -32,34 +32,34 @@ void fill_soc(struct system_on_chip* soc, char* soc_name, SOC soc_model, int32_t
soc->soc_vendor = get_soc_vendor_from_soc(soc_model);
soc->process = process;
int len = strlen(soc_name) + strlen(soc_trademark_string[soc->soc_vendor]) + 1;
soc->soc_name = malloc(sizeof(char) * len);
soc->soc_name = emalloc(sizeof(char) * len);
memset(soc->soc_name, 0, sizeof(char) * len);
sprintf(soc->soc_name, "%s%s", soc_trademark_string[soc->soc_vendor], soc_name);
sprintf(soc->soc_name, "%s%s", soc_trademark_string[soc->soc_vendor], soc_name);
}
bool match_soc(struct system_on_chip* soc, char* raw_name, char* expected_name, char* soc_name, SOC soc_model, int32_t process) {
if(strlen(raw_name) > strlen(expected_name))
return false;
int len = strlen(raw_name);
if(strncmp(raw_name, expected_name, len) != 0) {
return false;
}
else {
fill_soc(soc, soc_name, soc_model, process);
return true;
return true;
}
}
char* toupperstr(char* str) {
int len = strlen(str) + 1;
char* ret = malloc(sizeof(char) * len);
char* ret = emalloc(sizeof(char) * len);
memset(ret, 0, sizeof(char) * len);
for(int i=0; i < len; i++) {
ret[i] = toupper((unsigned char) str[i]);
ret[i] = toupper((unsigned char) str[i]);
}
return ret;
}
@@ -82,22 +82,22 @@ bool match_broadcom(char* soc_name, struct system_on_chip* soc) {
if((tmp = strstr(soc_name, "BCM")) == NULL)
return false;
SOC_START
SOC_EQ(tmp, "BCM2835", "2835", SOC_BCM_2835, soc, 65)
SOC_EQ(tmp, "BCM2836", "2836", SOC_BCM_2836, soc, 40)
SOC_EQ(tmp, "BCM2837", "2837", SOC_BCM_2837, soc, 40)
SOC_EQ(tmp, "BCM2837B0", "2837B0", SOC_BCM_2837B0, soc, 40)
SOC_EQ(tmp, "BCM2711", "2711", SOC_BCM_2711, soc, 28)
SOC_EQ(tmp, "BCM21553", "21553", SOC_BCM_21553, soc, 65)
SOC_EQ(tmp, "BCM21553-Thunderbird", "21553 Thunderbird", SOC_BCM_21553T, soc, 65)
SOC_EQ(tmp, "BCM21663", "21663", SOC_BCM_21663, soc, 40)
SOC_EQ(tmp, "BCM21664", "21664", SOC_BCM_21664, soc, 40)
SOC_EQ(tmp, "BCM28155", "28155", SOC_BCM_28155, soc, 40)
SOC_EQ(tmp, "BCM23550", "23550", SOC_BCM_23550, soc, 40)
SOC_EQ(tmp, "BCM28145", "28145", SOC_BCM_28145, soc, 40)
SOC_EQ(tmp, "BCM2157", "2157", SOC_BCM_2157, soc, 65)
SOC_EQ(tmp, "BCM21654", "21654", SOC_BCM_21654, soc, 40)
SOC_EQ(tmp, "BCM2835", "2835", SOC_BCM_2835, soc, 65)
SOC_EQ(tmp, "BCM2836", "2836", SOC_BCM_2836, soc, 40)
SOC_EQ(tmp, "BCM2837", "2837", SOC_BCM_2837, soc, 40)
SOC_EQ(tmp, "BCM2837B0", "2837B0", SOC_BCM_2837B0, soc, 40)
SOC_EQ(tmp, "BCM2711", "2711", SOC_BCM_2711, soc, 28)
SOC_EQ(tmp, "BCM21553", "21553", SOC_BCM_21553, soc, 65)
SOC_EQ(tmp, "BCM21553-Thunderbird", "21553 Thunderbird", SOC_BCM_21553T, soc, 65)
SOC_EQ(tmp, "BCM21663", "21663", SOC_BCM_21663, soc, 40)
SOC_EQ(tmp, "BCM21664", "21664", SOC_BCM_21664, soc, 40)
SOC_EQ(tmp, "BCM28155", "28155", SOC_BCM_28155, soc, 40)
SOC_EQ(tmp, "BCM23550", "23550", SOC_BCM_23550, soc, 40)
SOC_EQ(tmp, "BCM28145", "28145", SOC_BCM_28145, soc, 40)
SOC_EQ(tmp, "BCM2157", "2157", SOC_BCM_2157, soc, 65)
SOC_EQ(tmp, "BCM21654", "21654", SOC_BCM_21654, soc, 40)
SOC_END
}
@@ -108,7 +108,7 @@ bool match_hisilicon(char* soc_name, struct system_on_chip* soc) {
if((tmp = strstr(soc_name, "Hi")) == NULL)
return false;
SOC_START
SOC_EQ(tmp, "Hi3620GFC", "K3V2", SOC_HISILICON_3620, soc, 40)
//SOC_EQ(tmp, "?", "K3V2E", SOC_KIRIN, soc, ?)
@@ -200,16 +200,16 @@ bool match_mediatek(char* soc_name, struct system_on_chip* soc) {
if((tmp = strstr(soc_name, "MT")) == NULL)
return false;
SOC_START
// Dimensity //
SOC_EQ(tmp, "MT6889", "Dimensity 1000", SOC_MTK_MT6889, soc, 7)
SOC_EQ(tmp, "MT6885Z", "Dimensity 1000L", SOC_MTK_MT6885Z, soc, 7)
//SOC_EQ(tmp, "?", "Dimensity 700", SOC_MTK_, soc, 7)
SOC_EQ(tmp, "MT6853", "Dimensity 720", SOC_MTK_MT6853, soc, 7)
SOC_EQ(tmp, "MT6889", "Dimensity 1000", SOC_MTK_MT6889, soc, 7)
SOC_EQ(tmp, "MT6885Z", "Dimensity 1000L", SOC_MTK_MT6885Z, soc, 7)
//SOC_EQ(tmp, "?", "Dimensity 700", SOC_MTK_, soc, 7)
SOC_EQ(tmp, "MT6853", "Dimensity 720", SOC_MTK_MT6853, soc, 7)
SOC_EQ(tmp, "MT6873", "Dimensity 800", SOC_MTK_MT6873, soc, 7)
SOC_EQ(tmp, "MT6875", "Dimensity 820", SOC_MTK_MT6875, soc, 7)
// Helio //
// Helio //
SOC_EQ(tmp, "MT6761D", "Helio A20", SOC_MTK_MT6761D, soc, 12)
SOC_EQ(tmp, "MT6761", "Helio A22", SOC_MTK_MT6761, soc, 12)
SOC_EQ(tmp, "MT6762D", "Helio A25", SOC_MTK_MT6762D, soc, 12)
@@ -310,7 +310,7 @@ bool match_mediatek(char* soc_name, struct system_on_chip* soc) {
*
* If Qualcomm official website reports the SoC name without the initial two or three SKU name,
* we assume APQ if second number is 0, or MSM if second number is different than 0
*
*
* All SoC names here have been retrieved from official Qualcomm resources. However, Linux kernel
* and Android may report the SoC with slightly different. Therefore, this function needs some
* rework (e.g, debug with http://specdevice.com/unmoderated.php?lang=en)
@@ -322,11 +322,11 @@ bool match_qualcomm(char* soc_name, struct system_on_chip* soc) {
if((tmp = strstr(soc_name_upper, "MSM")) != NULL);
else if((tmp = strstr(soc_name_upper, "SDM")) != NULL);
else if((tmp = strstr(soc_name_upper, "APQ")) != NULL);
else if((tmp = strstr(soc_name_upper, "SM")) != NULL);
else if((tmp = strstr(soc_name_upper, "QM")) != NULL);
else if((tmp = strstr(soc_name_upper, "SM")) != NULL);
else if((tmp = strstr(soc_name_upper, "QM")) != NULL);
else if((tmp = strstr(soc_name_upper, "QSD")) != NULL);
else return false;
SOC_START
// Snapdragon S1 //
SOC_EQ(tmp, "QSD8650", "S1", SOC_SNAPD_QSD8650, soc, 65)
@@ -340,36 +340,36 @@ bool match_qualcomm(char* soc_name, struct system_on_chip* soc) {
SOC_EQ(tmp, "MSM7625A", "S1", SOC_SNAPD_MSM7625A, soc, 45)
SOC_EQ(tmp, "MSM7225A", "S1", SOC_SNAPD_MSM7225A, soc, 45)
// Snapdragon S2 //
SOC_EQ(tmp, "MSM8655", "S2", SOC_SNAPD_MSM8655, soc, 45)
SOC_EQ(tmp, "MSM8255", "S2", SOC_SNAPD_MSM8255, soc, 45)
SOC_EQ(tmp, "MSM8655", "S2", SOC_SNAPD_MSM8655, soc, 45)
SOC_EQ(tmp, "MSM8255", "S2", SOC_SNAPD_MSM8255, soc, 45)
SOC_EQ(tmp, "APQ8055", "S2", SOC_SNAPD_APQ8055, soc, 45)
SOC_EQ(tmp, "MSM7630", "S2", SOC_SNAPD_MSM7630, soc, 45)
SOC_EQ(tmp, "MSM7230", "S2", SOC_SNAPD_MSM7230, soc, 45)
SOC_EQ(tmp, "MSM7230", "S2", SOC_SNAPD_MSM7230, soc, 45)
// Snapdragon S3 //
SOC_EQ(tmp, "MSM8660", "S3", SOC_SNAPD_MSM8660, soc, 45)
SOC_EQ(tmp, "MSM8260", "S3", SOC_SNAPD_MSM8260, soc, 45)
SOC_EQ(tmp, "APQ8060", "S3", SOC_SNAPD_APQ8060, soc, 45)
SOC_EQ(tmp, "MSM8660", "S3", SOC_SNAPD_MSM8660, soc, 45)
SOC_EQ(tmp, "MSM8260", "S3", SOC_SNAPD_MSM8260, soc, 45)
SOC_EQ(tmp, "APQ8060", "S3", SOC_SNAPD_APQ8060, soc, 45)
// Snapdragon S4 //
SOC_EQ(tmp, "MSM8225", "S4 Play", SOC_SNAPD_MSM8225, soc, 45)
SOC_EQ(tmp, "MSM8625", "S4 Play", SOC_SNAPD_MSM8625, soc, 45)
SOC_EQ(tmp, "APQ8060A", "S4 Plus", SOC_SNAPD_APQ8060A, soc, 28)
SOC_EQ(tmp, "MSM8960", "S4 Plus", SOC_SNAPD_MSM8960, soc, 28)
SOC_EQ(tmp, "MSM8260A", "S4 Plus", SOC_SNAPD_MSM8260A, soc, 28)
SOC_EQ(tmp, "MSM8627", "S4 Plus", SOC_SNAPD_MSM8627, soc, 28)
SOC_EQ(tmp, "MSM8227", "S4 Plus", SOC_SNAPD_MSM8227, soc, 28)
SOC_EQ(tmp, "APQ8064", "S4 Pro", SOC_SNAPD_APQ8064, soc, 28)
SOC_EQ(tmp, "MSM8960T", "S4 Pro", SOC_SNAPD_MSM8960T, soc, 28)
SOC_EQ(tmp, "APQ8060A", "S4 Plus", SOC_SNAPD_APQ8060A, soc, 28)
SOC_EQ(tmp, "MSM8960", "S4 Plus", SOC_SNAPD_MSM8960, soc, 28)
SOC_EQ(tmp, "MSM8260A", "S4 Plus", SOC_SNAPD_MSM8260A, soc, 28)
SOC_EQ(tmp, "MSM8627", "S4 Plus", SOC_SNAPD_MSM8627, soc, 28)
SOC_EQ(tmp, "MSM8227", "S4 Plus", SOC_SNAPD_MSM8227, soc, 28)
SOC_EQ(tmp, "APQ8064", "S4 Pro", SOC_SNAPD_APQ8064, soc, 28)
SOC_EQ(tmp, "MSM8960T", "S4 Pro", SOC_SNAPD_MSM8960T, soc, 28)
// Snapdragon 2XX //
SOC_EQ(tmp, "MSM8110", "200", SOC_SNAPD_MSM8110, soc, 28)
SOC_EQ(tmp, "MSM8210", "200", SOC_SNAPD_MSM8210, soc, 28)
SOC_EQ(tmp, "MSM8610", "200", SOC_SNAPD_MSM8610, soc, 28)
SOC_EQ(tmp, "MSM8112", "200", SOC_SNAPD_MSM8112, soc, 28)
SOC_EQ(tmp, "MSM8212", "200", SOC_SNAPD_MSM8212, soc, 28)
SOC_EQ(tmp, "MSM8612", "200", SOC_SNAPD_MSM8612, soc, 28)
SOC_EQ(tmp, "MSM8225Q", "200", SOC_SNAPD_MSM8225Q, soc, 45)
SOC_EQ(tmp, "MSM8625Q", "200", SOC_SNAPD_MSM8625Q, soc, 45)
SOC_EQ(tmp, "MSM8208", "208", SOC_SNAPD_MSM8208, soc, 28)
SOC_EQ(tmp, "MSM8905", "205", SOC_SNAPD_MSM8905, soc, 28)
SOC_EQ(tmp, "MSM8110", "200", SOC_SNAPD_MSM8110, soc, 28)
SOC_EQ(tmp, "MSM8210", "200", SOC_SNAPD_MSM8210, soc, 28)
SOC_EQ(tmp, "MSM8610", "200", SOC_SNAPD_MSM8610, soc, 28)
SOC_EQ(tmp, "MSM8112", "200", SOC_SNAPD_MSM8112, soc, 28)
SOC_EQ(tmp, "MSM8212", "200", SOC_SNAPD_MSM8212, soc, 28)
SOC_EQ(tmp, "MSM8612", "200", SOC_SNAPD_MSM8612, soc, 28)
SOC_EQ(tmp, "MSM8225Q", "200", SOC_SNAPD_MSM8225Q, soc, 45)
SOC_EQ(tmp, "MSM8625Q", "200", SOC_SNAPD_MSM8625Q, soc, 45)
SOC_EQ(tmp, "MSM8208", "208", SOC_SNAPD_MSM8208, soc, 28)
SOC_EQ(tmp, "MSM8905", "205", SOC_SNAPD_MSM8905, soc, 28)
SOC_EQ(tmp, "MSM8909", "210 / 212", SOC_SNAPD_MSM8909, soc, 28) // In the future, we can differenciate them using frequency
SOC_EQ(tmp, "QM215", "215", SOC_SNAPD_QM215, soc, 28)
// Snapdragon 4XX //
@@ -473,21 +473,21 @@ struct system_on_chip* parse_soc_from_string(struct system_on_chip* soc) {
if(match_special(raw_name, soc))
return soc;
if (match_qualcomm(raw_name, soc))
return soc;
if(match_mediatek(raw_name, soc))
return soc;
if(match_exynos(raw_name, soc))
return soc;
if(match_hisilicon(raw_name, soc))
return soc;
match_broadcom(raw_name, soc);
return soc;
}
@@ -501,37 +501,37 @@ static inline int android_property_get(const char* key, char* value) {
struct system_on_chip* guess_soc_from_android(struct system_on_chip* soc) {
char tmp[100];
int property_len = 0;
property_len = android_property_get("ro.mediatek.platform", (char *) &tmp);
if(property_len > 0) {
soc->raw_name = malloc(sizeof(char) * (property_len + 1));
soc->raw_name = emalloc(sizeof(char) * (property_len + 1));
strncpy(soc->raw_name, tmp, property_len + 1);
soc->raw_name[property_len] = '\0';
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
return parse_soc_from_string(soc);
}
property_len = android_property_get("ro.product.board", (char *) &tmp);
if(property_len > 0) {
soc->raw_name = malloc(sizeof(char) * (property_len + 1));
if(property_len > 0) {
soc->raw_name = emalloc(sizeof(char) * (property_len + 1));
strncpy(soc->raw_name, tmp, property_len + 1);
soc->raw_name[property_len] = '\0';
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
return parse_soc_from_string(soc);
}
}
return soc;
}
#endif
struct system_on_chip* guess_soc_from_cpuinfo(struct system_on_chip* soc) {
char* tmp = get_hardware_from_cpuinfo();
if(tmp != NULL) {
soc->raw_name = tmp;
return parse_soc_from_string(soc);
}
return soc;
}
@@ -574,7 +574,7 @@ struct system_on_chip* guess_soc_raspbery_pi(struct system_on_chip* soc) {
char* soc_raw_name = soc_rpi_string[pppp];
/*int soc_len = strlen(soc_raw_name);
soc->raw_name = malloc(sizeof(char) * (soc_len + 1));
soc->raw_name = emalloc(sizeof(char) * (soc_len + 1));
strncpy(soc->raw_name, soc_raw_name, soc_len + 1);*/
match_broadcom(soc_raw_name, soc);
@@ -582,7 +582,7 @@ struct system_on_chip* guess_soc_raspbery_pi(struct system_on_chip* soc) {
}
struct system_on_chip* get_soc() {
struct system_on_chip* soc = malloc(sizeof(struct system_on_chip));
struct system_on_chip* soc = emalloc(sizeof(struct system_on_chip));
soc->raw_name = NULL;
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
soc->process = UNKNOWN;
@@ -601,7 +601,7 @@ struct system_on_chip* get_soc() {
soc = guess_soc_from_cpuinfo(soc);
if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) {
if(soc->raw_name != NULL)
printWarn("SoC detection failed using /proc/cpuinfo: Found '%s' string", soc->raw_name);
printWarn("SoC detection failed using /proc/cpuinfo: Found '%s' string", soc->raw_name);
else
printWarn("SoC detection failed using /proc/cpuinfo: No string found");
#ifdef __ANDROID__
@@ -609,16 +609,16 @@ struct system_on_chip* get_soc() {
if(soc->raw_name == NULL)
printWarn("SoC detection failed using Android: No string found");
else if(soc->soc_vendor == SOC_VENDOR_UNKNOWN)
printWarn("SoC detection failed using Android: Found '%s' string", soc->raw_name);
printWarn("SoC detection failed using Android: Found '%s' string", soc->raw_name);
#endif
}
if(soc->raw_name == NULL) {
soc->raw_name = malloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
soc->raw_name = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
snprintf(soc->raw_name, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
}
return soc;
return soc;
}
char* get_soc_name(struct system_on_chip* soc) {
@@ -633,16 +633,15 @@ VENDOR get_soc_vendor(struct system_on_chip* soc) {
char* get_str_process(struct system_on_chip* soc) {
char* str;
if(soc->process == UNKNOWN) {
str = malloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
str = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
snprintf(str, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
}
else {
str = malloc(sizeof(char) * 5);
str = emalloc(sizeof(char) * 5);
memset(str, 0, sizeof(char) * 5);
snprintf(str, 5, "%dnm", soc->process);
snprintf(str, 5, "%dnm", soc->process);
}
return str;
}

View File

@@ -45,26 +45,26 @@ enum {
UARCH_ARM1156,
UARCH_ARM1176,
UARCH_ARM11MPCORE,
UARCH_CORTEX_A5,
UARCH_CORTEX_A7,
UARCH_CORTEX_A8,
UARCH_CORTEX_A9,
UARCH_CORTEX_A12,
UARCH_CORTEX_A15,
UARCH_CORTEX_A17,
UARCH_CORTEX_A32,
UARCH_CORTEX_A35,
UARCH_CORTEX_A53,
UARCH_CORTEX_A5,
UARCH_CORTEX_A7,
UARCH_CORTEX_A8,
UARCH_CORTEX_A9,
UARCH_CORTEX_A12,
UARCH_CORTEX_A15,
UARCH_CORTEX_A17,
UARCH_CORTEX_A32,
UARCH_CORTEX_A35,
UARCH_CORTEX_A53,
UARCH_CORTEX_A55r0, // ARM Cortex-A55 revision 0 (restricted dual-issue capabilities compared to revision 1+).
UARCH_CORTEX_A55,
UARCH_CORTEX_A57,
UARCH_CORTEX_A65,
UARCH_CORTEX_A72,
UARCH_CORTEX_A73,
UARCH_CORTEX_A75,
UARCH_CORTEX_A55,
UARCH_CORTEX_A57,
UARCH_CORTEX_A65,
UARCH_CORTEX_A72,
UARCH_CORTEX_A73,
UARCH_CORTEX_A75,
UARCH_CORTEX_A76,
UARCH_CORTEX_A77,
UARCH_CORTEX_A78,
UARCH_CORTEX_A78,
UARCH_NEOVERSE_N1,
UARCH_NEOVERSE_E1,
UARCH_SCORPION,
@@ -118,15 +118,15 @@ static const ISA isas_uarch[] = {
[UARCH_CORTEX_A17] = ISA_ARMv7_A,
[UARCH_CORTEX_A32] = ISA_ARMv8_A_AArch32,
[UARCH_CORTEX_A35] = ISA_ARMv8_A,
[UARCH_CORTEX_A53] = ISA_ARMv8_A,
[UARCH_CORTEX_A53] = ISA_ARMv8_A,
[UARCH_CORTEX_A55r0] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A55] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A57] = ISA_ARMv8_A,
[UARCH_CORTEX_A65] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A65] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A72] = ISA_ARMv8_A,
[UARCH_CORTEX_A73] = ISA_ARMv8_A,
[UARCH_CORTEX_A75] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A76] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A76] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A77] = ISA_ARMv8_2_A,
[UARCH_CORTEX_A78] = ISA_ARMv8_2_A,
[UARCH_NEOVERSE_N1] = ISA_ARMv8_2_A,
@@ -170,18 +170,18 @@ static char* isas_string[] = {
#define CHECK_UARCH(arch, cpu, im_, p_, v_, r_, str, uarch, vendor) \
else if (im_ == im && p_ == p && (v_ == NA || v_ == v) && (r_ == NA || r_ == r)) fill_uarch(arch, cpu, str, uarch, vendor);
#define UARCH_END else { printBug("Unknown microarchitecture detected: IM=0x%.8X P=0x%.8X V=0x%.8X R=0x%.8X", im, p, v, r); fill_uarch(arch, cpu, "Unknown", UARCH_UNKNOWN, CPU_VENDOR_UNKNOWN); }
void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u, VENDOR vendor) {
arch->uarch = u;
arch->uarch = u;
arch->isa = isas_uarch[arch->uarch];
cpu->cpu_vendor = vendor;
arch->uarch_str = malloc(sizeof(char) * (strlen(str)+1));
arch->uarch_str = emalloc(sizeof(char) * (strlen(str)+1));
strcpy(arch->uarch_str, str);
arch->isa_str = malloc(sizeof(char) * (strlen(isas_string[arch->isa])+1));
strcpy(arch->isa_str, isas_string[arch->isa]);
}
arch->isa_str = emalloc(sizeof(char) * (strlen(isas_string[arch->isa])+1));
strcpy(arch->isa_str, isas_string[arch->isa]);
}
/*
* Codes are based on pytorch/cpuinfo, more precisely:
@@ -191,7 +191,7 @@ void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u,
* - https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/cputype.h
*/
struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) {
struct uarch* arch = malloc(sizeof(struct uarch));
struct uarch* arch = emalloc(sizeof(struct uarch));
uint32_t im = midr_get_implementer(midr);
uint32_t p = midr_get_part(midr);
uint32_t v = midr_get_variant(midr);
@@ -221,7 +221,7 @@ struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) {
CHECK_UARCH(arch, cpu, 'A', 0xD03, NA, NA, "Cortex-A53", UARCH_CORTEX_A53, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD04, NA, NA, "Cortex-A35", UARCH_CORTEX_A35, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD05, NA, 0, "Cortex-A55", UARCH_CORTEX_A55r0, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD05, NA, NA, "Cortex-A55", UARCH_CORTEX_A55, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD05, NA, NA, "Cortex-A55", UARCH_CORTEX_A55, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD06, NA, NA, "Cortex-A65", UARCH_CORTEX_A65, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD07, NA, NA, "Cortex-A57", UARCH_CORTEX_A57, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD08, NA, NA, "Cortex-A72", UARCH_CORTEX_A72, CPU_VENDOR_ARM)
@@ -233,26 +233,26 @@ struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) {
CHECK_UARCH(arch, cpu, 'A', 0xD0E, NA, NA, "Cortex-A76", UARCH_CORTEX_A76, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD41, NA, NA, "Cortex-A78", UARCH_CORTEX_A78, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'A', 0xD4A, NA, NA, "Neoverse E1", UARCH_NEOVERSE_E1, CPU_VENDOR_ARM)
CHECK_UARCH(arch, cpu, 'B', 0x00F, NA, NA, "Brahma B15", UARCH_BRAHMA_B15, CPU_VENDOR_BROADCOM)
CHECK_UARCH(arch, cpu, 'B', 0x100, NA, NA, "Brahma B53", UARCH_BRAHMA_B53, CPU_VENDOR_BROADCOM)
CHECK_UARCH(arch, cpu, 'B', 0x516, NA, NA, "ThunderX2", UARCH_THUNDERX2, CPU_VENDOR_CAVIUM)
CHECK_UARCH(arch, cpu, 'C', 0x0A0, NA, NA, "ThunderX", UARCH_THUNDERX, CPU_VENDOR_CAVIUM)
CHECK_UARCH(arch, cpu, 'C', 0x0A1, NA, NA, "ThunderX 88XX", UARCH_THUNDERX, CPU_VENDOR_CAVIUM)
CHECK_UARCH(arch, cpu, 'C', 0x0A2, NA, NA, "ThunderX 81XX", UARCH_THUNDERX, CPU_VENDOR_CAVIUM)
CHECK_UARCH(arch, cpu, 'C', 0x0A3, NA, NA, "ThunderX 81XX", UARCH_THUNDERX, CPU_VENDOR_CAVIUM)
CHECK_UARCH(arch, cpu, 'C', 0x0AF, NA, NA, "ThunderX2 99XX", UARCH_THUNDERX2, CPU_VENDOR_CAVIUM)
CHECK_UARCH(arch, cpu, 'H', 0xD01, NA, NA, "TaiShan v110", UARCH_TAISHAN_V110, CPU_VENDOR_HUAWUEI) // Kunpeng 920 series
CHECK_UARCH(arch, cpu, 'H', 0xD40, NA, NA, "Cortex-A76", UARCH_CORTEX_A76, CPU_VENDOR_ARM) // Kirin 980 Big/Medium cores -> Cortex-A76
CHECK_UARCH(arch, cpu, 'N', 0x000, NA, NA, "Denver", UARCH_DENVER, CPU_VENDOR_NVIDIA)
CHECK_UARCH(arch, cpu, 'N', 0x003, NA, NA, "Denver2", UARCH_DENVER2, CPU_VENDOR_NVIDIA)
CHECK_UARCH(arch, cpu, 'N', 0x004, NA, NA, "Carmel", UARCH_CARMEL, CPU_VENDOR_NVIDIA)
CHECK_UARCH(arch, cpu, 'P', 0x000, NA, NA, "Xgene", UARCH_XGENE, CPU_VENDOR_APM)
CHECK_UARCH(arch, cpu, 'Q', 0x00F, NA, NA, "Scorpion", UARCH_SCORPION, CPU_VENDOR_QUALCOMM)
CHECK_UARCH(arch, cpu, 'Q', 0x02D, NA, NA, "Scorpion", UARCH_KRAIT, CPU_VENDOR_QUALCOMM)
CHECK_UARCH(arch, cpu, 'Q', 0x04D, 1, 0, "Krait 200", UARCH_KRAIT, CPU_VENDOR_QUALCOMM)
@@ -273,29 +273,28 @@ struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) {
CHECK_UARCH(arch, cpu, 'Q', 0x803, NA, NA, "Kryo 385 Silver", UARCH_CORTEX_A55r0, CPU_VENDOR_ARM) // Low-power Kryo 385 "Silver" -> Cortex-A55r0
CHECK_UARCH(arch, cpu, 'Q', 0x804, NA, NA, "Kryo 485 Gold", UARCH_CORTEX_A76, CPU_VENDOR_ARM) // High-performance Kryo 485 "Gold" / "Gold Prime" -> Cortex-A76
CHECK_UARCH(arch, cpu, 'Q', 0x805, NA, NA, "Kryo 485 Silver", UARCH_CORTEX_A55, CPU_VENDOR_ARM) // Low-performance Kryo 485 "Silver" -> Cortex-A55
CHECK_UARCH(arch, cpu, 'Q', 0xC00, NA, NA, "Falkor", UARCH_FALKOR, CPU_VENDOR_QUALCOMM)
CHECK_UARCH(arch, cpu, 'Q', 0xC01, NA, NA, "Saphira", UARCH_SAPHIRA, CPU_VENDOR_QUALCOMM)
CHECK_UARCH(arch, cpu, 'Q', 0xC00, NA, NA, "Falkor", UARCH_FALKOR, CPU_VENDOR_QUALCOMM)
CHECK_UARCH(arch, cpu, 'Q', 0xC01, NA, NA, "Saphira", UARCH_SAPHIRA, CPU_VENDOR_QUALCOMM)
CHECK_UARCH(arch, cpu, 'S', 0x001, 1, NA, "Exynos M1", UARCH_EXYNOS_M1, CPU_VENDOR_SAMSUNG) // Exynos 8890
CHECK_UARCH(arch, cpu, 'S', 0x001, 4, NA, "Exynos M2", UARCH_EXYNOS_M2, CPU_VENDOR_SAMSUNG) // Exynos 8895
CHECK_UARCH(arch, cpu, 'S', 0x002, 1, NA, "Exynos M3", UARCH_EXYNOS_M3, CPU_VENDOR_SAMSUNG) // Exynos 9810
CHECK_UARCH(arch, cpu, 'S', 0x003, 1, NA, "Exynos M4", UARCH_EXYNOS_M4, CPU_VENDOR_SAMSUNG) // Exynos 9820
CHECK_UARCH(arch, cpu, 'S', 0x004, 1, NA, "Exynos M5", UARCH_EXYNOS_M5, CPU_VENDOR_SAMSUNG) // Exynos 9820 (this one looks wrong at uarch.c ...)
CHECK_UARCH(arch, cpu, 'V', 0x581, NA, NA, "PJ4", UARCH_PJ4, CPU_VENDOR_MARVELL)
CHECK_UARCH(arch, cpu, 'V', 0x584, NA, NA, "PJ4B-MP", UARCH_PJ4, CPU_VENDOR_MARVELL)
UARCH_END
return arch;
}
char* get_str_uarch(struct cpuInfo* cpu) {
return cpu->arch->uarch_str;
return cpu->arch->uarch_str;
}
void free_uarch_struct(struct uarch* arch) {
void free_uarch_struct(struct uarch* arch) {
free(arch->uarch_str);
free(arch);
}

View File

@@ -81,8 +81,8 @@ uint32_t get_midr_from_cpuinfo(uint32_t core, bool* success) {
*success = true;
if((buf = read_file(_PATH_CPUINFO, &filelen)) == NULL) {
perror("open");
*success = false;
return 0;
*success = false;
return 0;
}
char* tmp = strstr(buf, CPUINFO_CPU_STRING);
@@ -92,9 +92,9 @@ uint32_t get_midr_from_cpuinfo(uint32_t core, bool* success) {
current_core++;
tmp = strstr(tmp, CPUINFO_CPU_STRING);
}
if(tmp == NULL) {
*success = false;
*success = false;
return 0;
}
@@ -108,35 +108,35 @@ uint32_t get_midr_from_cpuinfo(uint32_t core, bool* success) {
if ((ret = parse_cpuinfo_field(tmp, CPUINFO_CPU_IMPLEMENTER_STR, 16)) < 0) {
printf("Failed parsing cpu_implementer\n");
*success = false;
*success = false;
return 0;
}
cpu_implementer = (uint32_t) ret;
if ((ret = parse_cpuinfo_field(tmp, CPUINFO_CPU_ARCHITECTURE_STR, 10)) < 0) {
printf("Failed parsing cpu_architecture\n");
*success = false;
*success = false;
return 0;
}
cpu_architecture = (uint32_t) 0xF; // Why?
if ((ret = parse_cpuinfo_field(tmp, CPUINFO_CPU_VARIANT_STR, 16)) < 0) {
printf("Failed parsing cpu_variant\n");
*success = false;
*success = false;
return 0;
}
cpu_variant = (uint32_t) ret;
if ((ret = parse_cpuinfo_field(tmp, CPUINFO_CPU_PART_STR, 16)) < 0) {
printf("Failed parsing cpu_part\n");
*success = false;
*success = false;
return 0;
}
cpu_part = (uint32_t) ret;
if ((ret = parse_cpuinfo_field(tmp, CPUINFO_CPU_REVISION_STR, 10)) < 0) {
printf("Failed parsing cpu_revision\n");
*success = false;
*success = false;
return 0;
}
cpu_revision = (uint32_t) ret;
@@ -164,7 +164,7 @@ char* get_field_from_cpuinfo(char* CPUINFO_FIELD) {
char* tmp2 = strstr(tmp1, "\n");
int strlen = (1 + (tmp2-tmp1));
char* hardware = malloc(sizeof(char) * strlen);
char* hardware = emalloc(sizeof(char) * strlen);
memset(hardware, 0, sizeof(char) * strlen);
strncpy(hardware, tmp1, tmp2-tmp1);

View File

@@ -71,7 +71,7 @@ bool show_debug() {
}
bool show_raw() {
return args.raw_flag;
return args.raw_flag;
}
bool verbose_enabled() {
@@ -83,20 +83,20 @@ int max_arg_str_length() {
int len = sizeof(args_str) / sizeof(args_str[0]);
for(int i=0; i < len; i++) {
max_len = max(max_len, (int) strlen(args_str[i]));
}
}
return max_len;
}
STYLE parse_style(char* style) {
uint8_t i = 0;
uint8_t styles_count = sizeof(SYTLES_STR_LIST) / sizeof(SYTLES_STR_LIST[0]);
while(i != styles_count && (SYTLES_STR_LIST[i] == NULL || strcmp(SYTLES_STR_LIST[i], style) != 0))
i++;
if(i == styles_count)
return STYLE_INVALID;
return i;
}
@@ -109,11 +109,11 @@ void free_colors_struct(struct colors* cs) {
}
bool parse_color(char* optarg_str, struct colors** cs) {
*cs = malloc(sizeof(struct colors));
(*cs)->c1 = malloc(sizeof(struct color));
(*cs)->c2 = malloc(sizeof(struct color));
(*cs)->c3 = malloc(sizeof(struct color));
(*cs)->c4 = malloc(sizeof(struct color));
*cs = emalloc(sizeof(struct colors));
(*cs)->c1 = emalloc(sizeof(struct color));
(*cs)->c2 = emalloc(sizeof(struct color));
(*cs)->c3 = emalloc(sizeof(struct color));
(*cs)->c4 = emalloc(sizeof(struct color));
struct color** c1 = &((*cs)->c1);
struct color** c2 = &((*cs)->c2);
struct color** c3 = &((*cs)->c3);
@@ -121,43 +121,43 @@ bool parse_color(char* optarg_str, struct colors** cs) {
int32_t ret;
char* str_to_parse = NULL;
bool free_ptr;
if(strcmp(optarg_str, COLOR_STR_INTEL) == 0) {
str_to_parse = malloc(sizeof(char) * 46);
str_to_parse = emalloc(sizeof(char) * 46);
strcpy(str_to_parse, COLOR_DEFAULT_INTEL);
free_ptr = true;
}
else if(strcmp(optarg_str, COLOR_STR_AMD) == 0) {
str_to_parse = malloc(sizeof(char) * 44);
strcpy(str_to_parse, COLOR_DEFAULT_AMD);
str_to_parse = emalloc(sizeof(char) * 44);
strcpy(str_to_parse, COLOR_DEFAULT_AMD);
free_ptr = true;
}
else if(strcmp(optarg_str, COLOR_STR_IBM) == 0) {
str_to_parse = malloc(sizeof(char) * 45);
str_to_parse = emalloc(sizeof(char) * 45);
strcpy(str_to_parse, COLOR_DEFAULT_IBM);
free_ptr = true;
}
else if(strcmp(optarg_str, COLOR_STR_ARM) == 0) {
str_to_parse = malloc(sizeof(char) * 46);
strcpy(str_to_parse, COLOR_DEFAULT_ARM);
str_to_parse = emalloc(sizeof(char) * 46);
strcpy(str_to_parse, COLOR_DEFAULT_ARM);
free_ptr = true;
}
else {
else {
str_to_parse = optarg_str;
free_ptr = false;
}
ret = sscanf(str_to_parse, "%d,%d,%d:%d,%d,%d:%d,%d,%d:%d,%d,%d",
ret = sscanf(str_to_parse, "%d,%d,%d:%d,%d,%d:%d,%d,%d:%d,%d,%d",
&(*c1)->R, &(*c1)->G, &(*c1)->B,
&(*c2)->R, &(*c2)->G, &(*c2)->B,
&(*c3)->R, &(*c3)->G, &(*c3)->B,
&(*c4)->R, &(*c4)->G, &(*c4)->B);
if(ret != 12) {
printErr("Expected to read 12 values for color but read %d", ret);
return false;
return false;
}
//TODO: Refactor c1->R c2->R ... to c[i]->R
if((*c1)->R < 0 || (*c1)->R > 255) {
printErr("Red in color 1 is invalid. Must be in range (0, 255)");
@@ -182,17 +182,17 @@ bool parse_color(char* optarg_str, struct colors** cs) {
if((*c2)->B < 0 || (*c2)->B > 255) {
printErr("Blue in color 2 is invalid. Must be in range (0, 255)");
return false;
}
}
if(free_ptr) free (str_to_parse);
return true;
return true;
}
char* build_short_options() {
const char *c = args_chr;
int len = sizeof(args_chr) / sizeof(args_chr[0]);
char* str = (char *) malloc(sizeof(char) * (len*2 + 1));
char* str = (char *) emalloc(sizeof(char) * (len*2 + 1));
memset(str, 0, sizeof(char) * (len*2 + 1));
#ifdef ARCH_X86
@@ -210,7 +210,7 @@ char* build_short_options() {
bool parse_args(int argc, char* argv[]) {
int opt;
int option_index = 0;
int option_index = 0;
opterr = 0;
bool color_flag = false;
@@ -243,7 +243,7 @@ bool parse_args(int argc, char* argv[]) {
printErr("Color option specified more than once");
return false;
}
color_flag = true;
color_flag = true;
if(!parse_color(optarg, &args.colors)) {
printErr("Color parsing failed");
return false;
@@ -276,7 +276,7 @@ bool parse_args(int argc, char* argv[]) {
else if(opt == args_chr[ARG_VERSION]) {
args.version_flag = true;
}
else {
else {
printWarn("Invalid options");
args.help_flag = true;
}

View File

@@ -40,7 +40,7 @@ char* get_str_cpu_name(struct cpuInfo* cpu) {
#if defined(ARCH_X86) || defined(ARCH_PPC)
char* get_str_sockets(struct topology* topo) {
char* string = malloc(sizeof(char) * 2);
char* string = emalloc(sizeof(char) * 2);
int32_t sanity_ret = snprintf(string, 2, "%d", topo->sockets);
if(sanity_ret < 0) {
printBug("get_str_sockets: snprintf returned a negative value for input: '%d'", topo->sockets);
@@ -56,44 +56,44 @@ uint32_t get_nsockets(struct topology* topo) {
int32_t get_value_as_smallest_unit(char ** str, uint32_t value) {
int32_t sanity_ret;
*str = malloc(sizeof(char)* 11); //8 for digits, 2 for units
*str = emalloc(sizeof(char)* 11); //8 for digits, 2 for units
if(value/1024 >= 1024)
sanity_ret = snprintf(*str, 10,"%.4g"STRING_MEGABYTES, (double)value/(1<<20));
else
sanity_ret = snprintf(*str, 10,"%.4g"STRING_KILOBYTES, (double)value/(1<<10));
sanity_ret = snprintf(*str, 10,"%.4g"STRING_KILOBYTES, (double)value/(1<<10));
return sanity_ret;
}
// String functions
// String functions
char* get_str_cache_two(int32_t cache_size, uint32_t physical_cores) {
// 4 for digits, 2 for units, 2 for ' (', 3 digits, 2 for units and 7 for ' Total)'
uint32_t max_size = 4+2 + 2 + 4+2 + 7 + 1;
int32_t sanity_ret;
char* string = malloc(sizeof(char) * max_size);
char* string = emalloc(sizeof(char) * max_size);
char* tmp1;
char* tmp2;
char* tmp2;
int32_t tmp1_len = get_value_as_smallest_unit(&tmp1, cache_size);
int32_t tmp2_len = get_value_as_smallest_unit(&tmp2, cache_size * physical_cores);
if(tmp1_len < 0) {
printBug("get_value_as_smallest_unit: snprintf returned a negative value for input: %d\n", cache_size);
return NULL;
return NULL;
}
if(tmp2_len < 0) {
printBug("get_value_as_smallest_unit: snprintf returned a negative value for input: %d\n", cache_size * physical_cores);
return NULL;
return NULL;
}
uint32_t size = tmp1_len + 2 + tmp2_len + 7 + 1;
sanity_ret = snprintf(string, size, "%s (%s Total)", tmp1, tmp2);
sanity_ret = snprintf(string, size, "%s (%s Total)", tmp1, tmp2);
if(sanity_ret < 0) {
printBug("get_str_cache_two: snprintf returned a negative value for input: '%s' and '%s'\n", tmp1, tmp2);
return NULL;
return NULL;
}
free(tmp1);
free(tmp2);
return string;
@@ -103,21 +103,21 @@ char* get_str_cache_one(int32_t cache_size) {
// 4 for digits, 2 for units, 2 for ' (', 3 digits, 2 for units and 7 for ' Total)'
uint32_t max_size = 4+2 + 1;
int32_t sanity_ret;
char* string = malloc(sizeof(char) * max_size);
char* string = emalloc(sizeof(char) * max_size);
char* tmp;
int32_t tmp_len = get_value_as_smallest_unit(&tmp, cache_size);
if(tmp_len < 0) {
printBug("get_value_as_smallest_unit: snprintf returned a negative value for input: %d", cache_size);
return NULL;
return NULL;
}
uint32_t size = tmp_len + 1;
sanity_ret = snprintf(string, size, "%s", tmp);
if(sanity_ret < 0) {
printBug("get_str_cache_one: snprintf returned a negative value for input: '%s'", tmp);
return NULL;
return NULL;
}
free(tmp);
return string;
@@ -145,7 +145,7 @@ char* get_str_l2(struct cache* cach) {
char* get_str_l3(struct cache* cach) {
if(!cach->L3->exists)
return NULL;
return NULL;
return get_str_cache(cach->L3->size, cach->L3->num_caches);
}
@@ -153,7 +153,7 @@ char* get_str_freq(struct frequency* freq) {
//Max 3 digits and 3 for '(M/G)Hz' plus 1 for '\0'
uint32_t size = (5+1+3+1);
assert(strlen(STRING_UNKNOWN)+1 <= size);
char* string = malloc(sizeof(char)*size);
char* string = emalloc(sizeof(char)*size);
memset(string, 0, sizeof(char)*size);
if(freq->max == UNKNOWN_FREQ || freq->max < 0)

View File

@@ -1,5 +1,9 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "global.h"
#ifdef _WIN32
@@ -68,3 +72,25 @@ void set_log_level(bool verbose) {
int max(int a, int b) {
return a > b ? a : b;
}
void* emalloc(size_t size) {
void* ptr = malloc(size);
if(ptr == NULL) {
printErr("malloc failed: %s", strerror(errno));
exit(1);
}
return ptr;
}
void* ecalloc(size_t nmemb, size_t size) {
void* ptr = calloc(nmemb, size);
if(ptr == NULL) {
printErr("calloc failed: %s", strerror(errno));
exit(1);
}
return ptr;
}

View File

@@ -8,5 +8,7 @@ void printWarn(const char *fmt, ...);
void printErr(const char *fmt, ...);
void printBug(const char *fmt, ...);
int max(int a, int b);
void* emalloc(size_t size);
void* ecalloc(size_t nmemb, size_t size);
#endif

View File

@@ -107,7 +107,7 @@ static const char* ATTRIBUTE_FIELDS [] = {
struct attribute {
int type;
char* value;
char* value;
};
struct ascii {
@@ -129,14 +129,14 @@ void setAttribute(struct ascii* art, int type, char* value) {
art->attributes[art->n_attributes_set]->value = value;
art->attributes[art->n_attributes_set]->type = type;
art->n_attributes_set++;
if(art->n_attributes_set > MAX_ATTRIBUTES) {
printBug("Set %d attributes, while max value is %d!", art->n_attributes_set, MAX_ATTRIBUTES);
}
}
char* rgb_to_ansi(struct color* c, bool background, bool bold) {
char* str = malloc(sizeof(char) * 100);
char* str = emalloc(sizeof(char) * 100);
if(background) {
snprintf(str, 44, "\x1b[48;2;%.3d;%.3d;%.3dm", c->R, c->G, c->B);
}
@@ -152,19 +152,19 @@ char* rgb_to_ansi(struct color* c, bool background, bool bold) {
struct ascii* set_ascii(VENDOR vendor, STYLE style, struct colors* cs) {
char *COL_FANCY_1, *COL_FANCY_2, *COL_FANCY_3, *COL_FANCY_4, *COL_RETRO_1, *COL_RETRO_2, *COL_RETRO_3, *COL_RETRO_4;
struct ascii* art = malloc(sizeof(struct ascii));
struct ascii* art = emalloc(sizeof(struct ascii));
art->n_attributes_set = 0;
art->additional_spaces = 0;
art->vendor = vendor;
art->attributes = malloc(sizeof(struct attribute *) * MAX_ATTRIBUTES);
art->attributes = emalloc(sizeof(struct attribute *) * MAX_ATTRIBUTES);
for(uint32_t i=0; i < MAX_ATTRIBUTES; i++) {
art->attributes[i] = malloc(sizeof(struct attribute));
art->attributes[i] = emalloc(sizeof(struct attribute));
art->attributes[i]->type = 0;
art->attributes[i]->value = NULL;
}
strcpy(art->reset, COLOR_RESET);
#ifdef ARCH_X86
#ifdef ARCH_X86
if(art->vendor == CPU_VENDOR_INTEL) {
COL_FANCY_1 = COLOR_BG_CYAN;
COL_FANCY_2 = COLOR_BG_WHITE;
@@ -176,11 +176,11 @@ struct ascii* set_ascii(VENDOR vendor, STYLE style, struct colors* cs) {
COL_FANCY_1 = COLOR_BG_WHITE;
COL_FANCY_2 = COLOR_BG_GREEN;
COL_FANCY_3 = COLOR_FG_WHITE;
COL_FANCY_4 = COLOR_FG_GREEN;
COL_FANCY_4 = COLOR_FG_GREEN;
art->ascii_chars[0] = '@';
}
else {
printBug("Invalid CPU vendor in set_ascii (%d)", art->vendor);
printBug("Invalid CPU vendor in set_ascii (%d)", art->vendor);
return NULL;
}
#elif ARCH_PPC
@@ -321,7 +321,7 @@ struct ascii* set_ascii(VENDOR vendor, STYLE style, struct colors* cs) {
}
char tmp[NUMBER_OF_LINES * LINE_SIZE + 1];
#ifdef ARCH_X86
#ifdef ARCH_X86
if(art->vendor == CPU_VENDOR_INTEL)
strcpy(tmp, INTEL_ASCII);
else if(art->vendor == CPU_VENDOR_AMD)
@@ -391,7 +391,7 @@ void print_algorithm_intel(struct ascii* art, int n, bool* flag) {
void print_algorithm_amd(struct ascii* art, int n, bool* flag) {
*flag = false; // dummy, just silence compiler error
for(int i=0; i < LINE_SIZE; i++) {
if(art->art[n][i] == '@')
printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset);
@@ -402,7 +402,7 @@ void print_algorithm_amd(struct ascii* art, int n, bool* flag) {
}
}
void print_ascii_x86(struct ascii* art, uint32_t la, void (*callback_print_algorithm)(struct ascii* art, int i, bool* flag)) {
void print_ascii_x86(struct ascii* art, uint32_t la, void (*callback_print_algorithm)(struct ascii* art, int i, bool* flag)) {
int attr_to_print = 0;
int attr_type;
char* attr_value;
@@ -419,7 +419,7 @@ void print_ascii_x86(struct ascii* art, uint32_t la, void (*callback_print_algor
attr_type = art->attributes[attr_to_print]->type;
attr_value = art->attributes[attr_to_print]->value;
attr_to_print++;
space_right = 1 + (la - strlen(ATTRIBUTE_FIELDS[attr_type]));
printf("%s%s%s%*s%s%s%s\n", art->color1_text, ATTRIBUTE_FIELDS[attr_type], art->reset, space_right, "", art->color2_text, attr_value, art->reset);
}
@@ -430,7 +430,7 @@ void print_ascii_x86(struct ascii* art, uint32_t la, void (*callback_print_algor
void print_ascii(struct ascii* art) {
uint32_t longest_attribute = longest_attribute_length(art);
if(art->vendor == CPU_VENDOR_INTEL)
print_ascii_x86(art, longest_attribute, &print_algorithm_intel);
else if(art->vendor == CPU_VENDOR_AMD)
@@ -438,14 +438,14 @@ void print_ascii(struct ascii* art) {
else {
printBug("Invalid CPU vendor: %d\n", art->vendor);
}
}
bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
struct ascii* art = set_ascii(get_cpu_vendor(cpu), s, cs);
if(art == NULL)
return false;
return false;
char* uarch = get_str_uarch(cpu);
char* manufacturing_process = get_str_process(cpu);
char* sockets = get_str_sockets(cpu->topo);
@@ -480,7 +480,7 @@ bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
setAttribute(art,ATTRIBUTE_NCORES,n_cores);
}
setAttribute(art,ATTRIBUTE_AVX,avx);
setAttribute(art,ATTRIBUTE_FMA,fma);
setAttribute(art,ATTRIBUTE_FMA,fma);
setAttribute(art,ATTRIBUTE_L1i,l1i);
setAttribute(art,ATTRIBUTE_L1d,l1d);
setAttribute(art,ATTRIBUTE_L2,l2);
@@ -488,7 +488,7 @@ bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
setAttribute(art,ATTRIBUTE_L3,l3);
}
setAttribute(art,ATTRIBUTE_PEAK,pp);
if(art->n_attributes_set > NUMBER_OF_LINES) {
printBug("The number of attributes set is bigger than the max that can be displayed");
return false;
@@ -566,8 +566,8 @@ void print_ascii(struct ascii* art) {
bool print_cpufetch_ppc(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
struct ascii* art = set_ascii(get_cpu_vendor(cpu), s, cs);
if(art == NULL)
return false;
return false;
char* uarch = get_str_uarch(cpu);
char* manufacturing_process = get_str_process(cpu);
char* sockets = get_str_sockets(cpu->topo);
@@ -624,25 +624,25 @@ void print_algorithm_snapd_mtk(struct ascii* art, int n) {
if(art->art[n][i] == '@')
printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset);
else if(art->art[n][i] == '#')
printf("%s%c%s", art->color2_ascii, art->ascii_chars[1], art->reset);
printf("%s%c%s", art->color2_ascii, art->ascii_chars[1], art->reset);
else
printf("%c",art->art[n][i]);
printf("%c",art->art[n][i]);
}
}
void print_algorithm_samsung(struct ascii* art, int n) {
int y_margin = 2;
int x_margin = 2 * y_margin;
for(int i=0; i < LINE_SIZE; i++) {
if(art->art[n][i] == '#') {
printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset);
}
else if((n >= y_margin && n < NUMBER_OF_LINES-y_margin) && (i >= x_margin && i < LINE_SIZE-x_margin)) {
if(art->art[n][i] == '#')
printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset);
printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset);
else
printf("%s%c%s","\x1b[48;2;10;10;10m" COLOR_FG_WHITE, art->art[n][i], art->reset);
printf("%s%c%s","\x1b[48;2;10;10;10m" COLOR_FG_WHITE, art->art[n][i], art->reset);
}
else
printf("%c", art->art[n][i]);
@@ -650,21 +650,21 @@ void print_algorithm_samsung(struct ascii* art, int n) {
}
void print_algorithm_arm(struct ascii* art, int n) {
for(int i=0; i < LINE_SIZE; i++) {
for(int i=0; i < LINE_SIZE; i++) {
if(art->art[n][i] == '#')
printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset);
printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset);
else
printf("%c",art->art[n][i]);
printf("%c",art->art[n][i]);
}
}
void print_ascii_arm(struct ascii* art, uint32_t la, void (*callback_print_algorithm)(struct ascii* art, int n)) {
void print_ascii_arm(struct ascii* art, uint32_t la, void (*callback_print_algorithm)(struct ascii* art, int n)) {
int attr_to_print = 0;
int attr_type;
char* attr_value;
uint32_t limit_up;
uint32_t limit_down;
uint32_t space_right;
uint32_t space_up = (NUMBER_OF_LINES - art->n_attributes_set)/2;
uint32_t space_down = NUMBER_OF_LINES - art->n_attributes_set - space_up;
@@ -678,7 +678,7 @@ void print_ascii_arm(struct ascii* art, uint32_t la, void (*callback_print_algor
}
bool add_space = false;
uint32_t len = max(art->n_attributes_set, NUMBER_OF_LINES);
for(uint32_t n=0; n < len; n++) {
if(n >= art->additional_spaces && n < NUMBER_OF_LINES + art->additional_spaces)
callback_print_algorithm(art, n - art->additional_spaces);
@@ -689,14 +689,14 @@ void print_ascii_arm(struct ascii* art, uint32_t la, void (*callback_print_algor
attr_type = art->attributes[attr_to_print]->type;
attr_value = art->attributes[attr_to_print]->value;
attr_to_print++;
if(attr_type == ATTRIBUTE_PEAK) {
add_space = false;
}
if(attr_type == ATTRIBUTE_CPU_NUM) {
printf("%s%s%s\n", art->color1_text, attr_value, art->reset);
add_space = true;
}
}
else {
if(add_space) {
space_right = 1 + (la - strlen(ATTRIBUTE_FIELDS[attr_type]));
@@ -715,30 +715,30 @@ void print_ascii_arm(struct ascii* art, uint32_t la, void (*callback_print_algor
void print_ascii(struct ascii* art) {
uint32_t longest_attribute = longest_attribute_length(art);
if(art->vendor == SOC_VENDOR_SNAPDRAGON || art->vendor == SOC_VENDOR_MEDIATEK || art->vendor == SOC_VENDOR_KIRIN || art->vendor == SOC_VENDOR_BROADCOM)
print_ascii_arm(art, longest_attribute, &print_algorithm_snapd_mtk);
print_ascii_arm(art, longest_attribute, &print_algorithm_snapd_mtk);
else if(art->vendor == SOC_VENDOR_EXYNOS)
print_ascii_arm(art, longest_attribute, &print_algorithm_samsung);
print_ascii_arm(art, longest_attribute, &print_algorithm_samsung);
else {
if(art->vendor != SOC_VENDOR_UNKNOWN)
printWarn("Invalid SOC vendor: %d\n", art->vendor);
print_ascii_arm(art, longest_attribute, &print_algorithm_arm);
}
}
bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
struct ascii* art = set_ascii(get_soc_vendor(cpu->soc), s, cs);
if(art == NULL)
return false;
return false;
char* manufacturing_process = get_str_process(cpu->soc);
char* soc_name = get_soc_name(cpu->soc);
char* features = get_str_features(cpu);
setAttribute(art,ATTRIBUTE_SOC,soc_name);
setAttribute(art,ATTRIBUTE_TECHNOLOGY,manufacturing_process);
if(cpu->num_cpus == 1) {
char* uarch = get_str_uarch(cpu);
char* max_frequency = get_str_freq(cpu->freq);
@@ -752,20 +752,20 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
* Cache functionality may be implemented
* in the future
*/
setAttribute(art,ATTRIBUTE_UARCH,uarch);
setAttribute(art,ATTRIBUTE_FREQUENCY,max_frequency);
setAttribute(art,ATTRIBUTE_NCORES,n_cores);
if(features != NULL) {
setAttribute(art, ATTRIBUTE_FEATURES, features);
}
setAttribute(art, ATTRIBUTE_FEATURES, features);
}
}
else {
struct cpuInfo* ptr = cpu;
struct cpuInfo* ptr = cpu;
for(int i = 0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) {
char* uarch = get_str_uarch(ptr);
char* max_frequency = get_str_freq(ptr->freq);
char* n_cores = get_str_topology(ptr, ptr->topo, false);
char* n_cores = get_str_topology(ptr, ptr->topo, false);
/*
* char* l1i = get_str_l1i(cpu->cach);
* char* l1d = get_str_l1d(cpu->cach);
@@ -775,22 +775,22 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
* Cache functionality may be implemented
* in the future
*/
char* cpu_num = malloc(sizeof(char) * 9);
char* cpu_num = emalloc(sizeof(char) * 9);
sprintf(cpu_num, "CPU %d:", i+1);
setAttribute(art, ATTRIBUTE_CPU_NUM, cpu_num);
setAttribute(art, ATTRIBUTE_UARCH, uarch);
setAttribute(art, ATTRIBUTE_FREQUENCY, max_frequency);
setAttribute(art, ATTRIBUTE_NCORES, n_cores);
if(features != NULL) {
setAttribute(art, ATTRIBUTE_FEATURES, features);
}
setAttribute(art, ATTRIBUTE_FEATURES, features);
}
}
}
char* pp = get_str_peak_performance(cpu);
setAttribute(art,ATTRIBUTE_PEAK,pp);
if(art->n_attributes_set > NUMBER_OF_LINES) {
if(art->n_attributes_set > NUMBER_OF_LINES) {
art->additional_spaces = (art->n_attributes_set - NUMBER_OF_LINES) / 2;
}
if(cpu->hv->present)
@@ -798,7 +798,7 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
print_ascii(art);
free(manufacturing_process);
free(manufacturing_process);
free(pp);
free(art->attributes);
@@ -823,7 +823,7 @@ bool print_cpufetch(struct cpuInfo* cpu, STYLE s, struct colors* cs) {
return false;
}
}
#ifdef ARCH_X86
return print_cpufetch_x86(cpu, s, cs);
#elif ARCH_PPC

View File

@@ -4,7 +4,7 @@
char* read_file(char* path, int* len) {
int fd = open(path, O_RDONLY);
if(fd == -1) {
return NULL;
}
@@ -13,17 +13,17 @@ char* read_file(char* path, int* len) {
int bytes_read = 0;
int offset = 0;
int block = 128;
char* buf = malloc(sizeof(char)*DEFAULT_FILE_SIZE);
char* buf = emalloc(sizeof(char)*DEFAULT_FILE_SIZE);
memset(buf, 0, sizeof(char)*DEFAULT_FILE_SIZE);
while ( (bytes_read = read(fd, buf+offset, block)) > 0 ) {
offset += bytes_read;
}
}
if (close(fd) == -1) {
return NULL;
}
*len = offset;
return buf;
}
@@ -49,7 +49,7 @@ long get_freq_from_file(char* path, bool hv_present) {
free(buf);
return UNKNOWN_FREQ;
}
// We will be getting the frequency in KHz
// We consider it is an error if frequency is
// greater than 10 GHz or less than 100 MHz
@@ -57,9 +57,9 @@ long get_freq_from_file(char* path, bool hv_present) {
printBug("Invalid data was read from file '%s': %ld\n", path, ret);
return UNKNOWN_FREQ;
}
free(buf);
return ret/1000;
}
@@ -128,7 +128,7 @@ int get_num_caches_from_files(char** paths, int num_paths) {
int SHARED_MAP_MAX_LEN = 8 + 1;
int filelen;
char* buf;
uint32_t* shared_maps = malloc(sizeof(uint32_t *) * num_paths);
uint32_t* shared_maps = emalloc(sizeof(uint32_t *) * num_paths);
// 1. Read cpu_shared_map from every core
for(int i=0; i < num_paths; i++) {
@@ -158,7 +158,7 @@ int get_num_caches_from_files(char** paths, int num_paths) {
// 2. Count number of different masks; this is the number of caches
int num_caches = 0;
bool found = false;
uint32_t* unique_shared_maps = malloc(sizeof(uint32_t *) * num_paths);
uint32_t* unique_shared_maps = emalloc(sizeof(uint32_t *) * num_paths);
for(int i=0; i < num_paths; i++) unique_shared_maps[i] = 0;
for(int i=0; i < num_paths; i++) {
@@ -176,7 +176,7 @@ int get_num_caches_from_files(char** paths, int num_paths) {
}
int get_num_caches_by_level(struct cpuInfo* cpu, uint32_t level) {
char** paths = malloc(sizeof(char *) * cpu->topo->total_cores);
char** paths = emalloc(sizeof(char *) * cpu->topo->total_cores);
char* cache_path = NULL;
if(level == 0) cache_path = _PATH_CACHE_L1I;
@@ -189,7 +189,7 @@ int get_num_caches_by_level(struct cpuInfo* cpu, uint32_t level) {
}
for(int i=0; i < cpu->topo->total_cores; i++) {
paths[i] = malloc(sizeof(char) * _PATH_CACHE_MAX_LEN);
paths[i] = emalloc(sizeof(char) * _PATH_CACHE_MAX_LEN);
sprintf(paths[i], "%s%s/cpu%d%s%s", _PATH_SYS_SYSTEM, _PATH_SYS_CPU, i, cache_path, _PATH_CACHE_SHARED_MAP);
}

View File

@@ -22,17 +22,17 @@ void init_topology_struct(struct topology* topo, struct cache* cach) {
}
void init_cache_struct(struct cache* cach) {
cach->L1i = malloc(sizeof(struct cach));
cach->L1d = malloc(sizeof(struct cach));
cach->L2 = malloc(sizeof(struct cach));
cach->L3 = malloc(sizeof(struct cach));
cach->cach_arr = malloc(sizeof(struct cach*) * 4);
cach->L1i = emalloc(sizeof(struct cach));
cach->L1d = emalloc(sizeof(struct cach));
cach->L2 = emalloc(sizeof(struct cach));
cach->L3 = emalloc(sizeof(struct cach));
cach->cach_arr = emalloc(sizeof(struct cach*) * 4);
cach->cach_arr[0] = cach->L1i;
cach->cach_arr[1] = cach->L1d;
cach->cach_arr[2] = cach->L2;
cach->cach_arr[3] = cach->L3;
cach->max_cache_level = 0;
cach->L1i->exists = false;
cach->L1d->exists = false;
@@ -41,7 +41,7 @@ void init_cache_struct(struct cache* cach) {
}
struct cache* get_cache_info(struct cpuInfo* cpu) {
struct cache* cach = malloc(sizeof(struct cache));
struct cache* cach = emalloc(sizeof(struct cache));
init_cache_struct(cach);
cach->L1i->size = get_l1i_cache_size(0);
@@ -74,7 +74,7 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
}
struct topology* get_topology_info(struct cache* cach) {
struct topology* topo = malloc(sizeof(struct topology));
struct topology* topo = emalloc(sizeof(struct topology));
init_topology_struct(topo, cach);
// 1. Total cores detection
@@ -85,14 +85,14 @@ struct topology* get_topology_info(struct cache* cach) {
// To find physical cores, we use topo->total_cores and core_ids
// To find number of sockets, we use package_ids
int* core_ids = malloc(sizeof(int) * topo->total_cores);
int* package_ids = malloc(sizeof(int) * topo->total_cores);
int* core_ids = emalloc(sizeof(int) * topo->total_cores);
int* package_ids = emalloc(sizeof(int) * topo->total_cores);
fill_core_ids_from_sys(core_ids, topo->total_cores);
fill_package_ids_from_sys(package_ids, topo->total_cores);
// 2. Socket detection
int *package_ids_count = malloc(sizeof(int) * topo->total_cores);
int *package_ids_count = emalloc(sizeof(int) * topo->total_cores);
for(int i=0; i < topo->total_cores; i++) {
package_ids_count[i] = 0;
}
@@ -106,7 +106,7 @@ struct topology* get_topology_info(struct cache* cach) {
}
// 3. Physical cores detection
int *core_ids_unified = malloc(sizeof(int) * topo->total_cores);
int *core_ids_unified = emalloc(sizeof(int) * topo->total_cores);
for(int i=0; i < topo->total_cores; i++) {
core_ids_unified[i] = -1;
}
@@ -147,7 +147,7 @@ struct uarch* get_cpu_uarch(struct cpuInfo* cpu) {
}
struct frequency* get_frequency_info() {
struct frequency* freq = malloc(sizeof(struct frequency));
struct frequency* freq = emalloc(sizeof(struct frequency));
freq->max = get_max_freq_from_file(0, false);
freq->base = get_min_freq_from_file(0, false);
@@ -156,8 +156,8 @@ struct frequency* get_frequency_info() {
}
struct cpuInfo* get_cpu_info() {
struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo));
struct features* feat = malloc(sizeof(struct features));
struct cpuInfo* cpu = emalloc(sizeof(struct cpuInfo));
struct features* feat = emalloc(sizeof(struct features));
cpu->feat = feat;
bool *ptr = &(feat->AES);
@@ -180,7 +180,7 @@ struct cpuInfo* get_cpu_info() {
}
char* get_str_altivec(struct cpuInfo* cpu) {
char* string = calloc(4, sizeof(char));
char* string = ecalloc(4, sizeof(char));
if(cpu->feat->altivec) strcpy(string, "Yes");
else strcpy(string, "No");
@@ -197,7 +197,7 @@ char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64
//7 for GFLOP/s and 6 for digits,eg 412.14
uint32_t size = 7+6+1+1;
assert(strlen(STRING_UNKNOWN)+1 <= size);
char* string = malloc(sizeof(char)*size);
char* string = emalloc(sizeof(char)*size);
//First check we have consistent data
if(freq == UNKNOWN_FREQ) {
@@ -223,7 +223,7 @@ char* get_str_topology(struct topology* topo, bool dual_socket) {
char* string;
if(topo->smt_supported > 1) {
uint32_t size = 3+3+17+1;
string = malloc(sizeof(char)*size);
string = emalloc(sizeof(char)*size);
if(dual_socket)
snprintf(string, size, "%d cores (%d threads)", topo->physical_cores * topo->sockets, topo->logical_cores * topo->sockets);
else
@@ -231,7 +231,7 @@ char* get_str_topology(struct topology* topo, bool dual_socket) {
}
else {
uint32_t size = 3+7+1;
string = malloc(sizeof(char)*size);
string = emalloc(sizeof(char)*size);
if(dual_socket)
snprintf(string, size, "%d cores",topo->physical_cores * topo->sockets);
else

View File

@@ -60,7 +60,7 @@ struct uarch {
#define FILL_START if (false) {}
#define FILL_UARCH(u, uarch, uarch_str, uarch_process) \
else if(u == uarch) { fill = true; str = uarch_str; process = uarch_process; }
#define FILL_END else { printBug("Found invalid microarchitecture: %d", u); }
#define FILL_END else { printBug("Found invalid microarchitecture: %d", u); }
void fill_uarch(struct uarch* arch, MICROARCH u) {
arch->uarch = u;
@@ -96,7 +96,7 @@ void fill_uarch(struct uarch* arch, MICROARCH u) {
FILL_END
if(fill) {
arch->uarch_str = malloc(sizeof(char) * (strlen(str)+1));
arch->uarch_str = emalloc(sizeof(char) * (strlen(str)+1));
strcpy(arch->uarch_str, str);
arch->process= process;
}
@@ -104,11 +104,11 @@ void fill_uarch(struct uarch* arch, MICROARCH u) {
/*
* PVR masks/values from arch/powerpc/kernel/cputable.c (Linux kernel)
* This list may be incorrect, incomplete or overly simplified,
* This list may be incorrect, incomplete or overly simplified,
* specially in the case of 32 bit entries
*/
struct uarch* get_uarch_from_pvr(uint32_t pvr) {
struct uarch* arch = malloc(sizeof(struct uarch));
struct uarch* arch = emalloc(sizeof(struct uarch));
UARCH_START
// 64 bit
@@ -250,11 +250,11 @@ bool has_altivec(struct uarch* arch) {
}
char* get_str_uarch(struct cpuInfo* cpu) {
return cpu->arch->uarch_str;
return cpu->arch->uarch_str;
}
char* get_str_process(struct cpuInfo* cpu) {
char* str = malloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
char* str = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
int32_t process = cpu->arch->process;
if(process == UNK) {

View File

@@ -60,7 +60,7 @@ uint32_t get_apic_id(bool x2apic_id) {
uint32_t ebx = 0;
uint32_t ecx = 0;
uint32_t edx = 0;
if(x2apic_id) {
eax = 0x0000000B;
cpuid(&eax, &ebx, &ecx, &edx);
@@ -92,12 +92,12 @@ bool bind_to_cpu(int cpu_id) {
cpuset_t currentCPU;
CPU_ZERO(&currentCPU);
CPU_SET(cpu_id, &currentCPU);
if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &currentCPU) == -1) {
if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &currentCPU) == -1) {
perror("cpuset_setaffinity");
return false;
}
return true;
#endif
#endif
}
#endif
@@ -109,51 +109,51 @@ bool fill_topo_masks_apic(struct topology* topo) {
uint32_t core_plus_smt_id_max_cnt;
uint32_t core_id_max_cnt;
uint32_t smt_id_per_core_max_cnt;
cpuid(&eax, &ebx, &ecx, &edx);
core_plus_smt_id_max_cnt = (ebx >> 16) & 0xFF;
eax = 0x00000004;
ecx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
core_id_max_cnt = (eax >> 26) + 1;
smt_id_per_core_max_cnt = core_plus_smt_id_max_cnt / core_id_max_cnt;
topo->apic->smt_mask = create_mask(smt_id_per_core_max_cnt, &(topo->apic->smt_mask_width));
smt_id_per_core_max_cnt = core_plus_smt_id_max_cnt / core_id_max_cnt;
topo->apic->smt_mask = create_mask(smt_id_per_core_max_cnt, &(topo->apic->smt_mask_width));
topo->apic->core_mask = create_mask(core_id_max_cnt,&(topo->apic->pkg_mask_shift));
topo->apic->pkg_mask_shift += topo->apic->smt_mask_width;
topo->apic->core_mask <<= topo->apic->smt_mask_width;
topo->apic->pkg_mask = (-1) ^ (topo->apic->core_mask | topo->apic->smt_mask);
return true;
}
bool fill_topo_masks_x2apic(struct topology* topo) {
int32_t level_type;
int32_t level_shift;
int32_t coreplus_smt_mask = 0;
bool level2 = false;
bool level1 = false;
uint32_t eax = 0;
uint32_t ebx = 0;
uint32_t ecx = 0;
uint32_t edx = 0;
uint32_t i = 0;
while(true) {
eax = 0x0000000B;
ecx = i;
cpuid(&eax, &ebx, &ecx, &edx);
if(ebx == 0) break;
level_type = (ecx >> 8) & 0xFF;
level_shift = eax & 0xFFF;
switch(level_type) {
level_shift = eax & 0xFFF;
switch(level_type) {
case 1: // SMT
topo->apic->smt_mask = ~(0xFFFFFFFF << level_shift);
topo->apic->smt_mask_width = level_shift;
@@ -170,10 +170,10 @@ bool fill_topo_masks_x2apic(struct topology* topo) {
printErr("Found invalid level when querying topology: %d", level_type);
break;
}
i++; // sublevel to query
}
if (level1 && level2) {
topo->apic->core_mask = coreplus_smt_mask ^ topo->apic->smt_mask;
}
@@ -194,13 +194,13 @@ bool fill_topo_masks_x2apic(struct topology* topo) {
// as the number of cores, but in the case of Xeon Phi KNL it is not
uint32_t max_apic_id_size(uint32_t** cache_id_apic, struct topology* topo) {
uint32_t max = 0;
for(int i=0; i < topo->cach->max_cache_level; i++) {
for(int j=0; j < topo->total_cores; j++) {
for(int j=0; j < topo->total_cores; j++) {
if(cache_id_apic[j][i] > max) max = cache_id_apic[j][i];
}
}
max++;
if(max > (uint32_t) topo->total_cores) return max;
return topo->total_cores;
@@ -208,15 +208,15 @@ uint32_t max_apic_id_size(uint32_t** cache_id_apic, struct topology* topo) {
bool build_topo_from_apic(uint32_t* apic_pkg, uint32_t* apic_smt, uint32_t** cache_id_apic, struct topology* topo) {
uint32_t size = max_apic_id_size(cache_id_apic, topo);
uint32_t* sockets = malloc(sizeof(uint32_t) * size);
uint32_t* smt = malloc(sizeof(uint32_t) * size);
uint32_t* apic_id = malloc(sizeof(uint32_t) * size);
uint32_t* sockets = emalloc(sizeof(uint32_t) * size);
uint32_t* smt = emalloc(sizeof(uint32_t) * size);
uint32_t* apic_id = emalloc(sizeof(uint32_t) * size);
uint32_t num_caches = 0;
memset(sockets, 0, sizeof(uint32_t) * size);
memset(smt, 0, sizeof(uint32_t) * size);
memset(apic_id, 0, sizeof(uint32_t) * size);
memset(apic_id, 0, sizeof(uint32_t) * size);
// System topology
for(int i=0; i < topo->total_cores; i++) {
sockets[apic_pkg[i]] = 1;
@@ -228,44 +228,44 @@ bool build_topo_from_apic(uint32_t* apic_pkg, uint32_t* apic_smt, uint32_t** cac
if(smt[i] != 0)
topo->smt_available++;
}
topo->logical_cores = topo->total_cores / topo->sockets;
topo->physical_cores = topo->logical_cores / topo->smt_available;
// Cache topology
for(int i=0; i < topo->cach->max_cache_level; i++) {
num_caches = 0;
memset(apic_id, 0, sizeof(uint32_t) * size);
for(int c=0; c < topo->total_cores; c++) {
for(int c=0; c < topo->total_cores; c++) {
apic_id[cache_id_apic[c][i]]++;
}
for(uint32_t c=0; c < size; c++) {
for(uint32_t c=0; c < size; c++) {
if(apic_id[c] > 0) num_caches++;
}
topo->cach->cach_arr[i]->num_caches = num_caches;
}
free(sockets);
free(smt);
free(apic_id);
return true;
}
void get_cache_topology_from_apic(struct topology* topo) {
void get_cache_topology_from_apic(struct topology* topo) {
uint32_t eax = 0x00000004;
uint32_t ebx = 0;
uint32_t ecx = 0;
uint32_t edx = 0;
for(int i=0; i < topo->cach->max_cache_level; i++) {
for(int i=0; i < topo->cach->max_cache_level; i++) {
eax = 0x00000004;
ecx = i;
cpuid(&eax, &ebx, &ecx, &edx);
uint32_t SMTMaxCntPerEachCache = ((eax >> 14) & 0x7FF) + 1;
uint32_t dummy;
topo->apic->cache_select_mask[i] = create_mask(SMTMaxCntPerEachCache,&dummy);
@@ -289,15 +289,15 @@ void add_apic_to_array(uint32_t apic, uint32_t* apic_ids, int n) {
if(apic_ids[i] != (uint32_t) -1) last = i+1;
i++;
}
if(!found) {
if(!found) {
apic_ids[last] = apic;
//printf("Added %d\n", apic);
}
}
bool fill_apic_ids(uint32_t* apic_ids, int n, bool x2apic_id) {
#ifdef __APPLE__
#ifdef __APPLE__
// macOS extremely dirty approach...
printf("cpufetch is computing APIC IDs, please wait...\n");
bool end = false;
@@ -306,11 +306,11 @@ bool fill_apic_ids(uint32_t* apic_ids, int n, bool x2apic_id) {
while(!end) {
apic = get_apic_id(x2apic_id);
add_apic_to_array(apic, apic_ids, n);
end = apic_array_full(apic_ids, n);
end = apic_array_full(apic_ids, n);
usleep(1000);
}
}
#else
for(int i=0; i < n; i++) {
if(!bind_to_cpu(i)) {
@@ -323,14 +323,14 @@ bool fill_apic_ids(uint32_t* apic_ids, int n, bool x2apic_id) {
return true;
}
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) {
uint32_t apic_id;
uint32_t* apic_ids = malloc(sizeof(uint32_t) * topo->total_cores);
uint32_t* apic_pkg = malloc(sizeof(uint32_t) * topo->total_cores);
uint32_t* apic_core = malloc(sizeof(uint32_t) * topo->total_cores);
uint32_t* apic_smt = malloc(sizeof(uint32_t) * topo->total_cores);
uint32_t** cache_smt_id_apic = malloc(sizeof(uint32_t*) * topo->total_cores);
uint32_t** cache_id_apic = malloc(sizeof(uint32_t*) * topo->total_cores);
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) {
uint32_t apic_id;
uint32_t* apic_ids = emalloc(sizeof(uint32_t) * topo->total_cores);
uint32_t* apic_pkg = emalloc(sizeof(uint32_t) * topo->total_cores);
uint32_t* apic_core = emalloc(sizeof(uint32_t) * topo->total_cores);
uint32_t* apic_smt = emalloc(sizeof(uint32_t) * topo->total_cores);
uint32_t** cache_smt_id_apic = emalloc(sizeof(uint32_t*) * topo->total_cores);
uint32_t** cache_id_apic = emalloc(sizeof(uint32_t*) * topo->total_cores);
bool x2apic_id;
if(cpu->maxLevels >= 0x0000000B) {
@@ -347,48 +347,48 @@ bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) {
else {
x2apic_id = false;
}
for(int i=0; i < topo->total_cores; i++) {
cache_smt_id_apic[i] = malloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
cache_id_apic[i] = malloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
cache_smt_id_apic[i] = emalloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
cache_id_apic[i] = emalloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
}
topo->apic->cache_select_mask = malloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
topo->apic->cache_id_apic = malloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
topo->apic->cache_select_mask = emalloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
topo->apic->cache_id_apic = emalloc(sizeof(uint32_t) * (topo->cach->max_cache_level));
if(x2apic_id) {
if(!fill_topo_masks_x2apic(topo))
return false;
}
else {
if(!fill_topo_masks_apic(topo))
return false;
return false;
}
get_cache_topology_from_apic(topo);
get_cache_topology_from_apic(topo);
if(!fill_apic_ids(apic_ids, topo->total_cores, x2apic_id))
return false;
for(int i=0; i < topo->total_cores; i++) {
for(int i=0; i < topo->total_cores; i++) {
apic_id = apic_ids[i];
apic_pkg[i] = (apic_id & topo->apic->pkg_mask) >> topo->apic->pkg_mask_shift;
apic_core[i] = (apic_id & topo->apic->core_mask) >> topo->apic->smt_mask_width;
apic_smt[i] = apic_id & topo->apic->smt_mask;
for(int c=0; c < topo->cach->max_cache_level; c++) {
cache_smt_id_apic[i][c] = apic_id & topo->apic->cache_select_mask[c];
cache_id_apic[i][c] = apic_id & (-1 ^ topo->apic->cache_select_mask[c]);
}
}
/* DEBUG
for(int i=0; i < topo->cach->max_cache_level; i++) {
printf("[CACH %1d]", i);
for(int j=0; j < topo->total_cores; j++)
printf("[%03d]", cache_id_apic[j][i]);
printf("\n");
}
}
for(int i=0; i < topo->total_cores; i++)
printf("[%2d] 0x%.8X\n", i, apic_pkg[i]);
printf("\n");
@@ -397,16 +397,16 @@ bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) {
printf("\n");
for(int i=0; i < topo->total_cores; i++)
printf("[%2d] 0x%.8X\n", i, apic_smt[i]);*/
bool ret = build_topo_from_apic(apic_pkg, apic_smt, cache_id_apic, topo);
// Assumption: If we cant get smt_available, we assume it is equal to smt_supported...
if (!x2apic_id) {
printWarn("Can't read SMT from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x0000000B, cpu->maxLevels);
printWarn("Can't read SMT from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x0000000B, cpu->maxLevels);
topo->smt_supported = topo->smt_available;
}
free(apic_pkg);
free(apic_core);
free(apic_smt);
@@ -416,17 +416,17 @@ bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) {
}
free(cache_smt_id_apic);
free(cache_id_apic);
return ret;
}
}
uint32_t is_smt_enabled_amd(struct topology* topo) {
#ifdef __APPLE__
UNUSED(topo);
return 1;
#else
#else
uint32_t id;
for(int i = 0; i < topo->total_cores; i++) {
if(!bind_to_cpu(i)) {
printErr("Failed binding to CPU %d", i);
@@ -435,7 +435,7 @@ uint32_t is_smt_enabled_amd(struct topology* topo) {
id = get_apic_id(false) & 1; // get the last bit
if(id == 1) return 2; // We assume there isn't any AMD CPU with more than 2th per core.
}
return 1;
#endif
return 1;
#endif
}

View File

@@ -58,22 +58,22 @@ void init_topology_struct(struct topology* topo, struct cache* cach) {
topo->smt_available = 0;
topo->smt_supported = 0;
topo->sockets = 0;
topo->apic = malloc(sizeof(struct apic));
topo->apic = emalloc(sizeof(struct apic));
topo->cach = cach;
}
void init_cache_struct(struct cache* cach) {
cach->L1i = malloc(sizeof(struct cach));
cach->L1d = malloc(sizeof(struct cach));
cach->L2 = malloc(sizeof(struct cach));
cach->L3 = malloc(sizeof(struct cach));
cach->cach_arr = malloc(sizeof(struct cach*) * 4);
cach->L1i = emalloc(sizeof(struct cach));
cach->L1d = emalloc(sizeof(struct cach));
cach->L2 = emalloc(sizeof(struct cach));
cach->L3 = emalloc(sizeof(struct cach));
cach->cach_arr = emalloc(sizeof(struct cach*) * 4);
cach->cach_arr[0] = cach->L1i;
cach->cach_arr[1] = cach->L1d;
cach->cach_arr[2] = cach->L2;
cach->cach_arr[3] = cach->L3;
cach->max_cache_level = 0;
cach->L1i->exists = false;
cach->L1d->exists = false;
@@ -83,7 +83,7 @@ void init_cache_struct(struct cache* cach) {
void get_name_cpuid(char* name, uint32_t reg1, uint32_t reg2, uint32_t reg3) {
uint32_t c = 0;
name[c++] = reg1 & MASK;
name[c++] = (reg1>>8) & MASK;
name[c++] = (reg1>>16) & MASK;
@@ -106,14 +106,14 @@ char* get_str_cpu_name_internal() {
uint32_t ecx = 0;
uint32_t edx = 0;
uint32_t c = 0;
char * name = malloc(sizeof(char) * CPU_NAME_MAX_LENGTH);
char * name = emalloc(sizeof(char) * CPU_NAME_MAX_LENGTH);
memset(name, 0, CPU_NAME_MAX_LENGTH);
for(int i=0; i < 3; i++) {
for(int i=0; i < 3; i++) {
eax = 0x80000002 + i;
cpuid(&eax, &ebx, &ecx, &edx);
name[c++] = eax & MASK;
name[c++] = (eax>>8) & MASK;
name[c++] = (eax>>16) & MASK;
@@ -129,22 +129,22 @@ char* get_str_cpu_name_internal() {
name[c++] = edx & MASK;
name[c++] = (edx>>8) & MASK;
name[c++] = (edx>>16) & MASK;
name[c++] = (edx>>24) & MASK;
name[c++] = (edx>>24) & MASK;
}
name[c] = '\0';
//Remove unused characters
//Remove unused characters
char *str = name;
char *dest = name;
// Remove spaces before name
while (*str != '\0' && *str == ' ')str++;
while (*str != '\0' && *str == ' ')str++;
// Remove spaces between the name and after it
while (*str != '\0') {
while (*str == ' ' && *(str + 1) == ' ') str++;
*dest++ = *str++;
}
*dest = '\0';
return name;
}
@@ -153,27 +153,27 @@ struct uarch* get_cpu_uarch(struct cpuInfo* cpu) {
uint32_t ebx = 0;
uint32_t ecx = 0;
uint32_t edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
uint32_t stepping = eax & 0xF;
uint32_t model = (eax >> 4) & 0xF;
uint32_t emodel = (eax >> 16) & 0xF;
uint32_t family = (eax >> 8) & 0xF;
uint32_t efamily = (eax >> 20) & 0xFF;
return get_uarch_from_cpuid(cpu, efamily, family, emodel, model, (int)stepping);
}
struct hypervisor* get_hp_info(bool hv_present) {
struct hypervisor* hv = malloc(sizeof(struct hypervisor));
struct hypervisor* hv = emalloc(sizeof(struct hypervisor));
if(!hv_present) {
hv->present = false;
return hv;
return hv;
}
hv->present = true;
hv->present = true;
uint32_t eax = 0x40000000;
uint32_t ebx = 0;
uint32_t ecx = 0;
@@ -184,37 +184,37 @@ struct hypervisor* get_hp_info(bool hv_present) {
char name[13];
memset(name, 0, 13);
get_name_cpuid(name, ebx, ecx, edx);
bool found = false;
uint8_t len = sizeof(hv_vendors_string) / sizeof(hv_vendors_string[0]);
for(uint8_t v=0; v < len && !found; v++) {
if(strcmp(hv_vendors_string[v], name) == 0) {
hv->hv_vendor = v;
found = true;
found = true;
}
}
if(!found) {
hv->hv_vendor = HV_VENDOR_INVALID;
printWarn("Unknown hypervisor vendor: %s", name);
printWarn("Unknown hypervisor vendor: %s", name);
}
hv->hv_name = hv_vendors_name[hv->hv_vendor];
return hv;
}
struct cpuInfo* get_cpu_info() {
struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo));
struct features* feat = malloc(sizeof(struct features));
struct cpuInfo* cpu = emalloc(sizeof(struct cpuInfo));
struct features* feat = emalloc(sizeof(struct features));
cpu->feat = feat;
bool *ptr = &(feat->AES);
for(uint32_t i = 0; i < sizeof(struct features)/sizeof(bool); i++, ptr++) {
*ptr = false;
}
uint32_t eax = 0;
uint32_t ebx = 0;
uint32_t ecx = 0;
@@ -228,11 +228,11 @@ struct cpuInfo* get_cpu_info() {
char name[13];
memset(name,0,13);
get_name_cpuid(name, ebx, edx, ecx);
if(strcmp(CPU_VENDOR_INTEL_STRING,name) == 0)
cpu->cpu_vendor = CPU_VENDOR_INTEL;
else if (strcmp(CPU_VENDOR_AMD_STRING,name) == 0)
cpu->cpu_vendor = CPU_VENDOR_AMD;
cpu->cpu_vendor = CPU_VENDOR_AMD;
else {
cpu->cpu_vendor = CPU_VENDOR_INVALID;
printErr("Unknown CPU vendor: %s", name);
@@ -245,7 +245,7 @@ struct cpuInfo* get_cpu_info() {
ecx = 0;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
cpu->maxExtendedLevels = eax;
cpu->maxExtendedLevels = eax;
//Fill instructions support
if (cpu->maxLevels >= 0x00000001){
@@ -271,7 +271,7 @@ struct cpuInfo* get_cpu_info() {
else {
printWarn("Can't read features information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000001, cpu->maxLevels);
}
if (cpu->maxLevels >= 0x00000007){
eax = 0x00000007;
ecx = 0x00000000;
@@ -288,9 +288,9 @@ struct cpuInfo* get_cpu_info() {
((ebx & (1U << 21)) != 0));
}
else {
printWarn("Can't read features information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000007, cpu->maxLevels);
printWarn("Can't read features information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000007, cpu->maxLevels);
}
if (cpu->maxExtendedLevels >= 0x80000001){
eax = 0x80000001;
cpuid(&eax, &ebx, &ecx, &edx);
@@ -298,25 +298,25 @@ struct cpuInfo* get_cpu_info() {
feat->FMA4 = (ecx & (1U << 16)) != 0;
}
else {
printWarn("Can't read features information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000001, cpu->maxExtendedLevels);
printWarn("Can't read features information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000001, cpu->maxExtendedLevels);
}
if (cpu->maxExtendedLevels >= 0x80000004){
cpu->cpu_name = get_str_cpu_name_internal();
}
else {
cpu->cpu_name = malloc(sizeof(char)*8);
else {
cpu->cpu_name = emalloc(sizeof(char)*8);
sprintf(cpu->cpu_name,"Unknown");
printWarn("Can't read cpu name from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000004, cpu->maxExtendedLevels);
printWarn("Can't read cpu name from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000004, cpu->maxExtendedLevels);
}
cpu->topology_extensions = false;
if(cpu->cpu_vendor == CPU_VENDOR_AMD && cpu->maxExtendedLevels >= 0x80000001) {
eax = 0x80000001;
cpuid(&eax, &ebx, &ecx, &edx);
cpuid(&eax, &ebx, &ecx, &edx);
cpu->topology_extensions = (ecx >> 22) & 1;
}
cpu->arch = get_cpu_uarch(cpu);
cpu->freq = get_frequency_info(cpu);
cpu->cach = get_cache_info(cpu);
@@ -328,26 +328,26 @@ struct cpuInfo* get_cpu_info() {
return cpu;
}
bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
if(cpu->maxExtendedLevels >= 0x8000001D && cpu->topology_extensions) {
bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
if(cpu->maxExtendedLevels >= 0x8000001D && cpu->topology_extensions) {
uint32_t i, eax, ebx, ecx, edx, num_sharing_cache, cache_type, cache_level;
i = 0;
do {
eax = 0x8000001D;
ebx = 0;
ecx = i; // cache id
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
cache_type = eax & 0x1F;
cpuid(&eax, &ebx, &ecx, &edx);
cache_type = eax & 0x1F;
if(cache_type > 0) {
num_sharing_cache = ((eax >> 14) & 0xFFF) + 1;
cache_level = (eax >>= 5) & 0x7;
switch (cache_type) {
num_sharing_cache = ((eax >> 14) & 0xFFF) + 1;
cache_level = (eax >>= 5) & 0x7;
switch (cache_type) {
case 1: // Data Cache (We assume this is L1d)
if(cache_level != 1) {
printBug("Found data cache at level %d (expected 1)", cache_level);
@@ -355,7 +355,7 @@ bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
}
topo->cach->L1d->num_caches = topo->logical_cores / num_sharing_cache;
break;
case 2: // Instruction Cache (We assume this is L1i)
if(cache_level != 1) {
printBug("Found instruction cache at level %d (expected 1)", cache_level);
@@ -363,9 +363,9 @@ bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
}
topo->cach->L1i->num_caches = topo->logical_cores / num_sharing_cache;
break;
case 3: // Unified Cache (This may be L2 or L3)
if(cache_level == 2) {
if(cache_level == 2) {
topo->cach->L2->num_caches = topo->logical_cores / num_sharing_cache;
}
else if(cache_level == 3) {
@@ -375,44 +375,44 @@ bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
printWarn("Found unknown unified cache at level %d", cache_level);
}
break;
default: // Unknown cache type
printBug("Unknown cache type %d with level %d found at i=%d", cache_type, cache_level, i);
return false;
}
return false;
}
}
i++;
} while (cache_type > 0);
} while (cache_type > 0);
}
else {
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s). Guessing cache topology", 0x8000001D, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s). Guessing cache topology", 0x8000001D, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
topo->cach->L1i->num_caches = topo->physical_cores;
topo->cach->L1d->num_caches = topo->physical_cores;
if(topo->cach->L3->exists) {
topo->cach->L2->num_caches = topo->physical_cores;
topo->cach->L3->num_caches = 1;
topo->cach->L3->num_caches = 1;
}
else {
topo->cach->L2->num_caches = 1;
topo->cach->L2->num_caches = 1;
}
}
return true;
}
// Main reference: https://software.intel.com/content/www/us/en/develop/articles/intel-64-architecture-processor-topology-enumeration.html
// Very interesting resource: https://wiki.osdev.org/Detecting_CPU_Topology_(80x86)
struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach) {
struct topology* topo = malloc(sizeof(struct topology));
struct topology* topo = emalloc(sizeof(struct topology));
init_topology_struct(topo, cach);
uint32_t eax = 0;
uint32_t ebx = 0;
uint32_t ecx = 0;
uint32_t edx = 0;
// Ask the OS the total number of cores it sees
// If we have one socket, it will be same as the cpuid,
// but in dual socket it will not!
@@ -425,45 +425,45 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach) {
if((topo->total_cores = sysconf(_SC_NPROCESSORS_ONLN)) == -1) {
perror("sysconf");
topo->total_cores = topo->logical_cores; // fallback
}
#endif
}
#endif
switch(cpu->cpu_vendor) {
case CPU_VENDOR_INTEL:
if (cpu->maxLevels >= 0x00000004) {
if (cpu->maxLevels >= 0x00000004) {
get_topology_from_apic(cpu, topo);
}
else {
printWarn("Can't read topology information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000001, cpu->maxLevels);
else {
printWarn("Can't read topology information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000001, cpu->maxLevels);
topo->physical_cores = 1;
topo->logical_cores = 1;
topo->smt_available = 1;
topo->smt_supported = 1;
}
}
break;
case CPU_VENDOR_AMD:
case CPU_VENDOR_AMD:
if (cpu->maxExtendedLevels >= 0x80000008) {
eax = 0x80000008;
cpuid(&eax, &ebx, &ecx, &edx);
eax = 0x80000008;
cpuid(&eax, &ebx, &ecx, &edx);
topo->logical_cores = (ecx & 0xFF) + 1;
if (cpu->maxExtendedLevels >= 0x8000001E && cpu->topology_extensions) {
eax = 0x8000001E;
eax = 0x8000001E;
cpuid(&eax, &ebx, &ecx, &edx);
topo->smt_supported = ((ebx >> 8) & 0x03) + 1;
topo->smt_supported = ((ebx >> 8) & 0x03) + 1;
}
else {
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s)", 0x8000001E, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
topo->smt_supported = 1;
}
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s)", 0x8000001E, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
topo->smt_supported = 1;
}
}
else {
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000008, cpu->maxExtendedLevels);
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000008, cpu->maxExtendedLevels);
topo->physical_cores = 1;
topo->logical_cores = 1;
topo->smt_supported = 1;
topo->smt_supported = 1;
}
if (cpu->maxLevels >= 0x00000001) {
if(topo->smt_supported > 1)
topo->smt_available = is_smt_enabled_amd(topo);
@@ -471,25 +471,25 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach) {
topo->smt_available = 1;
}
else {
printWarn("Can't read topology information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x0000000B, cpu->maxLevels);
printWarn("Can't read topology information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x0000000B, cpu->maxLevels);
topo->smt_available = 1;
}
topo->physical_cores = topo->logical_cores / topo->smt_available;
if(topo->smt_supported > 1)
topo->sockets = topo->total_cores / topo->smt_supported / topo->physical_cores; // Idea borrowed from lscpu
else
topo->sockets = topo->total_cores / topo->physical_cores;
get_cache_topology_amd(cpu, topo);
topo->sockets = topo->total_cores / topo->physical_cores;
get_cache_topology_amd(cpu, topo);
break;
default:
printBug("Cant get topology because VENDOR is empty");
return NULL;
}
return topo;
}
@@ -499,13 +499,13 @@ struct cache* get_cache_info_amd_fallback(struct cache* cach) {
uint32_t ecx = 0;
uint32_t edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
cach->L1d->size = (ecx >> 24) * 1024;
cach->L1i->size = (edx >> 24) * 1024;
eax = 0x80000006;
cpuid(&eax, &ebx, &ecx, &edx);
cach->L2->size = (ecx >> 16) * 1024;
cach->L3->size = (edx >> 18) * 512 * 1024;
@@ -529,17 +529,17 @@ struct cache* get_cache_info_general(struct cache* cach, uint32_t level) {
uint32_t edx = 0;
int i=0;
int32_t cache_type;
do {
eax = level; // get cache info
ebx = 0;
ecx = i; // cache id
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
cpuid(&eax, &ebx, &ecx, &edx);
cache_type = eax & 0x1F;
// If its 0, we tried fetching a non existing cache
if (cache_type > 0) {
int32_t cache_level = (eax >>= 5) & 0x7;
@@ -547,11 +547,11 @@ struct cache* get_cache_info_general(struct cache* cach, uint32_t level) {
uint32_t cache_coherency_line_size = (ebx & 0xFFF) + 1;
uint32_t cache_physical_line_partitions = ((ebx >>= 12) & 0x3FF) + 1;
uint32_t cache_ways_of_associativity = ((ebx >>= 10) & 0x3FF) + 1;
int32_t cache_total_size = cache_ways_of_associativity * cache_physical_line_partitions * cache_coherency_line_size * cache_sets;
int32_t cache_total_size = cache_ways_of_associativity * cache_physical_line_partitions * cache_coherency_line_size * cache_sets;
cach->max_cache_level++;
switch (cache_type) {
switch (cache_type) {
case 1: // Data Cache (We assume this is L1d)
if(cache_level != 1) {
printBug("Found data cache at level %d (expected 1)", cache_level);
@@ -560,7 +560,7 @@ struct cache* get_cache_info_general(struct cache* cach, uint32_t level) {
cach->L1d->size = cache_total_size;
cach->L1d->exists = true;
break;
case 2: // Instruction Cache (We assume this is L1i)
if(cache_level != 1) {
printBug("Found instruction cache at level %d (expected 1)", cache_level);
@@ -569,9 +569,9 @@ struct cache* get_cache_info_general(struct cache* cach, uint32_t level) {
cach->L1i->size = cache_total_size;
cach->L1i->exists = true;
break;
case 3: // Unified Cache (This may be L2 or L3)
if(cache_level == 2) {
if(cache_level == 2) {
cach->L2->size = cache_total_size;
cach->L2->exists = true;
}
@@ -584,21 +584,21 @@ struct cache* get_cache_info_general(struct cache* cach, uint32_t level) {
cach->max_cache_level--;
}
break;
default: // Unknown cache type
printBug("Unknown cache type %d with level %d found at i=%d", cache_type, cache_level, i);
return NULL;
return NULL;
}
}
}
i++;
} while (cache_type > 0);
return cach;
}
struct cache* get_cache_info(struct cpuInfo* cpu) {
struct cache* cach = malloc(sizeof(struct cache));
struct cache* get_cache_info(struct cpuInfo* cpu) {
struct cache* cach = emalloc(sizeof(struct cache));
init_cache_struct(cach);
uint32_t level;
@@ -607,9 +607,9 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
// We use extended 0x8000001D for AMD
// or 0x80000005/6 for old AMD
if(cpu->cpu_vendor == CPU_VENDOR_INTEL) {
level = 0x00000004;
level = 0x00000004;
if(cpu->maxLevels < level) {
printWarn("Can't read cache information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", level, cpu->maxLevels);
printWarn("Can't read cache information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", level, cpu->maxLevels);
return NULL;
}
else {
@@ -619,7 +619,7 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
else {
level = 0x8000001D;
if(cpu->maxExtendedLevels < level || !cpu->topology_extensions) {
printWarn("Can't read cache information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s)", level, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
printWarn("Can't read cache information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s)", level, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
level = 0x80000006;
if(cpu->maxExtendedLevels < level) {
printWarn("Can't read cache information from cpuid using old method (needed extended level is 0x%.8X, max is 0x%.8X)", level, cpu->maxExtendedLevels);
@@ -629,7 +629,7 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
cach = get_cache_info_amd_fallback(cach);
}
else {
cach = get_cache_info_general(cach, level);
cach = get_cache_info_general(cach, level);
}
}
@@ -637,8 +637,8 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
}
struct frequency* get_frequency_info(struct cpuInfo* cpu) {
struct frequency* freq = malloc(sizeof(struct frequency));
struct frequency* freq = emalloc(sizeof(struct frequency));
if(cpu->maxLevels < 0x00000016) {
#if defined (_WIN32) || defined (__APPLE__)
printWarn("Can't read frequency information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000016, cpu->maxLevels);
@@ -703,7 +703,7 @@ char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64
//7 for GFLOP/s and 6 for digits,eg 412.14
uint32_t size = 7+6+1+1;
assert(strlen(STRING_UNKNOWN)+1 <= size);
char* string = malloc(sizeof(char)*size);
char* string = emalloc(sizeof(char)*size);
//First check we have consistent data
if(freq == UNKNOWN_FREQ) {
@@ -714,8 +714,8 @@ char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64
struct features* feat = cpu->feat;
double flops = topo->physical_cores * topo->sockets * (freq*1000000);
int vpus = get_number_of_vpus(cpu);
flops = flops * vpus;
flops = flops * vpus;
if(feat->FMA3 || feat->FMA4)
flops = flops*2;
@@ -729,11 +729,11 @@ char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64
flops = flops*8;
else if(feat->SSE)
flops = flops*4;
// See https://sites.utexas.edu/jdm4372/2018/01/22/a-peculiar-
// throughput-limitation-on-intels-xeon-phi-x200-knights-landing/
if(is_knights_landing(cpu))
flops = flops * 6 / 7;
flops = flops * 6 / 7;
if(flops >= (double)1000000000000.0)
snprintf(string,size,"%.2f TFLOP/s",flops/1000000000000);
@@ -741,7 +741,7 @@ char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64
snprintf(string,size,"%.2f GFLOP/s",flops/1000000000);
else
snprintf(string,size,"%.2f MFLOP/s",flops/1000000);
return string;
}
@@ -751,7 +751,7 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_soc
if(topo->smt_supported > 1) {
//3 for digits, 21 for ' cores (SMT disabled)' which is the longest possible output
uint32_t size = 3+21+1;
string = malloc(sizeof(char)*size);
string = emalloc(sizeof(char)*size);
if(dual_socket) {
if(topo->smt_available > 1)
snprintf(string, size, "%d cores (%d threads)",topo->physical_cores * topo->sockets, topo->logical_cores * topo->sockets);
@@ -775,7 +775,7 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_soc
}
else {
uint32_t size = 3+7+1;
string = malloc(sizeof(char)*size);
string = emalloc(sizeof(char)*size);
if(dual_socket)
snprintf(string, size, "%d cores",topo->physical_cores * topo->sockets);
else
@@ -786,7 +786,7 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_soc
char* get_str_avx(struct cpuInfo* cpu) {
//If all AVX are available, it will use up to 15
char* string = malloc(sizeof(char)*17+1);
char* string = emalloc(sizeof(char)*17+1);
if(!cpu->feat->AVX)
snprintf(string,2+1,"No");
else if(!cpu->feat->AVX2)
@@ -808,7 +808,7 @@ char* get_str_sse(struct cpuInfo* cpu) {
uint32_t SSE4a_sl = 6;
uint32_t SSE4_1_sl = 7;
uint32_t SSE4_2_sl = 7;
char* string = malloc(sizeof(char)*SSE_sl+SSE2_sl+SSE3_sl+SSSE3_sl+SSE4a_sl+SSE4_1_sl+SSE4_2_sl+1);
char* string = emalloc(sizeof(char)*SSE_sl+SSE2_sl+SSE3_sl+SSSE3_sl+SSE4a_sl+SSE4_1_sl+SSE4_2_sl+1);
if(cpu->feat->SSE) {
snprintf(string+last,SSE_sl+1,"SSE,");
@@ -845,7 +845,7 @@ char* get_str_sse(struct cpuInfo* cpu) {
}
char* get_str_fma(struct cpuInfo* cpu) {
char* string = malloc(sizeof(char)*9+1);
char* string = emalloc(sizeof(char)*9+1);
if(!cpu->feat->FMA3)
snprintf(string,2+1,"No");
else if(!cpu->feat->FMA4)
@@ -861,9 +861,9 @@ void print_debug(struct cpuInfo* cpu) {
uint32_t ebx = 0;
uint32_t ecx = 0;
uint32_t edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
printf("%s\n", cpu->cpu_name);
if(cpu->hv->present) {
printf("- Hypervisor: %s\n", cpu->hv->hv_name);
@@ -871,7 +871,7 @@ void print_debug(struct cpuInfo* cpu) {
printf("- Max standard level: 0x%.8X\n", cpu->maxLevels);
printf("- Max extended level: 0x%.8X\n", cpu->maxExtendedLevels);
if(cpu->cpu_vendor == CPU_VENDOR_AMD) {
printf("- AMD topology extensions: %d\n", cpu->topology_extensions);
printf("- AMD topology extensions: %d\n", cpu->topology_extensions);
}
printf("- CPUID dump: 0x%.8X\n", eax);
@@ -887,7 +887,7 @@ void print_raw(struct cpuInfo* cpu) {
printf("%s\n\n", cpu->cpu_name);
printf(" CPUID leaf sub EAX EBX ECX EDX \n");
printf("--------------------------------------------------------------\n");
for(int c=0; c < cpu->topo->total_cores; c++) {
#ifndef __APPLE__
if(!bind_to_cpu(c)) {
@@ -895,9 +895,9 @@ void print_raw(struct cpuInfo* cpu) {
return;
}
#endif
printf("CPU %d:\n", c);
printf("CPU %d:\n", c);
for(uint32_t reg=0x00000000; reg <= cpu->maxLevels; reg++) {
if(reg == 0x00000004) {
for(uint32_t reg2=0x00000000; reg2 < cpu->cach->max_cache_level; reg2++) {
@@ -905,9 +905,9 @@ void print_raw(struct cpuInfo* cpu) {
ebx = 0;
ecx = reg2;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, reg2, eax, ebx, ecx, edx);
}
}
@@ -917,9 +917,9 @@ void print_raw(struct cpuInfo* cpu) {
ebx = 0;
ecx = reg2;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, reg2, eax, ebx, ecx, edx);
}
}
@@ -928,10 +928,10 @@ void print_raw(struct cpuInfo* cpu) {
ebx = 0;
ecx = 0;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, 0x00, eax, ebx, ecx, edx);
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, 0x00, eax, ebx, ecx, edx);
}
}
for(uint32_t reg=0x80000000; reg <= cpu->maxExtendedLevels; reg++) {
@@ -941,9 +941,9 @@ void print_raw(struct cpuInfo* cpu) {
ebx = 0;
ecx = reg2;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, reg2, eax, ebx, ecx, edx);
}
}
@@ -952,9 +952,9 @@ void print_raw(struct cpuInfo* cpu) {
ebx = 0;
ecx = 0;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, 0x00, eax, ebx, ecx, edx);
}
}

View File

@@ -124,7 +124,7 @@ struct uarch {
#define UARCH_END else { printBug("Unknown microarchitecture detected: M=0x%.8X EM=0x%.8X F=0x%.8X EF=0x%.8X S=0x%.8X", m, em, f, ef, s); fill_uarch(arch, "Unknown", UARCH_UNKNOWN, 0); }
void fill_uarch(struct uarch* arch, char* str, MICROARCH u, uint32_t process) {
arch->uarch_str = malloc(sizeof(char) * (strlen(str)+1));
arch->uarch_str = emalloc(sizeof(char) * (strlen(str)+1));
strcpy(arch->uarch_str, str);
arch->uarch = u;
arch->process= process;
@@ -132,8 +132,8 @@ void fill_uarch(struct uarch* arch, char* str, MICROARCH u, uint32_t process) {
// Inspired in Todd Allen's decode_uarch_intel
struct uarch* get_uarch_from_cpuid_intel(uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
struct uarch* arch = malloc(sizeof(struct uarch));
struct uarch* arch = emalloc(sizeof(struct uarch));
// EF: Extended Family //
// F: Family //
// EM: Extended Model //
@@ -249,14 +249,14 @@ struct uarch* get_uarch_from_cpuid_intel(uint32_t ef, uint32_t f, uint32_t em, u
CHECK_UARCH(arch, 1, 15, 0, 1, NA, "Itanium2", UARCH_ITANIUM2, 130)
CHECK_UARCH(arch, 1, 15, 0, 2, NA, "Itanium2", UARCH_ITANIUM2, 130)
UARCH_END
return arch;
}
// iNApired in Todd Allen's decode_uarch_amd
struct uarch* get_uarch_from_cpuid_amd(uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
struct uarch* arch = malloc(sizeof(struct uarch));
struct uarch* arch = emalloc(sizeof(struct uarch));
// EF: Extended Family //
// F: Family //
// EM: Extended Model //
@@ -264,7 +264,7 @@ struct uarch* get_uarch_from_cpuid_amd(uint32_t ef, uint32_t f, uint32_t em, uin
// S: Stepping //
// ----------------------------------------------------------------------------- //
// EF F EM M S //
UARCH_START
UARCH_START
CHECK_UARCH(arch, 0, 4, 0, 3, NA, "Am486", UARCH_AM486, UNK)
CHECK_UARCH(arch, 0, 4, 0, 7, NA, "Am486", UARCH_AM486, UNK)
CHECK_UARCH(arch, 0, 4, 0, 8, NA, "Am486", UARCH_AM486, UNK)
@@ -352,14 +352,14 @@ struct uarch* get_uarch_from_cpuid_amd(uint32_t ef, uint32_t f, uint32_t em, uin
CHECK_UARCH(arch, 10, 15, 2, 1, NA, "Zen 3", UARCH_ZEN3, 7) // instlatx64
CHECK_UARCH(arch, 10, 15, 5, 0, NA, "Zen 3", UARCH_ZEN3, 7) // instlatx64
UARCH_END
return arch;
}
struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
if(cpu->cpu_vendor == CPU_VENDOR_INTEL)
return get_uarch_from_cpuid_intel(ef, f, em, m, s);
else
else
return get_uarch_from_cpuid_amd(ef, f, em, m, s);
}
@@ -368,33 +368,33 @@ bool vpus_are_AVX512(struct cpuInfo* cpu) {
}
bool is_knights_landing(struct cpuInfo* cpu) {
return cpu->arch->uarch == UARCH_KNIGHTS_LANDING;
return cpu->arch->uarch == UARCH_KNIGHTS_LANDING;
}
int get_number_of_vpus(struct cpuInfo* cpu) {
int get_number_of_vpus(struct cpuInfo* cpu) {
switch(cpu->arch->uarch) {
// Intel
case UARCH_HASWELL:
case UARCH_BROADWELL:
case UARCH_SKYLAKE:
case UARCH_CASCADE_LAKE:
case UARCH_CASCADE_LAKE:
case UARCH_KABY_LAKE:
case UARCH_COMET_LAKE:
case UARCH_ROCKET_LAKE:
case UARCH_AMBER_LAKE:
case UARCH_WHISKEY_LAKE:
case UARCH_COFFE_LAKE:
case UARCH_PALM_COVE:
case UARCH_PALM_COVE:
case UARCH_KNIGHTS_LANDING:
case UARCH_KNIGHTS_MILL:
case UARCH_ICE_LAKE:
case UARCH_ICE_LAKE:
// AMD
case UARCH_ZEN2:
case UARCH_ZEN3:
case UARCH_ZEN3:
return 2;
default:
return 1;
@@ -402,11 +402,11 @@ int get_number_of_vpus(struct cpuInfo* cpu) {
}
char* get_str_uarch(struct cpuInfo* cpu) {
return cpu->arch->uarch_str;
return cpu->arch->uarch_str;
}
char* get_str_process(struct cpuInfo* cpu) {
char* str = malloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
char* str = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1));
int32_t process = cpu->arch->process;
if(process == UNK) {
@@ -426,7 +426,7 @@ char* get_str_process(struct cpuInfo* cpu) {
return str;
}
void free_uarch_struct(struct uarch* arch) {
void free_uarch_struct(struct uarch* arch) {
free(arch->uarch_str);
free(arch);
}