cpuset_syscall_test.c revision 4548c6cf9bcdd96d8303caa4130ab638b61f8a30
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 <miaox@cn.fujitsu.com>                                    */
20/*                                                                            */
21/******************************************************************************/
22
23#define _GNU_SOURCE
24
25#include <sched.h>
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <signal.h>
30#include <err.h>
31#include <limits.h>
32#include <getopt.h>
33#include <string.h>
34#include <fcntl.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <sys/mman.h>
38#include <sys/shm.h>
39#include <syscall.h>
40#include <inttypes.h>
41#include "config.h"
42#include "linux_syscall_numbers.h"
43#include "test.h"
44#include "usctest.h"
45
46char *TCID = "cpuset_syscall_test";
47
48#if HAVE_LINUX_MEMPOLICY_H
49#include <linux/mempolicy.h>
50
51#include "../cpuset_lib/cpuset.h"
52#include "../cpuset_lib/bitmask.h"
53
54int TST_TOTAL = 1;
55
56unsigned long mask;
57int test = -1;
58int flag_exit;
59int ret;
60
61#if HAVE_DECL_MPOL_F_MEMS_ALLOWED
62static int get_mempolicy(int *policy, unsigned long *nmask,
63			unsigned long maxnode, void *addr, int flags)
64{
65	return syscall(__NR_get_mempolicy, policy, nmask, maxnode, addr, flags);
66}
67#endif
68
69#if HAVE_DECL_MPOL_BIND
70static int mbind(void *start, unsigned long len, int policy, unsigned long *nodemask,
71		unsigned long maxnode, unsigned flags)
72{
73	return syscall(__NR_mbind, start, len, policy, nodemask, maxnode, flags);
74}
75
76static int set_mempolicy(int policy, unsigned long *nodemask, unsigned long maxnode)
77{
78	return syscall(__NR_set_mempolicy, policy, nodemask, maxnode);
79}
80#endif
81
82#define OPT_setaffinity		(SCHAR_MAX + 1)
83#define OPT_getaffinity		(SCHAR_MAX + 2)
84#define OPT_mbind		(SCHAR_MAX + 3)
85#define OPT_set_mempolicy	(SCHAR_MAX + 4)
86#define OPT_get_mempolicy	(SCHAR_MAX + 5)
87
88const struct option long_opts[] = {
89	{ "setaffinity",	1, NULL, OPT_setaffinity	},
90	{ "getaffinity",	0, NULL, OPT_getaffinity	},
91	{ "mbind",		1, NULL, OPT_mbind		},
92	{ "set_mempolicy",	1, NULL, OPT_set_mempolicy	},
93	{ "get_mempolicy",	0, NULL, OPT_get_mempolicy	},
94	{ NULL,			0, NULL, 0			},
95};
96
97void process_options(int argc, char *argv[])
98{
99	int c;
100	char *end;
101
102	while (1) {
103		c = getopt_long(argc, argv, "", long_opts, NULL);
104		if (c == -1)
105			break;
106
107		switch (c) {
108		case OPT_setaffinity:
109			test = 0;
110			mask = strtoul(optarg, &end, 10);
111			if (*end != '\0')
112				errx(1, "wrong -s argument!");
113			break;
114		case OPT_getaffinity:
115			test = 1;
116			break;
117		case OPT_mbind:
118			test = 2;
119			mask = strtoul(optarg, &end, 10);
120			if (*end != '\0')
121				errx(1, "wrong -s argument!");
122			break;
123		case OPT_set_mempolicy:
124			test = 3;
125			mask = strtoul(optarg, &end, 10);
126			if (*end != '\0')
127				errx(1, "wrong -s argument!");
128			break;
129		case OPT_get_mempolicy:
130			test = 4;
131			break;
132		default:
133			errx(1, "unknown option!\n");
134			break;
135		}
136	}
137}
138
139void sigint_handler(int __attribute__((unused)) signo)
140{
141	flag_exit = 1;
142}
143
144void test_setaffinity(void)
145{
146	cpu_set_t tmask;
147	int i;
148	CPU_ZERO(&tmask);
149	for (i = 0; i < 8 * sizeof(mask); i++) {
150		if ((1 << i) & mask)
151			CPU_SET(i, &tmask);
152	}
153	ret = sched_setaffinity(0, sizeof(tmask), &tmask);
154}
155
156void test_getaffinity(void)
157{
158	cpu_set_t tmask;
159	int i;
160	CPU_ZERO(&tmask);
161	ret = sched_getaffinity(0, sizeof(tmask), &tmask);
162	for (i = 0; i < 8 * sizeof(mask); i++) {
163		if (CPU_ISSET(i, &tmask))
164			printf("%d,", i);
165	}
166}
167
168void test_mbind(void)
169{
170	void *addr;
171	int len = 10 * 1024 * 1024;
172	addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
173	if (addr == MAP_FAILED) {
174		ret = 1;
175		return;
176	}
177	printf("%p\n", addr);
178#if HAVE_DECL_MPOL_BIND
179	ret = mbind(addr, len, MPOL_BIND, &mask, 8 * sizeof(mask), 0);
180#else
181	ret = 1;
182#endif
183}
184
185void test_set_mempolicy(void)
186{
187#if HAVE_DECL_MPOL_BIND
188	ret = set_mempolicy(MPOL_BIND, &mask, 8 * sizeof(mask));
189#else
190	ret = -1;
191#endif
192}
193
194void test_get_mempolicy(void)
195{
196	int nbits;
197	struct bitmask *nmask;
198	char str[256];
199
200	nbits = cpuset_mems_nbits();
201	if (nbits <= 0) {
202		warn("get the nbits of nodes failed");
203		ret = 1;
204		return;
205	}
206
207	nmask = bitmask_alloc(nbits);
208	if (nmask == NULL) {
209		warn("alloc bitmask failed");
210		ret = 1;
211		return;
212	}
213#if HAVE_DECL_MPOL_F_MEMS_ALLOWED
214	ret = get_mempolicy(NULL, bitmask_mask(nmask), bitmask_nbits(nmask), 0,
215				MPOL_F_MEMS_ALLOWED);
216#else
217	ret = -1;
218#endif
219
220	bitmask_displaylist(str, 256, nmask);
221	puts(str);
222}
223
224void sigusr_handler(int __attribute__((unused)) signo)
225{
226	switch (test) {
227	case 0: test_setaffinity(); break;
228	case 1: test_getaffinity(); break;
229	case 2: test_mbind(); break;
230	case 3: test_set_mempolicy(); break;
231	case 4: test_get_mempolicy(); break;
232	default:;
233	}
234	test = -1;
235}
236
237int main(int argc, char *argv[])
238{
239	struct sigaction sigint_action;
240	struct sigaction sigusr_action;
241
242	memset(&sigint_action, 0, sizeof(sigint_action));
243	sigint_action.sa_handler = &sigint_handler;
244	sigaction(SIGINT, &sigint_action, NULL);
245
246	memset(&sigusr_action, 0, sizeof(sigusr_action));
247	sigusr_action.sa_handler = &sigusr_handler;
248	sigaction(SIGUSR1, &sigusr_action, NULL);
249
250	process_options(argc, argv);
251
252	while (!flag_exit)
253		sleep(1);
254
255	return ret;
256}
257#else
258int main (void) {
259	printf("System doesn't have required mempolicy support\n");
260	tst_exit();
261}
262#endif
263