1 /******************************************************************************/
2 /* */
3 /* Copyright (c) 2009 FUJITSU LIMITED */
4 /* */
5 /* This program is free software; you can redistribute it and/or modify */
6 /* it under the terms of the GNU General Public License as published by */
7 /* the Free Software Foundation; either version 2 of the License, or */
8 /* (at your option) any later version. */
9 /* */
10 /* This program is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
13 /* the GNU General Public License for more details. */
14 /* */
15 /* You should have received a copy of the GNU General Public License */
16 /* along with this program; if not, write to the Free Software */
17 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18 /* */
19 /* Author: Miao Xie <[email protected]> */
20 /* */
21 /******************************************************************************/
22
23 #define _GNU_SOURCE
24
25 #include "config.h"
26 #include <sched.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <signal.h>
31 #include <err.h>
32 #include <limits.h>
33 #include <getopt.h>
34 #include <string.h>
35 #include <fcntl.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/mman.h>
39 #include <sys/shm.h>
40 #include <sys/syscall.h>
41 #include <inttypes.h>
42
43 #include "test.h"
44
45 char *TCID = "cpuset_syscall_test";
46 int TST_TOTAL = 1;
47
48 #ifdef HAVE_NUMA_V2
49 #include <numaif.h>
50
51 #include "../cpuset_lib/cpuset.h"
52 #include "../cpuset_lib/bitmask.h"
53
54 static unsigned long mask;
55 static int test = -1;
56 static int flag_exit;
57 static int ret;
58
59 #define OPT_setaffinity (SCHAR_MAX + 1)
60 #define OPT_getaffinity (SCHAR_MAX + 2)
61 #define OPT_mbind (SCHAR_MAX + 3)
62 #define OPT_set_mempolicy (SCHAR_MAX + 4)
63 #define OPT_get_mempolicy (SCHAR_MAX + 5)
64
65 const struct option long_opts[] = {
66 {"setaffinity", 1, NULL, OPT_setaffinity},
67 {"getaffinity", 0, NULL, OPT_getaffinity},
68 {"mbind", 1, NULL, OPT_mbind},
69 {"set_mempolicy", 1, NULL, OPT_set_mempolicy},
70 {"get_mempolicy", 0, NULL, OPT_get_mempolicy},
71 {NULL, 0, NULL, 0},
72 };
73
process_options(int argc,char * argv[])74 void process_options(int argc, char *argv[])
75 {
76 int c;
77 char *end;
78
79 while (1) {
80 c = getopt_long(argc, argv, "", long_opts, NULL);
81 if (c == -1)
82 break;
83
84 switch (c) {
85 case OPT_setaffinity:
86 test = 0;
87 mask = strtoul(optarg, &end, 10);
88 if (*end != '\0')
89 errx(1, "wrong -s argument!");
90 break;
91 case OPT_getaffinity:
92 test = 1;
93 break;
94 case OPT_mbind:
95 test = 2;
96 mask = strtoul(optarg, &end, 10);
97 if (*end != '\0')
98 errx(1, "wrong -s argument!");
99 break;
100 case OPT_set_mempolicy:
101 test = 3;
102 mask = strtoul(optarg, &end, 10);
103 if (*end != '\0')
104 errx(1, "wrong -s argument!");
105 break;
106 case OPT_get_mempolicy:
107 test = 4;
108 break;
109 default:
110 errx(1, "unknown option!\n");
111 break;
112 }
113 }
114 }
115
sigint_handler(int signo)116 void sigint_handler(int __attribute__ ((unused)) signo)
117 {
118 flag_exit = 1;
119 }
120
test_setaffinity(void)121 void test_setaffinity(void)
122 {
123 cpu_set_t tmask;
124 unsigned int i;
125 CPU_ZERO(&tmask);
126 for (i = 0; i < 8 * sizeof(mask); i++) {
127 if ((1 << i) & mask)
128 CPU_SET(i, &tmask);
129 }
130 ret = sched_setaffinity(0, sizeof(tmask), &tmask);
131 }
132
test_getaffinity(void)133 void test_getaffinity(void)
134 {
135 cpu_set_t tmask;
136 unsigned int i;
137 CPU_ZERO(&tmask);
138 ret = sched_getaffinity(0, sizeof(tmask), &tmask);
139 for (i = 0; i < 8 * sizeof(mask); i++) {
140 if (CPU_ISSET(i, &tmask))
141 printf("%d,", i);
142 }
143 }
144
test_mbind(void)145 void test_mbind(void)
146 {
147 void *addr;
148 int len = 10 * 1024 * 1024;
149 addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
150 if (addr == MAP_FAILED) {
151 ret = 1;
152 return;
153 }
154 printf("%p\n", addr);
155 ret = mbind(addr, len, MPOL_BIND, &mask, 8 * sizeof(mask), 0);
156 }
157
test_set_mempolicy(void)158 void test_set_mempolicy(void)
159 {
160 ret = set_mempolicy(MPOL_BIND, &mask, 8 * sizeof(mask));
161 }
162
test_get_mempolicy(void)163 void test_get_mempolicy(void)
164 {
165 int nbits;
166 struct bitmask *nmask;
167 char str[256];
168
169 nbits = cpuset_mems_nbits();
170 if (nbits <= 0) {
171 warn("get the nbits of nodes failed");
172 ret = 1;
173 return;
174 }
175
176 nmask = bitmask_alloc(nbits);
177 if (nmask == NULL) {
178 warn("alloc bitmask failed");
179 ret = 1;
180 return;
181 }
182 ret = get_mempolicy(NULL, bitmask_mask(nmask), bitmask_nbits(nmask), 0,
183 MPOL_F_MEMS_ALLOWED);
184
185 bitmask_displaylist(str, 256, nmask);
186 puts(str);
187 }
188
sigusr_handler(int signo)189 void sigusr_handler(int __attribute__ ((unused)) signo)
190 {
191 switch (test) {
192 case 0:
193 test_setaffinity();
194 break;
195 case 1:
196 test_getaffinity();
197 break;
198 case 2:
199 test_mbind();
200 break;
201 case 3:
202 test_set_mempolicy();
203 break;
204 case 4:
205 test_get_mempolicy();
206 break;
207 default:;
208 }
209 test = -1;
210 }
211
main(int argc,char * argv[])212 int main(int argc, char *argv[])
213 {
214 struct sigaction sigint_action;
215 struct sigaction sigusr_action;
216
217 memset(&sigint_action, 0, sizeof(sigint_action));
218 sigint_action.sa_handler = &sigint_handler;
219 sigaction(SIGINT, &sigint_action, NULL);
220
221 memset(&sigusr_action, 0, sizeof(sigusr_action));
222 sigusr_action.sa_handler = &sigusr_handler;
223 sigaction(SIGUSR1, &sigusr_action, NULL);
224
225 process_options(argc, argv);
226
227 while (!flag_exit)
228 sleep(1);
229
230 return ret;
231 }
232 #else
main(void)233 int main(void)
234 {
235 tst_brkm(TCONF, NULL, NUMA_ERROR_MSG);
236 }
237 #endif
238