1 /******************************************************************************/
2 /* Copyright (c) Crackerjack Project., 2007 */
3 /* */
4 /* This program is free software; you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation; either version 2 of the License, or */
7 /* (at your option) any later version. */
8 /* */
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
12 /* the GNU General Public License for more details. */
13 /* */
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program; if not, write to the Free Software */
16 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
17 /* */
18 /******************************************************************************/
19 /******************************************************************************/
20 /* */
21 /* File: sched_getaffinity01.c */
22 /* */
23 /* Description: This tests the sched_getaffinity() syscall */
24 /* */
25 /* Usage: <for command-line> */
26 /* sched_getaffinity01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
27 /* where, -c n : Run n copies concurrently. */
28 /* -e : Turn on errno logging. */
29 /* -i n : Execute test n times. */
30 /* -I x : Execute test for x seconds. */
31 /* -P x : Pause for x seconds between iterations. */
32 /* -t : Turn on syscall timing. */
33 /* */
34 /* Total Tests: 1 */
35 /* */
36 /* Test Name: sched_getaffinity01 */
37 /* History: Porting from Crackerjack to LTP is done by */
38 /* Manas Kumar Nayak maknayak@in.ibm.com> */
39 /******************************************************************************/
40 #define _GNU_SOURCE
41 #define __USE_GNU
42 #include <sys/types.h>
43 #include <errno.h>
44 #include <limits.h>
45 #include <sched.h>
46 #include <signal.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <unistd.h>
51
52 #include "test.h"
53 #include "linux_syscall_numbers.h"
54
55 char *TCID = "sched_getaffinity01";
56 int TST_TOTAL = 1;
57
58 static long num;
59 static void do_test(void);
60 static void setup(void);
61 static void cleanup(void);
62
63 #define QUICK_TEST(t) \
64 do { \
65 TEST(t); \
66 tst_resm((TEST_RETURN == -1 ? TPASS : TFAIL) | TTERRNO, #t); \
67 } while (0)
68
69 #if !(__GLIBC_PREREQ(2, 7))
70 #define CPU_FREE(ptr) free(ptr)
71 #endif
72
main(int ac,char ** av)73 int main(int ac, char **av)
74 {
75 int lc;
76
77 tst_parse_opts(ac, av, NULL, NULL);
78 setup();
79
80 for (lc = 0; TEST_LOOPING(lc); ++lc) {
81 tst_count = 0;
82
83 do_test();
84 }
85
86 cleanup();
87 tst_exit();
88 }
89
do_test(void)90 static void do_test(void)
91 {
92 int i;
93 cpu_set_t *mask;
94 int nrcpus = 1024;
95 pid_t unused_pid;
96 unsigned len;
97
98 #if __GLIBC_PREREQ(2, 7)
99 realloc:
100 mask = CPU_ALLOC(nrcpus);
101 #else
102 mask = malloc(sizeof(cpu_set_t));
103 #endif
104 if (mask == NULL)
105 tst_brkm(TFAIL | TTERRNO, cleanup, "fail to get enough memory");
106 #if __GLIBC_PREREQ(2, 7)
107 len = CPU_ALLOC_SIZE(nrcpus);
108 CPU_ZERO_S(len, mask);
109 #else
110 len = sizeof(cpu_set_t);
111 CPU_ZERO(mask);
112 #endif
113 /* positive test */
114 TEST(sched_getaffinity(0, len, mask));
115 if (TEST_RETURN == -1) {
116 CPU_FREE(mask);
117 #if __GLIBC_PREREQ(2, 7)
118 if (errno == EINVAL && nrcpus < (1024 << 8)) {
119 nrcpus = nrcpus << 2;
120 goto realloc;
121 }
122 #else
123 if (errno == EINVAL)
124 tst_resm(TFAIL, "NR_CPUS > 1024, we'd better use a "
125 "newer glibc(>= 2.7)");
126 else
127 #endif
128 tst_resm(TFAIL | TTERRNO, "fail to get cpu affinity");
129 cleanup();
130 } else {
131 tst_resm(TINFO, "cpusetsize is %d", len);
132 tst_resm(TINFO, "mask.__bits[0] = %lu ", mask->__bits[0]);
133 for (i = 0; i < num; i++) {
134 #if __GLIBC_PREREQ(2, 7)
135 TEST(CPU_ISSET_S(i, len, mask));
136 #else
137 TEST(CPU_ISSET(i, mask));
138 #endif
139 if (TEST_RETURN != -1)
140 tst_resm(TPASS, "sched_getaffinity() succeed, "
141 "this process %d is running "
142 "processor: %d", getpid(), i);
143 }
144 }
145
146 #if __GLIBC_PREREQ(2, 7)
147 CPU_ZERO_S(len, mask);
148 #else
149 CPU_ZERO(mask);
150 #endif
151 /* negative tests */
152 QUICK_TEST(sched_getaffinity(0, len, (cpu_set_t *) - 1));
153 QUICK_TEST(sched_getaffinity(0, 0, mask));
154
155 unused_pid = tst_get_unused_pid(cleanup);
156 QUICK_TEST(sched_getaffinity(unused_pid, len, mask));
157 CPU_FREE(mask);
158 }
159
setup(void)160 static void setup(void)
161 {
162 TEST_PAUSE;
163 tst_tmpdir();
164
165 num = sysconf(_SC_NPROCESSORS_CONF);
166 if (num == -1)
167 tst_brkm(TBROK | TERRNO, NULL, "sysconf");
168 tst_resm(TINFO, "system has %ld processor(s).", num);
169 }
170
cleanup(void)171 static void cleanup(void)
172 {
173 tst_rmdir();
174 }
175