| |
| #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; |
| } |
| } |
| 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; |
| } |