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 static int child_fn(void* i_ptr) { 25 *reinterpret_cast<int*>(i_ptr) = 42; 26 return 123; 27 } 28 29 #if defined(__BIONIC__) 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. 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 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 // If CLONE_THREAD is set, CLONE_SIGHAND must be set too. 59 ASSERT_EQ(-1, clone(child_fn, &fake_child_stack[16], CLONE_THREAD, NULL)); 60 ASSERT_EQ(EINVAL, errno); 61 } 62 63 TEST(sched, clone_null_child_stack) { 64 int i = 0; 65 errno = 0; 66 ASSERT_EQ(-1, clone(child_fn, nullptr, CLONE_VM, &i)); 67 ASSERT_EQ(EINVAL, errno); 68 } 69 70 TEST(sched, cpu_set) { 71 cpu_set_t set; 72 73 CPU_ZERO(&set); 74 CPU_SET(0, &set); 75 CPU_SET(17, &set); 76 for (int i = 0; i < CPU_SETSIZE; i++) { 77 ASSERT_EQ(i == 0 || i == 17, CPU_ISSET(i, &set)); 78 } 79 80 // We should fail silently if we try to set/test outside the range. 81 CPU_SET(CPU_SETSIZE, &set); 82 ASSERT_FALSE(CPU_ISSET(CPU_SETSIZE, &set)); 83 } 84 85 TEST(sched, cpu_count) { 86 cpu_set_t set; 87 88 CPU_ZERO(&set); 89 ASSERT_EQ(0, CPU_COUNT(&set)); 90 CPU_SET(2, &set); 91 CPU_SET(10, &set); 92 ASSERT_EQ(2, CPU_COUNT(&set)); 93 CPU_CLR(10, &set); 94 ASSERT_EQ(1, CPU_COUNT(&set)); 95 } 96 97 TEST(sched, cpu_zero) { 98 cpu_set_t set; 99 100 CPU_ZERO(&set); 101 ASSERT_EQ(0, CPU_COUNT(&set)); 102 for (int i = 0; i < CPU_SETSIZE; i++) { 103 ASSERT_FALSE(CPU_ISSET(i, &set)); 104 } 105 } 106 107 TEST(sched, cpu_clr) { 108 cpu_set_t set; 109 110 CPU_ZERO(&set); 111 CPU_SET(0, &set); 112 CPU_SET(1, &set); 113 for (int i = 0; i < CPU_SETSIZE; i++) { 114 ASSERT_EQ(i == 0 || i == 1, CPU_ISSET(i, &set)); 115 } 116 CPU_CLR(1, &set); 117 for (int i = 0; i < CPU_SETSIZE; i++) { 118 ASSERT_EQ(i == 0, CPU_ISSET(i, &set)); 119 } 120 121 // We should fail silently if we try to clear/test outside the range. 122 CPU_CLR(CPU_SETSIZE, &set); 123 ASSERT_FALSE(CPU_ISSET(CPU_SETSIZE, &set)); 124 } 125 126 TEST(sched, cpu_equal) { 127 cpu_set_t set1; 128 cpu_set_t set2; 129 130 CPU_ZERO(&set1); 131 CPU_ZERO(&set2); 132 CPU_SET(1, &set1); 133 ASSERT_FALSE(CPU_EQUAL(&set1, &set2)); 134 CPU_SET(1, &set2); 135 ASSERT_TRUE(CPU_EQUAL(&set1, &set2)); 136 } 137 138 TEST(sched, cpu_op) { 139 cpu_set_t set1; 140 cpu_set_t set2; 141 cpu_set_t set3; 142 143 CPU_ZERO(&set1); 144 CPU_ZERO(&set2); 145 CPU_ZERO(&set3); 146 CPU_SET(0, &set1); 147 CPU_SET(0, &set2); 148 CPU_SET(1, &set2); 149 150 CPU_AND(&set3, &set1, &set2); 151 for (int i = 0; i < CPU_SETSIZE; i++) { 152 ASSERT_EQ(i == 0, CPU_ISSET(i, &set3)); 153 } 154 155 CPU_XOR(&set3, &set1, &set2); 156 for (int i = 0; i < CPU_SETSIZE; i++) { 157 ASSERT_EQ(i == 1, CPU_ISSET(i, &set3)); 158 } 159 160 CPU_OR(&set3, &set1, &set2); 161 for (int i = 0; i < CPU_SETSIZE; i++) { 162 ASSERT_EQ(i == 0 || i == 1, CPU_ISSET(i, &set3)); 163 } 164 } 165 166 167 TEST(sched, cpu_alloc_small) { 168 cpu_set_t* set = CPU_ALLOC(17); 169 size_t size = CPU_ALLOC_SIZE(17); 170 171 CPU_ZERO_S(size, set); 172 ASSERT_EQ(0, CPU_COUNT_S(size, set)); 173 CPU_SET_S(16, size, set); 174 ASSERT_TRUE(CPU_ISSET_S(16, size, set)); 175 176 CPU_FREE(set); 177 } 178 179 TEST(sched, cpu_alloc_big) { 180 cpu_set_t* set = CPU_ALLOC(10 * CPU_SETSIZE); 181 size_t size = CPU_ALLOC_SIZE(10 * CPU_SETSIZE); 182 183 CPU_ZERO_S(size, set); 184 ASSERT_EQ(0, CPU_COUNT_S(size, set)); 185 CPU_SET_S(CPU_SETSIZE, size, set); 186 ASSERT_TRUE(CPU_ISSET_S(CPU_SETSIZE, size, set)); 187 188 CPU_FREE(set); 189 } 190 191 TEST(sched, cpu_s_macros) { 192 int set_size = 64; 193 size_t size = CPU_ALLOC_SIZE(set_size); 194 cpu_set_t* set = CPU_ALLOC(set_size); 195 196 CPU_ZERO_S(size, set); 197 for (int i = 0; i < set_size; i++) { 198 ASSERT_FALSE(CPU_ISSET_S(i, size, set)); 199 CPU_SET_S(i, size, set); 200 ASSERT_TRUE(CPU_ISSET_S(i, size, set)); 201 ASSERT_EQ(i + 1, CPU_COUNT_S(size, set)); 202 } 203 204 for (int i = 0; i < set_size; i++) { 205 CPU_CLR_S(i, size, set); 206 ASSERT_FALSE(CPU_ISSET_S(i, size, set)); 207 ASSERT_EQ(set_size - i - 1, CPU_COUNT_S(size, set)); 208 } 209 210 CPU_FREE(set); 211 } 212 213 TEST(sched, cpu_op_s_macros) { 214 int set_size1 = 64; 215 int set_size2 = set_size1 * 2; 216 int set_size3 = set_size1 * 3; 217 size_t size1 = CPU_ALLOC_SIZE(set_size1); 218 size_t size2 = CPU_ALLOC_SIZE(set_size2); 219 size_t size3 = CPU_ALLOC_SIZE(set_size3); 220 221 cpu_set_t* set1 = CPU_ALLOC(set_size1); 222 cpu_set_t* set2 = CPU_ALLOC(set_size2); 223 cpu_set_t* set3 = CPU_ALLOC(set_size3); 224 CPU_ZERO_S(size1, set1); 225 CPU_ZERO_S(size2, set2); 226 CPU_ZERO_S(size3, set3); 227 228 CPU_SET_S(0, size1, set1); 229 CPU_SET_S(0, size2, set2); 230 CPU_SET_S(1, size3, set2); 231 232 CPU_AND_S(size1, set3, set1, set2); 233 for (int i = 0; i < set_size3; i++) { 234 ASSERT_EQ(i == 0, CPU_ISSET_S(i, size3, set3)); 235 } 236 237 CPU_OR_S(size1, set3, set1, set2); 238 for (int i = 0; i < set_size3; i++) { 239 ASSERT_EQ(i == 0 || i == 1, CPU_ISSET_S(i, size3, set3)); 240 } 241 242 CPU_XOR_S(size1, set3, set1, set2); 243 for (int i = 0; i < set_size3; i++) { 244 ASSERT_EQ(i == 1, CPU_ISSET_S(i, size3, set3)); 245 } 246 247 CPU_FREE(set1); 248 CPU_FREE(set2); 249 CPU_FREE(set3); 250 } 251 252 TEST(sched, cpu_equal_s) { 253 int set_size1 = 64; 254 int set_size2 = set_size1 * 2; 255 size_t size1 = CPU_ALLOC_SIZE(set_size1); 256 size_t size2 = CPU_ALLOC_SIZE(set_size2); 257 258 cpu_set_t* set1 = CPU_ALLOC(set_size1); 259 cpu_set_t* set2 = CPU_ALLOC(set_size2); 260 261 CPU_ZERO_S(size1, set1); 262 CPU_ZERO_S(size2, set2); 263 264 CPU_SET_S(0, size1, set1); 265 ASSERT_TRUE(CPU_EQUAL_S(size1, set1, set1)); 266 ASSERT_FALSE(CPU_EQUAL_S(size1, set1, set2)); 267 CPU_SET_S(0, size2, set2); 268 ASSERT_TRUE(CPU_EQUAL_S(size1, set1, set2)); 269 270 CPU_FREE(set1); 271 CPU_FREE(set2); 272 } 273 274 TEST(sched, sched_get_priority_min_sched_get_priority_max) { 275 EXPECT_LE(sched_get_priority_min(SCHED_BATCH), sched_get_priority_max(SCHED_BATCH)); 276 EXPECT_LE(sched_get_priority_min(SCHED_FIFO), sched_get_priority_max(SCHED_FIFO)); 277 EXPECT_LE(sched_get_priority_min(SCHED_IDLE), sched_get_priority_max(SCHED_IDLE)); 278 EXPECT_LE(sched_get_priority_min(SCHED_OTHER), sched_get_priority_max(SCHED_OTHER)); 279 EXPECT_LE(sched_get_priority_min(SCHED_RR), sched_get_priority_max(SCHED_RR)); 280 } 281 282 TEST(sched, sched_getscheduler_sched_setscheduler) { 283 // POSIX: "If pid is zero, the scheduling policy shall be returned for the 284 // calling process". 285 ASSERT_EQ(sched_getscheduler(getpid()), sched_getscheduler(0)); 286 287 const int original_policy = sched_getscheduler(getpid()); 288 sched_param p = {}; 289 p.sched_priority = sched_get_priority_min(original_policy); 290 errno = 0; 291 ASSERT_EQ(-1, sched_setscheduler(getpid(), INT_MAX, &p)); 292 ASSERT_EQ(EINVAL, errno); 293 294 ASSERT_EQ(0, sched_getparam(getpid(), &p)); 295 ASSERT_EQ(original_policy, sched_setscheduler(getpid(), SCHED_BATCH, &p)); 296 // POSIX says this should return the previous policy (here SCHED_BATCH), 297 // but the Linux system call doesn't, and the glibc wrapper doesn't correct 298 // this (the "returns 0" behavior is even documented on the man page in 299 // the BUGS section). This was our historical behavior too, so in the 300 // absence of reasons to break compatibility with ourselves and glibc, we 301 // don't behave as POSIX specifies. http://b/26203902. 302 ASSERT_EQ(0, sched_setscheduler(getpid(), original_policy, &p)); 303 } 304