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