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
is_cmdline_para(const char * para)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
is_ht_kernel()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
is_ht_cpu()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
is_ht_enabled()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.
check_ht_capability()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
get_cpu_count()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
get_current_cpu(pid_t pid)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