1 /***************************************************************************
2 HTaffinity.c - description
3 -------------------
4 email : sonic,zhang@intel.com
5 ***************************************************************************/
6
7 /***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15 #include "ht_utils.h"
16 #include <sys/syscall.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <sys/wait.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "test.h"
24
25 char *TCID = "smt_smp_affinity";
26 int TST_TOTAL = 3;
27
28 /************************************************************************************
29 int set_affinity(pid_t pid, unsigned int len, unsigned long *mask_ptr)
30 pid - pid of the process whose affinity is desired to be set.
31 mask_ptr - pointer to the new cpu_affinity_mask.
32 len - length in bytes of the bitmask pointed to by user_mask_ptr.
33
34 int get_affinity(pid_t pid, unsigned int len, unsigned long *mask_ptr)
35 pid - pid of the process whose affinity is being read.
36 mask_ptr pointer to store the current affinity information.
37 len - length in bytes of the bitmask pointed to by user_mask_ptr.
38 ************************************************************************************/
39
40 //Any application program can invoke these system call using sched_setaffinity() and sched_getaffinity(),
41 //with the syntax mentioned in the previous section, after declaring the interface as:
42
43 #define sched_setaffinity(pid, cpusetsize, mask) syscall(__NR_sched_setaffinity, pid, cpusetsize, mask)
44 #define sched_getaffinity(pid, cpusetsize, mask) syscall(__NR_sched_getaffinity, pid, cpusetsize, mask)
45
46 #define AFFINITY_NAME "affinity"
47 #define PROCFS_PATH "/proc/"
48
HT_SetAffinity(void)49 int HT_SetAffinity(void)
50 {
51 unsigned int mask;
52 pid_t pid;
53 int result = 1;
54 int cpu_count, i, j, k, cpuid;
55
56 pid = getpid();
57
58 tst_resm(TINFO, "Set affinity through system call");
59
60 cpu_count = get_cpu_count();
61 if (cpu_count == 0) {
62 return 0;
63 } else if (cpu_count > 32)
64 cpu_count = 32;
65
66 for (i = 0, mask = 0x1; i < cpu_count; i++, mask = mask << 1) {
67 tst_resm(TINFO, "Set test process affinity.");
68 printf("mask: %x\n", mask);
69
70 sched_setaffinity(pid, sizeof(unsigned long), &mask);
71
72 for (j = 0; j < 10; j++) {
73 for (k = 0; k < 10; k++) {
74 if (fork() == 0) {
75 system("ps > /dev/null");
76 exit(0);
77 }
78 }
79
80 sleep(1);
81
82 if (get_current_cpu(pid) != i)
83 break;
84 }
85
86 if (j < 10) {
87 tst_resm(TINFO, "...Error");
88 result = 0;
89 } else
90 tst_resm(TINFO, "...OK");
91
92 }
93
94 for (i = 0, mask = 0x3; i < cpu_count - 1; i++, mask = mask << 1) {
95 tst_resm(TINFO, "Set test process affinity.");
96 printf("mask: %x\n", mask);
97
98 sched_setaffinity(pid, sizeof(unsigned long), &mask);
99
100 for (j = 0; j < 10; j++) {
101 for (k = 0; k < 10; k++) {
102 if (fork() == 0) {
103 system("ps > /dev/null");
104 exit(0);
105 }
106 }
107
108 sleep(1);
109
110 cpuid = get_current_cpu(pid);
111 if (cpuid != i && cpuid != i + 1)
112 break;
113 }
114
115 if (j < 10) {
116 tst_resm(TINFO, "...Error");
117 result = 0;
118 } else
119 tst_resm(TINFO, "...OK");
120
121 }
122
123 if (result)
124 return 1;
125 else
126 return 0;
127 }
128
get_porc_affinity(pid_t pid)129 unsigned long get_porc_affinity(pid_t pid)
130 {
131 FILE *pfile;
132
133 sprintf(buf, "%s%d/%s%c", PROCFS_PATH, pid, AFFINITY_NAME, 0);
134
135 if ((pfile = fopen(buf, "r")) == NULL)
136 return 0;
137
138 if (fgets(buf, 255, pfile) == NULL) {
139 fclose(pfile);
140 return 0;
141 }
142
143 fclose(pfile);
144
145 return atol(buf);
146 }
147
HT_GetAffinity(void)148 int HT_GetAffinity(void)
149 {
150 unsigned int mask[2], mask1[2];
151 pid_t pid;
152
153 mask[0] = 0x1;
154 pid = getpid();
155
156 tst_resm(TINFO, "Get affinity through system call");
157
158 sched_setaffinity(pid, sizeof(mask), mask);
159
160 sleep(1);
161
162 sched_getaffinity(pid, sizeof(mask), mask1);
163
164 if (mask[0] == 0x1 && mask[0] == mask1[0]) {
165 mask[0] = 0x2;
166 sched_setaffinity(pid, sizeof(mask), mask);
167
168 sleep(1);
169
170 sched_getaffinity(pid, sizeof(mask), mask1);
171
172 if (mask[0] == 0x2 && mask[0] == mask1[0])
173 return 1;
174 else
175 return 0;
176 } else
177 return 0;
178 }
179
HT_InheritAffinity(void)180 int HT_InheritAffinity(void)
181 {
182 unsigned int mask[2];
183 pid_t pid;
184 int status;
185 mask[0] = 0x2;
186 pid = getpid();
187
188 sched_setaffinity(pid, sizeof(mask), mask);
189
190 sleep(1);
191 pid = fork();
192 if (pid == 0) {
193 sleep(1);
194 sched_getaffinity(pid, sizeof(mask), mask);
195 if (mask[0] == 0x2)
196 exit(0);
197
198 else
199 exit(1);
200 } else if (pid < 0) {
201 tst_resm(TINFO, "Inherit affinity:fork failed!");
202 return 0;
203 }
204 waitpid(pid, &status, 0);
205
206 if (WEXITSTATUS(status) == 0) {
207 tst_resm(TINFO, "Inherited affinity from parent process");
208 return 1;
209 } else
210 return 0;
211 }
212
213 // return 0 means Pass, return 1 means Fail
main(void)214 int main(void)
215 {
216
217 #if (!defined __i386__ && !defined __x86_64__)
218 tst_brkm(TCONF, NULL,
219 "This test suite can only execute on x86 architecture.");
220 #else
221 if (!check_ht_capability()) {
222
223 if (HT_GetAffinity())
224 tst_resm(TPASS, "System call getaffinity() is OK.");
225 else
226 tst_resm(TFAIL, "System call getaffinity() is error.");
227
228 printf("\n");
229
230 if (HT_InheritAffinity())
231 tst_resm(TPASS, "Inheritance of affinity is OK.");
232 else
233 tst_resm(TFAIL, "Inheritance of affinity is error.");
234
235 printf("\n");
236
237 if (HT_SetAffinity())
238 tst_resm(TPASS, "System call setaffinity() is OK.");
239 else
240 tst_resm(TFAIL, "System call setaffinity() is error.");
241 } else {
242 tst_brkm(TCONF, NULL, "HT is not enabled or not supported.");
243 }
244 #endif
245
246 tst_exit();
247 }
248