1 2 #include "ht_utils.h" 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <alloca.h> 7 #include <string.h> 8 #include <linux/unistd.h> 9 #include "ltp_cpuid.h" 10 11 #define PROC_PATH "/proc" 12 #define BUFF_SIZE 8192 13 #define PROCESSOR_STR "processor" 14 #define PACKAGE_STR "cpu_package" 15 #define HT_FLAG "ht" 16 #define FLAG_STR "flags" 17 18 #define MAX_CPU_NUM 128 19 20 char buffer[BUFF_SIZE]; 21 22 int is_cmdline_para(const char *para) 23 { 24 FILE *fp; 25 26 if ((fp = fopen("/proc/cmdline", "r")) != NULL && para != NULL) { 27 while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { 28 if (strstr(buffer, para) != NULL) { 29 fclose(fp); 30 return 1; 31 } 32 } 33 } 34 /* If fopen succeeds and the pointer para is NULL, 35 * It won't enter the above if-block. 36 * so need to close fp here. 37 */ 38 if (fp != NULL) 39 fclose(fp); 40 41 return 0; 42 } 43 44 int is_ht_kernel() 45 { 46 FILE *fp; 47 48 if ((fp = fopen("/proc/cpuinfo", "r")) != NULL) { 49 while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { 50 if (strncmp(buffer, PACKAGE_STR, strlen(PACKAGE_STR)) == 51 0) { 52 fclose(fp); 53 return 1; 54 } 55 } 56 fclose(fp); 57 } 58 59 return 0; 60 } 61 62 int is_ht_cpu() 63 { 64 /*Number of logic processor in a physical processor */ 65 int smp_num_siblings = -1; 66 /*ht flag */ 67 int ht = -1; 68 unsigned int eax, ebx, ecx, edx; 69 cpuid(1, &eax, &ebx, &ecx, &edx); 70 smp_num_siblings = (ebx & 0xff0000) >> 16; 71 ht = (edx & 0x10000000) >> 28; 72 73 if (ht == 1 && smp_num_siblings == 2) { 74 // printf("The processor in this system supports HT\n"); 75 return 1; 76 } else { 77 // printf("The processor in this system does not support HT\n"); 78 return 0; 79 } 80 } 81 82 int is_ht_enabled() 83 { 84 int cpu_map[MAX_CPU_NUM]; 85 /*A bit-map shows whether a 'logic' processor has ht flag */ 86 int ht_cpu[MAX_CPU_NUM]; 87 int logic_cpu_num = 0; 88 int package = -1; 89 int cpu_id = -1; 90 char *ht_flag = NULL; 91 int i = 0; 92 int j = 0; 93 int k = 0; 94 95 FILE *fp; 96 char *proc_cpuinfo = 97 (char *)alloca(strlen(PROC_PATH) + sizeof("/cpuinfo")); 98 strcat(strcpy(proc_cpuinfo, PROC_PATH), "/cpuinfo"); 99 100 if ((fp = fopen(proc_cpuinfo, "r")) != NULL) { 101 while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { 102 if (strncmp 103 (buffer, PROCESSOR_STR, 104 strlen(PROCESSOR_STR)) == 0) { 105 sscanf(buffer, PROCESSOR_STR "\t: %d", &cpu_id); 106 ht_cpu[cpu_id] = 0; 107 while (fgets(buffer, BUFF_SIZE - 1, fp) != NULL) { 108 if (strncmp 109 (buffer, PACKAGE_STR, 110 strlen(PACKAGE_STR)) == 0) { 111 sscanf(buffer, 112 PACKAGE_STR "\t: %d", 113 &package); 114 cpu_map[cpu_id] = package; 115 printf("cpu_map[%d]=%d\n", 116 cpu_id, package); 117 } 118 if (strncmp 119 (buffer, FLAG_STR, 120 strlen(FLAG_STR)) == 0) { 121 ht_flag = buffer; 122 while (*ht_flag != '\0') { 123 /*printf("ht_flag=%s",ht_flag); */ 124 if (strncmp 125 (ht_flag, HT_FLAG, 126 strlen(HT_FLAG)) == 127 0) { 128 ht_cpu[cpu_id] = 129 1; 130 break; 131 } 132 ht_flag++; 133 } 134 printf("ht_cpu[%d]=%d\n", 135 cpu_id, ht_cpu[cpu_id]); 136 logic_cpu_num += 1; 137 break; 138 } 139 } 140 } 141 } 142 } else 143 return 0; 144 145 fclose(fp); 146 147 for (i = 0; i < logic_cpu_num; i++) { 148 if (ht_cpu[i] == 1) { 149 for (j = i + 1; j < logic_cpu_num; j++) { 150 if (cpu_map[i] == cpu_map[j]) { 151 for (k = j + 1; k < logic_cpu_num; k++) { 152 if (cpu_map[j] == cpu_map[k]) { 153 /* Not proper HT support, with 3 logic processor in 1 cpu package */ 154 return 0; 155 } 156 } 157 if (ht_cpu[j] == 1) { 158 return 1; 159 } else 160 return 0; 161 } 162 } 163 /* in this case, processor[i] has ht flag, but is not ht enabled */ 164 if (j == logic_cpu_num) { 165 return 0; 166 } 167 } 168 } 169 if (i == logic_cpu_num) { 170 return 0; 171 } 172 return 0; 173 } 174 175 // return 0 means Pass, 176 // return 1 means ht is not enabled, 177 // return 2 means CPU is not support ht, 178 // return 3 mean kernel is not support ht. 179 int check_ht_capability() 180 { 181 int result; 182 183 if (is_ht_kernel()) { 184 if (is_ht_cpu()) { 185 if (is_ht_enabled()) 186 result = 0; //HT is enabled by default in this system. 187 else 188 result = 1; //HT is not enabled by default in this system. 189 } else 190 result = 2; //This processor does not support HT. 191 } else 192 result = 3; //HT feature is not included in this Linux Kernel. 193 194 return result; 195 } 196 197 #define PROCFS_PATH "/proc/" 198 #define CPUINFO_PATH "/proc/cpuinfo" 199 #define CPU_NAME "processor" 200 #define STAT_NAME "stat" 201 202 char buf[256]; 203 204 int get_cpu_count() 205 { 206 FILE *pfile; 207 int count; 208 209 if ((pfile = fopen(CPUINFO_PATH, "r")) == NULL) 210 return 0; 211 212 count = 0; 213 214 while (fgets(buf, 255, pfile) != NULL) { 215 if (strncmp(buf, CPU_NAME, strlen(CPU_NAME)) == 0) 216 count++; 217 } 218 219 fclose(pfile); 220 221 return count; 222 } 223 224 int get_current_cpu(pid_t pid) 225 { 226 int cpu = -1; 227 int da; 228 char str[100]; 229 char ch; 230 231 FILE *pfile; 232 233 sprintf(buf, "%s%d/%s%c", PROCFS_PATH, pid, STAT_NAME, 0); 234 235 if ((pfile = fopen(buf, "r")) == NULL) 236 return -1; 237 238 if (fscanf 239 (pfile, 240 "%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", 241 &da, str, &ch, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, 242 &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, 243 &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, &da, 244 &cpu) <= 0) { 245 fclose(pfile); 246 return -1; 247 } 248 249 fclose(pfile); 250 251 return cpu; 252 } 253