1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18
19#include <errno.h>
20#include <sched.h>
21#include <sys/types.h>
22#include <sys/wait.h>
23
24#if defined(__BIONIC__)
25static int child_fn(void* i_ptr) {
26  *reinterpret_cast<int*>(i_ptr) = 42;
27  return 123;
28}
29
30TEST(sched, clone) {
31  void* child_stack[1024];
32
33  int i = 0;
34  pid_t tid = clone(child_fn, &child_stack[1024], CLONE_VM, &i);
35
36  int status;
37  ASSERT_EQ(tid, TEMP_FAILURE_RETRY(waitpid(tid, &status, __WCLONE)));
38
39  ASSERT_EQ(42, i);
40
41  ASSERT_TRUE(WIFEXITED(status));
42  ASSERT_EQ(123, WEXITSTATUS(status));
43}
44#else
45// For glibc, any call to clone with CLONE_VM set will cause later pthread
46// calls in the same process to misbehave.
47// See https://sourceware.org/bugzilla/show_bug.cgi?id=10311 for more details.
48TEST(sched, clone) {
49  // In order to enumerate all possible tests for CTS, create an empty test.
50  GTEST_LOG_(INFO) << "This test does nothing.\n";
51}
52#endif
53
54TEST(sched, clone_errno) {
55  // Check that our hand-written clone assembler sets errno correctly on failure.
56  uintptr_t fake_child_stack[16];
57  errno = 0;
58  ASSERT_EQ(-1, clone(NULL, &fake_child_stack[16], CLONE_THREAD, NULL));
59  ASSERT_EQ(EINVAL, errno);
60}
61
62TEST(sched, cpu_set) {
63  cpu_set_t set;
64
65  CPU_ZERO(&set);
66  CPU_SET(0, &set);
67  CPU_SET(17, &set);
68  for (int i = 0; i < CPU_SETSIZE; i++) {
69    ASSERT_EQ(i == 0 || i == 17, CPU_ISSET(i, &set));
70  }
71
72  // We should fail silently if we try to set/test outside the range.
73  CPU_SET(CPU_SETSIZE, &set);
74  ASSERT_FALSE(CPU_ISSET(CPU_SETSIZE, &set));
75}
76
77TEST(sched, cpu_count) {
78  cpu_set_t set;
79
80  CPU_ZERO(&set);
81  ASSERT_EQ(0, CPU_COUNT(&set));
82  CPU_SET(2, &set);
83  CPU_SET(10, &set);
84  ASSERT_EQ(2, CPU_COUNT(&set));
85  CPU_CLR(10, &set);
86  ASSERT_EQ(1, CPU_COUNT(&set));
87}
88
89TEST(sched, cpu_zero) {
90  cpu_set_t set;
91
92  CPU_ZERO(&set);
93  ASSERT_EQ(0, CPU_COUNT(&set));
94  for (int i = 0; i < CPU_SETSIZE; i++) {
95    ASSERT_FALSE(CPU_ISSET(i, &set));
96  }
97}
98
99TEST(sched, cpu_clr) {
100  cpu_set_t set;
101
102  CPU_ZERO(&set);
103  CPU_SET(0, &set);
104  CPU_SET(1, &set);
105  for (int i = 0; i < CPU_SETSIZE; i++) {
106    ASSERT_EQ(i == 0 || i == 1, CPU_ISSET(i, &set));
107  }
108  CPU_CLR(1, &set);
109  for (int i = 0; i < CPU_SETSIZE; i++) {
110    ASSERT_EQ(i == 0, CPU_ISSET(i, &set));
111  }
112
113  // We should fail silently if we try to clear/test outside the range.
114  CPU_CLR(CPU_SETSIZE, &set);
115  ASSERT_FALSE(CPU_ISSET(CPU_SETSIZE, &set));
116}
117
118TEST(sched, cpu_equal) {
119  cpu_set_t set1;
120  cpu_set_t set2;
121
122  CPU_ZERO(&set1);
123  CPU_ZERO(&set2);
124  CPU_SET(1, &set1);
125  ASSERT_FALSE(CPU_EQUAL(&set1, &set2));
126  CPU_SET(1, &set2);
127  ASSERT_TRUE(CPU_EQUAL(&set1, &set2));
128}
129
130TEST(sched, cpu_op) {
131  cpu_set_t set1;
132  cpu_set_t set2;
133  cpu_set_t set3;
134
135  CPU_ZERO(&set1);
136  CPU_ZERO(&set2);
137  CPU_ZERO(&set3);
138  CPU_SET(0, &set1);
139  CPU_SET(0, &set2);
140  CPU_SET(1, &set2);
141
142  CPU_AND(&set3, &set1, &set2);
143  for (int i = 0; i < CPU_SETSIZE; i++) {
144    ASSERT_EQ(i == 0, CPU_ISSET(i, &set3));
145  }
146
147  CPU_XOR(&set3, &set1, &set2);
148  for (int i = 0; i < CPU_SETSIZE; i++) {
149    ASSERT_EQ(i == 1, CPU_ISSET(i, &set3));
150  }
151
152  CPU_OR(&set3, &set1, &set2);
153  for (int i = 0; i < CPU_SETSIZE; i++) {
154    ASSERT_EQ(i == 0 || i == 1, CPU_ISSET(i, &set3));
155  }
156}
157
158
159TEST(sched, cpu_alloc_small) {
160  cpu_set_t* set = CPU_ALLOC(17);
161  size_t size = CPU_ALLOC_SIZE(17);
162
163  CPU_ZERO_S(size, set);
164  ASSERT_EQ(0, CPU_COUNT_S(size, set));
165  CPU_SET_S(16, size, set);
166  ASSERT_TRUE(CPU_ISSET_S(16, size, set));
167
168  CPU_FREE(set);
169}
170
171TEST(sched, cpu_alloc_big) {
172  cpu_set_t* set = CPU_ALLOC(10 * CPU_SETSIZE);
173  size_t size = CPU_ALLOC_SIZE(10 * CPU_SETSIZE);
174
175  CPU_ZERO_S(size, set);
176  ASSERT_EQ(0, CPU_COUNT_S(size, set));
177  CPU_SET_S(CPU_SETSIZE, size, set);
178  ASSERT_TRUE(CPU_ISSET_S(CPU_SETSIZE, size, set));
179
180  CPU_FREE(set);
181}
182
183TEST(sched, cpu_s_macros) {
184  int set_size = 64;
185  size_t size = CPU_ALLOC_SIZE(set_size);
186  cpu_set_t* set = CPU_ALLOC(set_size);
187
188  CPU_ZERO_S(size, set);
189  for (int i = 0; i < set_size; i++) {
190    ASSERT_FALSE(CPU_ISSET_S(i, size, set));
191    CPU_SET_S(i, size, set);
192    ASSERT_TRUE(CPU_ISSET_S(i, size, set));
193    ASSERT_EQ(i + 1, CPU_COUNT_S(size, set));
194  }
195
196  for (int i = 0; i < set_size; i++) {
197    CPU_CLR_S(i, size, set);
198    ASSERT_FALSE(CPU_ISSET_S(i, size, set));
199    ASSERT_EQ(set_size - i - 1, CPU_COUNT_S(size, set));
200  }
201
202  CPU_FREE(set);
203}
204
205TEST(sched, cpu_op_s_macros) {
206  int set_size1 = 64;
207  int set_size2 = set_size1 * 2;
208  int set_size3 = set_size1 * 3;
209  size_t size1 = CPU_ALLOC_SIZE(set_size1);
210  size_t size2 = CPU_ALLOC_SIZE(set_size2);
211  size_t size3 = CPU_ALLOC_SIZE(set_size3);
212
213  cpu_set_t* set1 = CPU_ALLOC(set_size1);
214  cpu_set_t* set2 = CPU_ALLOC(set_size2);
215  cpu_set_t* set3 = CPU_ALLOC(set_size3);
216  CPU_ZERO_S(size1, set1);
217  CPU_ZERO_S(size2, set2);
218  CPU_ZERO_S(size3, set3);
219
220  CPU_SET_S(0, size1, set1);
221  CPU_SET_S(0, size2, set2);
222  CPU_SET_S(1, size3, set2);
223
224  CPU_AND_S(size1, set3, set1, set2);
225  for (int i = 0; i < set_size3; i++) {
226    ASSERT_EQ(i == 0, CPU_ISSET_S(i, size3, set3));
227  }
228
229  CPU_OR_S(size1, set3, set1, set2);
230  for (int i = 0; i < set_size3; i++) {
231    ASSERT_EQ(i == 0 || i == 1, CPU_ISSET_S(i, size3, set3));
232  }
233
234  CPU_XOR_S(size1, set3, set1, set2);
235  for (int i = 0; i < set_size3; i++) {
236    ASSERT_EQ(i == 1, CPU_ISSET_S(i, size3, set3));
237  }
238
239  CPU_FREE(set1);
240  CPU_FREE(set2);
241  CPU_FREE(set3);
242}
243
244TEST(sched, cpu_equal_s) {
245  int set_size1 = 64;
246  int set_size2 = set_size1 * 2;
247  size_t size1 = CPU_ALLOC_SIZE(set_size1);
248  size_t size2 = CPU_ALLOC_SIZE(set_size2);
249
250  cpu_set_t* set1 = CPU_ALLOC(set_size1);
251  cpu_set_t* set2 = CPU_ALLOC(set_size2);
252
253  CPU_ZERO_S(size1, set1);
254  CPU_ZERO_S(size2, set2);
255
256  CPU_SET_S(0, size1, set1);
257  ASSERT_TRUE(CPU_EQUAL_S(size1, set1, set1));
258  ASSERT_FALSE(CPU_EQUAL_S(size1, set1, set2));
259  CPU_SET_S(0, size2, set2);
260  ASSERT_TRUE(CPU_EQUAL_S(size1, set1, set2));
261
262  CPU_FREE(set1);
263  CPU_FREE(set2);
264}
265