#include "ht_utils.h" #include <stdio.h> #include <stdlib.h> #include <alloca.h> #include <string.h> #include <linux/unistd.h> #include "ltp_cpuid.h" #define PROC_PATH "/proc" #define BUFF_SIZE 8192 #define PROCESSOR_STR "processor" #define PACKAGE_STR "cpu_package" #define HT_FLAG "ht" #define FLAG_STR "flags" #define MAX_CPU_NUM 128 char buffer[BUFF_SIZE]; int is_cmdline_para(const char *para) { FILE *fp; if ((fp = fopen("/proc/cmdline", "r")) != NULL && para != NULL) { while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { if (strstr(buffer, para) != NULL) { fclose(fp); return 1; } } } /* If fopen succeeds and the pointer para is NULL, * It won't enter the above if-block. * so need to close fp here. */ if (fp != NULL) fclose(fp); return 0; } int is_ht_kernel() { FILE *fp; if ((fp = fopen("/proc/cpuinfo", "r")) != NULL) { while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { if (strncmp(buffer, PACKAGE_STR, strlen(PACKAGE_STR)) == 0) { fclose(fp); return 1; } } fclose(fp); } return 0; } int is_ht_cpu() { /*Number of logic processor in a physical processor */ int smp_num_siblings = -1; /*ht flag */ int ht = -1; unsigned int eax, ebx, ecx, edx; cpuid(1, &eax, &ebx, &ecx, &edx); smp_num_siblings = (ebx & 0xff0000) >> 16; ht = (edx & 0x10000000) >> 28; if (ht == 1 && smp_num_siblings == 2) { // printf("The processor in this system supports HT\n"); return 1; } else { // printf("The processor in this system does not support HT\n"); return 0; } } int is_ht_enabled() { int cpu_map[MAX_CPU_NUM]; /*A bit-map shows whether a 'logic' processor has ht flag */ int ht_cpu[MAX_CPU_NUM]; int logic_cpu_num = 0; int package = -1; int cpu_id = -1; char *ht_flag = NULL; int i = 0; int j = 0; int k = 0; FILE *fp; char *proc_cpuinfo = (char *)alloca(strlen(PROC_PATH) + sizeof("/cpuinfo")); strcat(strcpy(proc_cpuinfo, PROC_PATH), "/cpuinfo"); if ((fp = fopen(proc_cpuinfo, "r")) != NULL) { while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { if (strncmp (buffer, PROCESSOR_STR, strlen(PROCESSOR_STR)) == 0) { sscanf(buffer, PROCESSOR_STR "\t: %d", &cpu_id); ht_cpu[cpu_id] = 0; while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { if (strncmp (buffer, PACKAGE_STR, strlen(PACKAGE_STR)) == 0) { sscanf(buffer, PACKAGE_STR "\t: %d", &package); cpu_map[cpu_id] = package; printf("cpu_map[%d]=%d\n", cpu_id, package); } if (strncmp (buffer, FLAG_STR, strlen(FLAG_STR)) == 0) { ht_flag = buffer; while (*ht_flag != '\0') { /*printf("ht_flag=%s",ht_flag); */ if (strncmp (ht_flag, HT_FLAG, strlen(HT_FLAG)) == 0) { ht_cpu[cpu_id] = 1; break; } ht_flag++; } printf("ht_cpu[%d]=%d\n", cpu_id, ht_cpu[cpu_id]); logic_cpu_num += 1; break; } } } } } else return 0; fclose(fp); for (i = 0; i < logic_cpu_num; i++) { if (ht_cpu[i] == 1) { for (j = i + 1; j < logic_cpu_num; j++) { if (cpu_map[i] == cpu_map[j]) { for (k = j + 1; k < logic_cpu_num; k++) { if (cpu_map[j] == cpu_map[k]) { /* Not proper HT support, with 3 logic processor in 1 cpu package */ return 0; } } if (ht_cpu[j] == 1) { return 1; } else return 0; } } /* in this case, processor[i] has ht flag, but is not ht enabled */ if (j == logic_cpu_num) { return 0; } } } if (i == logic_cpu_num) { return 0; } return 0; } // return 0 means Pass, // return 1 means ht is not enabled, // return 2 means CPU is not support ht, // return 3 mean kernel is not support ht. int check_ht_capability() { int result; if (is_ht_kernel()) { if (is_ht_cpu()) { if (is_ht_enabled()) result = 0; //HT is enabled by default in this system. else result = 1; //HT is not enabled by default in this system. } else result = 2; //This processor does not support HT. } else result = 3; //HT feature is not included in this Linux Kernel. return result; } #define PROCFS_PATH "/proc/" #define CPUINFO_PATH "/proc/cpuinfo" #define CPU_NAME "processor" #define STAT_NAME "stat" char buf[256]; int get_cpu_count() { FILE *pfile; int count; if ((pfile = fopen(CPUINFO_PATH, "r")) == NULL) return 0; count = 0; while (fgets(buf, 255, pfile) != NULL) { if (strncmp(buf, CPU_NAME, strlen(CPU_NAME)) == 0) count++; } fclose(pfile); return count; } int get_current_cpu(pid_t pid) { int cpu = -1; int da; char str[100]; char ch; FILE *pfile; sprintf(buf, "%s%d/%s%c", PROCFS_PATH, pid, STAT_NAME, 0); if ((pfile = fopen(buf, "r")) == NULL) return -1; if (fscanf (pfile, "%d %s %c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", &da, str, &ch, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &cpu) <= 0) { fclose(pfile); return -1; } fclose(pfile); return cpu; }