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__)
child_fn(void * i_ptr)25 static int child_fn(void* i_ptr) {
26   *reinterpret_cast<int*>(i_ptr) = 42;
27   return 123;
28 }
29 
TEST(sched,clone)30 TEST(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.
TEST(sched,clone)48 TEST(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 
TEST(sched,clone_errno)54 TEST(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 
TEST(sched,cpu_set)62 TEST(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 
TEST(sched,cpu_count)77 TEST(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 
TEST(sched,cpu_zero)89 TEST(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 
TEST(sched,cpu_clr)99 TEST(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 
TEST(sched,cpu_equal)118 TEST(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 
TEST(sched,cpu_op)130 TEST(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 
TEST(sched,cpu_alloc_small)159 TEST(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 
TEST(sched,cpu_alloc_big)171 TEST(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 
TEST(sched,cpu_s_macros)183 TEST(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 
TEST(sched,cpu_op_s_macros)205 TEST(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 
TEST(sched,cpu_equal_s)244 TEST(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