pthread_test.cpp revision c3f114037dbf028896310609fd28cf2b3da99c4d
1/* 2 * Copyright (C) 2012 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 <inttypes.h> 21#include <limits.h> 22#include <pthread.h> 23#include <unistd.h> 24 25TEST(pthread, pthread_key_create) { 26 pthread_key_t key; 27 ASSERT_EQ(0, pthread_key_create(&key, NULL)); 28 ASSERT_EQ(0, pthread_key_delete(key)); 29 // Can't delete a key that's already been deleted. 30 ASSERT_EQ(EINVAL, pthread_key_delete(key)); 31} 32 33#if !defined(__GLIBC__) // glibc uses keys internally that its sysconf value doesn't account for. 34TEST(pthread, pthread_key_create_lots) { 35 // We can allocate _SC_THREAD_KEYS_MAX keys. 36 std::vector<pthread_key_t> keys; 37 for (int i = 0; i < sysconf(_SC_THREAD_KEYS_MAX); ++i) { 38 pthread_key_t key; 39 // If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is wrong. 40 ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << sysconf(_SC_THREAD_KEYS_MAX); 41 keys.push_back(key); 42 } 43 44 // ...and that really is the maximum. 45 pthread_key_t key; 46 ASSERT_EQ(EAGAIN, pthread_key_create(&key, NULL)); 47 48 // (Don't leak all those keys!) 49 for (size_t i = 0; i < keys.size(); ++i) { 50 ASSERT_EQ(0, pthread_key_delete(keys[i])); 51 } 52} 53#endif 54 55static void* IdFn(void* arg) { 56 return arg; 57} 58 59static void* SleepFn(void* arg) { 60 sleep(reinterpret_cast<uintptr_t>(arg)); 61 return NULL; 62} 63 64static void* SpinFn(void* arg) { 65 volatile bool* b = reinterpret_cast<volatile bool*>(arg); 66 while (!*b) { 67 } 68 return NULL; 69} 70 71static void* JoinFn(void* arg) { 72 return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL)); 73} 74 75static void AssertDetached(pthread_t t, bool is_detached) { 76 pthread_attr_t attr; 77 ASSERT_EQ(0, pthread_getattr_np(t, &attr)); 78 int detach_state; 79 ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &detach_state)); 80 pthread_attr_destroy(&attr); 81 ASSERT_EQ(is_detached, (detach_state == PTHREAD_CREATE_DETACHED)); 82} 83 84static void MakeDeadThread(pthread_t& t) { 85 ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, NULL)); 86 void* result; 87 ASSERT_EQ(0, pthread_join(t, &result)); 88} 89 90TEST(pthread, pthread_create) { 91 void* expected_result = reinterpret_cast<void*>(123); 92 // Can we create a thread? 93 pthread_t t; 94 ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, expected_result)); 95 // If we join, do we get the expected value back? 96 void* result; 97 ASSERT_EQ(0, pthread_join(t, &result)); 98 ASSERT_EQ(expected_result, result); 99} 100 101TEST(pthread, pthread_create_EAGAIN) { 102 pthread_attr_t attributes; 103 ASSERT_EQ(0, pthread_attr_init(&attributes)); 104 ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, static_cast<size_t>(-1) & ~(getpagesize() - 1))); 105 106 pthread_t t; 107 ASSERT_EQ(EAGAIN, pthread_create(&t, &attributes, IdFn, NULL)); 108} 109 110TEST(pthread, pthread_no_join_after_detach) { 111 pthread_t t1; 112 ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); 113 114 // After a pthread_detach... 115 ASSERT_EQ(0, pthread_detach(t1)); 116 AssertDetached(t1, true); 117 118 // ...pthread_join should fail. 119 void* result; 120 ASSERT_EQ(EINVAL, pthread_join(t1, &result)); 121} 122 123TEST(pthread, pthread_no_op_detach_after_join) { 124 bool done = false; 125 126 pthread_t t1; 127 ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done)); 128 129 // If thread 2 is already waiting to join thread 1... 130 pthread_t t2; 131 ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 132 133 sleep(1); // (Give t2 a chance to call pthread_join.) 134 135 // ...a call to pthread_detach on thread 1 will "succeed" (silently fail)... 136 ASSERT_EQ(0, pthread_detach(t1)); 137 AssertDetached(t1, false); 138 139 done = true; 140 141 // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 142 void* join_result; 143 ASSERT_EQ(0, pthread_join(t2, &join_result)); 144 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 145} 146 147TEST(pthread, pthread_join_self) { 148 void* result; 149 ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), &result)); 150} 151 152#if __BIONIC__ // For some reason, gtest on bionic can cope with this but gtest on glibc can't. 153 154static void TestBug37410() { 155 pthread_t t1; 156 ASSERT_EQ(0, pthread_create(&t1, NULL, JoinFn, reinterpret_cast<void*>(pthread_self()))); 157 pthread_exit(NULL); 158} 159 160// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to 161// run this test (which exits normally) in its own process. 162TEST(pthread_DeathTest, pthread_bug_37410) { 163 // http://code.google.com/p/android/issues/detail?id=37410 164 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 165 ASSERT_EXIT(TestBug37410(), ::testing::ExitedWithCode(0), ""); 166} 167#endif 168 169static void* SignalHandlerFn(void* arg) { 170 sigset_t wait_set; 171 sigfillset(&wait_set); 172 return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg))); 173} 174 175TEST(pthread, pthread_sigmask) { 176 // Check that SIGUSR1 isn't blocked. 177 sigset_t original_set; 178 sigemptyset(&original_set); 179 ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &original_set)); 180 ASSERT_FALSE(sigismember(&original_set, SIGUSR1)); 181 182 // Block SIGUSR1. 183 sigset_t set; 184 sigemptyset(&set); 185 sigaddset(&set, SIGUSR1); 186 ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, NULL)); 187 188 // Check that SIGUSR1 is blocked. 189 sigset_t final_set; 190 sigemptyset(&final_set); 191 ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &final_set)); 192 ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 193 // ...and that sigprocmask agrees with pthread_sigmask. 194 sigemptyset(&final_set); 195 ASSERT_EQ(0, sigprocmask(SIG_BLOCK, NULL, &final_set)); 196 ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 197 198 // Spawn a thread that calls sigwait and tells us what it received. 199 pthread_t signal_thread; 200 int received_signal = -1; 201 ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal)); 202 203 // Send that thread SIGUSR1. 204 pthread_kill(signal_thread, SIGUSR1); 205 206 // See what it got. 207 void* join_result; 208 ASSERT_EQ(0, pthread_join(signal_thread, &join_result)); 209 ASSERT_EQ(SIGUSR1, received_signal); 210 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 211 212 // Restore the original signal mask. 213 ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL)); 214} 215 216#if __BIONIC__ 217extern "C" int __pthread_clone(void* (*fn)(void*), void* child_stack, int flags, void* arg); 218TEST(pthread, __pthread_clone) { 219 uintptr_t fake_child_stack[16]; 220 errno = 0; 221 ASSERT_EQ(-1, __pthread_clone(NULL, &fake_child_stack[0], CLONE_THREAD, NULL)); 222 ASSERT_EQ(EINVAL, errno); 223} 224#endif 225 226#if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 227TEST(pthread, pthread_setname_np__too_long) { 228 ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "this name is far too long for linux")); 229} 230#endif 231 232#if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 233TEST(pthread, pthread_setname_np__self) { 234 ASSERT_EQ(0, pthread_setname_np(pthread_self(), "short 1")); 235} 236#endif 237 238#if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 239TEST(pthread, pthread_setname_np__other) { 240 // Emulator kernels don't currently support setting the name of other threads. 241 char* filename = NULL; 242 asprintf(&filename, "/proc/self/task/%d/comm", gettid()); 243 struct stat sb; 244 bool has_comm = (stat(filename, &sb) != -1); 245 free(filename); 246 247 if (has_comm) { 248 pthread_t t1; 249 ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); 250 ASSERT_EQ(0, pthread_setname_np(t1, "short 2")); 251 } else { 252 fprintf(stderr, "skipping test: this kernel doesn't have /proc/self/task/tid/comm files!\n"); 253 } 254} 255#endif 256 257#if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 258TEST(pthread, pthread_setname_np__no_such_thread) { 259 pthread_t dead_thread; 260 MakeDeadThread(dead_thread); 261 262 // Call pthread_setname_np after thread has already exited. 263 ASSERT_EQ(ESRCH, pthread_setname_np(dead_thread, "short 3")); 264} 265#endif 266 267TEST(pthread, pthread_kill__0) { 268 // Signal 0 just tests that the thread exists, so it's safe to call on ourselves. 269 ASSERT_EQ(0, pthread_kill(pthread_self(), 0)); 270} 271 272TEST(pthread, pthread_kill__invalid_signal) { 273 ASSERT_EQ(EINVAL, pthread_kill(pthread_self(), -1)); 274} 275 276static void pthread_kill__in_signal_handler_helper(int signal_number) { 277 static int count = 0; 278 ASSERT_EQ(SIGALRM, signal_number); 279 if (++count == 1) { 280 // Can we call pthread_kill from a signal handler? 281 ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 282 } 283} 284 285TEST(pthread, pthread_kill__in_signal_handler) { 286 struct sigaction action; 287 struct sigaction original_action; 288 sigemptyset(&action.sa_mask); 289 action.sa_flags = 0; 290 action.sa_handler = pthread_kill__in_signal_handler_helper; 291 ASSERT_EQ(0, sigaction(SIGALRM, &action, &original_action)); 292 ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 293 ASSERT_EQ(0, sigaction(SIGALRM, &original_action, NULL)); 294} 295 296TEST(pthread, pthread_detach__no_such_thread) { 297 pthread_t dead_thread; 298 MakeDeadThread(dead_thread); 299 300 ASSERT_EQ(ESRCH, pthread_detach(dead_thread)); 301} 302 303TEST(pthread, pthread_getcpuclockid__clock_gettime) { 304 pthread_t t; 305 ASSERT_EQ(0, pthread_create(&t, NULL, SleepFn, reinterpret_cast<void*>(5))); 306 307 clockid_t c; 308 ASSERT_EQ(0, pthread_getcpuclockid(t, &c)); 309 timespec ts; 310 ASSERT_EQ(0, clock_gettime(c, &ts)); 311} 312 313TEST(pthread, pthread_getcpuclockid__no_such_thread) { 314 pthread_t dead_thread; 315 MakeDeadThread(dead_thread); 316 317 clockid_t c; 318 ASSERT_EQ(ESRCH, pthread_getcpuclockid(dead_thread, &c)); 319} 320 321TEST(pthread, pthread_getschedparam__no_such_thread) { 322 pthread_t dead_thread; 323 MakeDeadThread(dead_thread); 324 325 int policy; 326 sched_param param; 327 ASSERT_EQ(ESRCH, pthread_getschedparam(dead_thread, &policy, ¶m)); 328} 329 330TEST(pthread, pthread_setschedparam__no_such_thread) { 331 pthread_t dead_thread; 332 MakeDeadThread(dead_thread); 333 334 int policy = 0; 335 sched_param param; 336 ASSERT_EQ(ESRCH, pthread_setschedparam(dead_thread, policy, ¶m)); 337} 338 339TEST(pthread, pthread_join__no_such_thread) { 340 pthread_t dead_thread; 341 MakeDeadThread(dead_thread); 342 343 void* result; 344 ASSERT_EQ(ESRCH, pthread_join(dead_thread, &result)); 345} 346 347TEST(pthread, pthread_kill__no_such_thread) { 348 pthread_t dead_thread; 349 MakeDeadThread(dead_thread); 350 351 ASSERT_EQ(ESRCH, pthread_kill(dead_thread, 0)); 352} 353 354TEST(pthread, pthread_join__multijoin) { 355 bool done = false; 356 357 pthread_t t1; 358 ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done)); 359 360 pthread_t t2; 361 ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 362 363 sleep(1); // (Give t2 a chance to call pthread_join.) 364 365 // Multiple joins to the same thread should fail. 366 ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 367 368 done = true; 369 370 // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 371 void* join_result; 372 ASSERT_EQ(0, pthread_join(t2, &join_result)); 373 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 374} 375 376static void* GetActualGuardSizeFn(void* arg) { 377 pthread_attr_t attributes; 378 pthread_getattr_np(pthread_self(), &attributes); 379 pthread_attr_getguardsize(&attributes, reinterpret_cast<size_t*>(arg)); 380 return NULL; 381} 382 383static size_t GetActualGuardSize(const pthread_attr_t& attributes) { 384 size_t result; 385 pthread_t t; 386 pthread_create(&t, &attributes, GetActualGuardSizeFn, &result); 387 void* join_result; 388 pthread_join(t, &join_result); 389 return result; 390} 391 392static void* GetActualStackSizeFn(void* arg) { 393 pthread_attr_t attributes; 394 pthread_getattr_np(pthread_self(), &attributes); 395 pthread_attr_getstacksize(&attributes, reinterpret_cast<size_t*>(arg)); 396 return NULL; 397} 398 399static size_t GetActualStackSize(const pthread_attr_t& attributes) { 400 size_t result; 401 pthread_t t; 402 pthread_create(&t, &attributes, GetActualStackSizeFn, &result); 403 void* join_result; 404 pthread_join(t, &join_result); 405 return result; 406} 407 408TEST(pthread, pthread_attr_setguardsize) { 409 pthread_attr_t attributes; 410 ASSERT_EQ(0, pthread_attr_init(&attributes)); 411 412 // Get the default guard size. 413 size_t default_guard_size; 414 ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &default_guard_size)); 415 416 // No such thing as too small: will be rounded up to one page by pthread_create. 417 ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 128)); 418 size_t guard_size; 419 ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 420 ASSERT_EQ(128U, guard_size); 421 ASSERT_EQ(4096U, GetActualGuardSize(attributes)); 422 423 // Large enough and a multiple of the page size. 424 ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024)); 425 ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 426 ASSERT_EQ(32*1024U, guard_size); 427 428 // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 429 ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024 + 1)); 430 ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 431 ASSERT_EQ(32*1024U + 1, guard_size); 432} 433 434TEST(pthread, pthread_attr_setstacksize) { 435 pthread_attr_t attributes; 436 ASSERT_EQ(0, pthread_attr_init(&attributes)); 437 438 // Get the default stack size. 439 size_t default_stack_size; 440 ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &default_stack_size)); 441 442 // Too small. 443 ASSERT_EQ(EINVAL, pthread_attr_setstacksize(&attributes, 128)); 444 size_t stack_size; 445 ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 446 ASSERT_EQ(default_stack_size, stack_size); 447 ASSERT_GE(GetActualStackSize(attributes), default_stack_size); 448 449 // Large enough and a multiple of the page size. 450 ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024)); 451 ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 452 ASSERT_EQ(32*1024U, stack_size); 453 ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 454 455 // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 456 ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024 + 1)); 457 ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 458 ASSERT_EQ(32*1024U + 1, stack_size); 459#if __BIONIC__ 460 // Bionic rounds up, which is what POSIX allows. 461 ASSERT_EQ(GetActualStackSize(attributes), (32 + 4)*1024U); 462#else 463 // glibc rounds down, in violation of POSIX. They document this in their BUGS section. 464 ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 465#endif 466} 467 468TEST(pthread, pthread_rwlock_smoke) { 469 pthread_rwlock_t l; 470 ASSERT_EQ(0, pthread_rwlock_init(&l, NULL)); 471 472 ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 473 ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 474 475 ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 476 ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 477 478 ASSERT_EQ(0, pthread_rwlock_destroy(&l)); 479} 480 481static int gOnceFnCallCount = 0; 482static void OnceFn() { 483 ++gOnceFnCallCount; 484} 485 486TEST(pthread, pthread_once_smoke) { 487 pthread_once_t once_control = PTHREAD_ONCE_INIT; 488 ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 489 ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 490 ASSERT_EQ(1, gOnceFnCallCount); 491} 492 493static int gAtForkPrepareCalls = 0; 494static void AtForkPrepare1() { gAtForkPrepareCalls = (gAtForkPrepareCalls << 4) | 1; } 495static void AtForkPrepare2() { gAtForkPrepareCalls = (gAtForkPrepareCalls << 4) | 2; } 496static int gAtForkParentCalls = 0; 497static void AtForkParent1() { gAtForkParentCalls = (gAtForkParentCalls << 4) | 1; } 498static void AtForkParent2() { gAtForkParentCalls = (gAtForkParentCalls << 4) | 2; } 499static int gAtForkChildCalls = 0; 500static void AtForkChild1() { gAtForkChildCalls = (gAtForkChildCalls << 4) | 1; } 501static void AtForkChild2() { gAtForkChildCalls = (gAtForkChildCalls << 4) | 2; } 502 503TEST(pthread, pthread_atfork) { 504 ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); 505 ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); 506 507 int pid = fork(); 508 ASSERT_NE(-1, pid) << strerror(errno); 509 510 // Child and parent calls are made in the order they were registered. 511 if (pid == 0) { 512 ASSERT_EQ(0x12, gAtForkChildCalls); 513 _exit(0); 514 } 515 ASSERT_EQ(0x12, gAtForkParentCalls); 516 517 // Prepare calls are made in the reverse order. 518 ASSERT_EQ(0x21, gAtForkPrepareCalls); 519} 520 521TEST(pthread, pthread_attr_getscope) { 522 pthread_attr_t attr; 523 ASSERT_EQ(0, pthread_attr_init(&attr)); 524 525 int scope; 526 ASSERT_EQ(0, pthread_attr_getscope(&attr, &scope)); 527 ASSERT_EQ(PTHREAD_SCOPE_SYSTEM, scope); 528} 529