diff --git a/src/arm/midr.c b/src/arm/midr.c index 2a45e77..f59f2b1 100644 --- a/src/arm/midr.c +++ b/src/arm/midr.c @@ -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) { diff --git a/src/arm/soc.c b/src/arm/soc.c index a8e8889..b28b934 100644 --- a/src/arm/soc.c +++ b/src/arm/soc.c @@ -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; } - diff --git a/src/arm/uarch.c b/src/arm/uarch.c index 5082137..9da5461 100644 --- a/src/arm/uarch.c +++ b/src/arm/uarch.c @@ -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); } - diff --git a/src/arm/udev.c b/src/arm/udev.c index c6c46c8..02d782b 100644 --- a/src/arm/udev.c +++ b/src/arm/udev.c @@ -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); diff --git a/src/common/args.c b/src/common/args.c index 8cd16f2..c686321 100644 --- a/src/common/args.c +++ b/src/common/args.c @@ -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; } diff --git a/src/common/cpu.c b/src/common/cpu.c index 84a0ec8..f93e950 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -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) diff --git a/src/common/global.c b/src/common/global.c index e4042aa..8b9f538 100644 --- a/src/common/global.c +++ b/src/common/global.c @@ -1,5 +1,9 @@ #include #include +#include +#include +#include + #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; +} diff --git a/src/common/global.h b/src/common/global.h index 1813143..5e090f0 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -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 diff --git a/src/common/printer.c b/src/common/printer.c index 76f5d97..c052ffa 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -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 diff --git a/src/common/udev.c b/src/common/udev.c index e670b65..3f72467 100644 --- a/src/common/udev.c +++ b/src/common/udev.c @@ -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); } diff --git a/src/ppc/ppc.c b/src/ppc/ppc.c index 00de361..f28b6e6 100644 --- a/src/ppc/ppc.c +++ b/src/ppc/ppc.c @@ -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 diff --git a/src/ppc/uarch.c b/src/ppc/uarch.c index 52b4273..4be62f2 100644 --- a/src/ppc/uarch.c +++ b/src/ppc/uarch.c @@ -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) { diff --git a/src/x86/apic.c b/src/x86/apic.c index 7cbd90a..ad6c768 100644 --- a/src/x86/apic.c +++ b/src/x86/apic.c @@ -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(¤tCPU); CPU_SET(cpu_id, ¤tCPU); - if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), ¤tCPU) == -1) { + if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), ¤tCPU) == -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 } diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index 66e44f8..e01e9f8 100644 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -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); } } diff --git a/src/x86/uarch.c b/src/x86/uarch.c index 3f6bb0c..57ba7f2 100644 --- a/src/x86/uarch.c +++ b/src/x86/uarch.c @@ -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); }