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 <pthread.h>
     21 #include <unistd.h>
     22 
     23 TEST(pthread, pthread_key_create) {
     24   pthread_key_t key;
     25   ASSERT_EQ(0, pthread_key_create(&key, NULL));
     26   ASSERT_EQ(0, pthread_key_delete(key));
     27   // Can't delete a key that's already been deleted.
     28   ASSERT_EQ(EINVAL, pthread_key_delete(key));
     29 }
     30 
     31 #if !defined(__GLIBC__) // glibc uses keys internally that its sysconf value doesn't account for.
     32 TEST(pthread, pthread_key_create_lots) {
     33   // We can allocate _SC_THREAD_KEYS_MAX keys.
     34   std::vector<pthread_key_t> keys;
     35   for (int i = 0; i < sysconf(_SC_THREAD_KEYS_MAX); ++i) {
     36     pthread_key_t key;
     37     // If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is wrong.
     38     ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << sysconf(_SC_THREAD_KEYS_MAX);
     39     keys.push_back(key);
     40   }
     41 
     42   // ...and that really is the maximum.
     43   pthread_key_t key;
     44   ASSERT_EQ(EAGAIN, pthread_key_create(&key, NULL));
     45 
     46   // (Don't leak all those keys!)
     47   for (size_t i = 0; i < keys.size(); ++i) {
     48     ASSERT_EQ(0, pthread_key_delete(keys[i]));
     49   }
     50 }
     51 #endif
     52 
     53 static void* IdFn(void* arg) {
     54   return arg;
     55 }
     56 
     57 static void* SleepFn(void* arg) {
     58   sleep(reinterpret_cast<unsigned int>(arg));
     59   return NULL;
     60 }
     61 
     62 static void* SpinFn(void* arg) {
     63   volatile bool* b = reinterpret_cast<volatile bool*>(arg);
     64   while (!*b) {
     65   }
     66   return NULL;
     67 }
     68 
     69 static void* JoinFn(void* arg) {
     70   return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL));
     71 }
     72 
     73 static void AssertDetached(pthread_t t, bool is_detached) {
     74   pthread_attr_t attr;
     75   ASSERT_EQ(0, pthread_getattr_np(t, &attr));
     76   int detach_state;
     77   ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &detach_state));
     78   pthread_attr_destroy(&attr);
     79   ASSERT_EQ(is_detached, (detach_state == PTHREAD_CREATE_DETACHED));
     80 }
     81 
     82 static void MakeDeadThread(pthread_t& t) {
     83   ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, NULL));
     84   void* result;
     85   ASSERT_EQ(0, pthread_join(t, &result));
     86 }
     87 
     88 TEST(pthread, pthread_create) {
     89   void* expected_result = reinterpret_cast<void*>(123);
     90   // Can we create a thread?
     91   pthread_t t;
     92   ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, expected_result));
     93   // If we join, do we get the expected value back?
     94   void* result;
     95   ASSERT_EQ(0, pthread_join(t, &result));
     96   ASSERT_EQ(expected_result, result);
     97 }
     98 
     99 TEST(pthread, pthread_create_EAGAIN) {
    100   pthread_attr_t attributes;
    101   ASSERT_EQ(0, pthread_attr_init(&attributes));
    102   ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, static_cast<size_t>(-1) & ~(getpagesize() - 1)));
    103 
    104   pthread_t t;
    105   ASSERT_EQ(EAGAIN, pthread_create(&t, &attributes, IdFn, NULL));
    106 }
    107 
    108 TEST(pthread, pthread_no_join_after_detach) {
    109   pthread_t t1;
    110   ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5)));
    111 
    112   // After a pthread_detach...
    113   ASSERT_EQ(0, pthread_detach(t1));
    114   AssertDetached(t1, true);
    115 
    116   // ...pthread_join should fail.
    117   void* result;
    118   ASSERT_EQ(EINVAL, pthread_join(t1, &result));
    119 }
    120 
    121 TEST(pthread, pthread_no_op_detach_after_join) {
    122   bool done = false;
    123 
    124   pthread_t t1;
    125   ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done));
    126 
    127   // If thread 2 is already waiting to join thread 1...
    128   pthread_t t2;
    129   ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1)));
    130 
    131   sleep(1); // (Give t2 a chance to call pthread_join.)
    132 
    133   // ...a call to pthread_detach on thread 1 will "succeed" (silently fail)...
    134   ASSERT_EQ(0, pthread_detach(t1));
    135   AssertDetached(t1, false);
    136 
    137   done = true;
    138 
    139   // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes).
    140   void* join_result;
    141   ASSERT_EQ(0, pthread_join(t2, &join_result));
    142   ASSERT_EQ(0, reinterpret_cast<int>(join_result));
    143 }
    144 
    145 TEST(pthread, pthread_join_self) {
    146   void* result;
    147   ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), &result));
    148 }
    149 
    150 #if __BIONIC__ // For some reason, gtest on bionic can cope with this but gtest on glibc can't.
    151 
    152 static void TestBug37410() {
    153   pthread_t t1;
    154   ASSERT_EQ(0, pthread_create(&t1, NULL, JoinFn, reinterpret_cast<void*>(pthread_self())));
    155   pthread_exit(NULL);
    156 }
    157 
    158 // Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
    159 // run this test (which exits normally) in its own process.
    160 TEST(pthread_DeathTest, pthread_bug_37410) {
    161   // http://code.google.com/p/android/issues/detail?id=37410
    162   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    163   ASSERT_EXIT(TestBug37410(), ::testing::ExitedWithCode(0), "");
    164 }
    165 #endif
    166 
    167 static void* SignalHandlerFn(void* arg) {
    168   sigset_t wait_set;
    169   sigfillset(&wait_set);
    170   return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg)));
    171 }
    172 
    173 TEST(pthread, pthread_sigmask) {
    174   // Block SIGUSR1.
    175   sigset_t set;
    176   sigemptyset(&set);
    177   sigaddset(&set, SIGUSR1);
    178   ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, NULL));
    179 
    180   // Spawn a thread that calls sigwait and tells us what it received.
    181   pthread_t signal_thread;
    182   int received_signal = -1;
    183   ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal));
    184 
    185   // Send that thread SIGUSR1.
    186   pthread_kill(signal_thread, SIGUSR1);
    187 
    188   // See what it got.
    189   void* join_result;
    190   ASSERT_EQ(0, pthread_join(signal_thread, &join_result));
    191   ASSERT_EQ(SIGUSR1, received_signal);
    192   ASSERT_EQ(0, reinterpret_cast<int>(join_result));
    193 }
    194 
    195 #if __BIONIC__
    196 extern "C" int  __pthread_clone(void* (*fn)(void*), void* child_stack, int flags, void* arg);
    197 TEST(pthread, __pthread_clone) {
    198   uintptr_t fake_child_stack[16];
    199   errno = 0;
    200   ASSERT_EQ(-1, __pthread_clone(NULL, &fake_child_stack[0], CLONE_THREAD, NULL));
    201   ASSERT_EQ(EINVAL, errno);
    202 }
    203 #endif
    204 
    205 #if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise.
    206 TEST(pthread, pthread_setname_np__too_long) {
    207   ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "this name is far too long for linux"));
    208 }
    209 #endif
    210 
    211 #if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise.
    212 TEST(pthread, pthread_setname_np__self) {
    213   ASSERT_EQ(0, pthread_setname_np(pthread_self(), "short 1"));
    214 }
    215 #endif
    216 
    217 #if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise.
    218 TEST(pthread, pthread_setname_np__other) {
    219   // Emulator kernels don't currently support setting the name of other threads.
    220   char* filename = NULL;
    221   asprintf(&filename, "/proc/self/task/%d/comm", gettid());
    222   struct stat sb;
    223   bool has_comm = (stat(filename, &sb) != -1);
    224   free(filename);
    225 
    226   if (has_comm) {
    227     pthread_t t1;
    228     ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5)));
    229     ASSERT_EQ(0, pthread_setname_np(t1, "short 2"));
    230   } else {
    231     fprintf(stderr, "skipping test: this kernel doesn't have /proc/self/task/tid/comm files!\n");
    232   }
    233 }
    234 #endif
    235 
    236 #if __BIONIC__ // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise.
    237 TEST(pthread, pthread_setname_np__no_such_thread) {
    238   pthread_t dead_thread;
    239   MakeDeadThread(dead_thread);
    240 
    241   // Call pthread_setname_np after thread has already exited.
    242   ASSERT_EQ(ESRCH, pthread_setname_np(dead_thread, "short 3"));
    243 }
    244 #endif
    245 
    246 TEST(pthread, pthread_kill__0) {
    247   // Signal 0 just tests that the thread exists, so it's safe to call on ourselves.
    248   ASSERT_EQ(0, pthread_kill(pthread_self(), 0));
    249 }
    250 
    251 TEST(pthread, pthread_kill__invalid_signal) {
    252   ASSERT_EQ(EINVAL, pthread_kill(pthread_self(), -1));
    253 }
    254 
    255 static void pthread_kill__in_signal_handler_helper(int signal_number) {
    256   static int count = 0;
    257   ASSERT_EQ(SIGALRM, signal_number);
    258   if (++count == 1) {
    259     // Can we call pthread_kill from a signal handler?
    260     ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM));
    261   }
    262 }
    263 
    264 TEST(pthread, pthread_kill__in_signal_handler) {
    265   struct sigaction action;
    266   sigemptyset(&action.sa_mask);
    267   action.sa_flags = 0;
    268   action.sa_handler = pthread_kill__in_signal_handler_helper;
    269   sigaction(SIGALRM, &action, NULL);
    270   ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM));
    271 }
    272 
    273 TEST(pthread, pthread_detach__no_such_thread) {
    274   pthread_t dead_thread;
    275   MakeDeadThread(dead_thread);
    276 
    277   ASSERT_EQ(ESRCH, pthread_detach(dead_thread));
    278 }
    279 
    280 TEST(pthread, pthread_getcpuclockid__no_such_thread) {
    281   pthread_t dead_thread;
    282   MakeDeadThread(dead_thread);
    283 
    284   clockid_t c;
    285   ASSERT_EQ(ESRCH, pthread_getcpuclockid(dead_thread, &c));
    286 }
    287 
    288 TEST(pthread, pthread_getschedparam__no_such_thread) {
    289   pthread_t dead_thread;
    290   MakeDeadThread(dead_thread);
    291 
    292   int policy;
    293   sched_param param;
    294   ASSERT_EQ(ESRCH, pthread_getschedparam(dead_thread, &policy, &param));
    295 }
    296 
    297 TEST(pthread, pthread_setschedparam__no_such_thread) {
    298   pthread_t dead_thread;
    299   MakeDeadThread(dead_thread);
    300 
    301   int policy = 0;
    302   sched_param param;
    303   ASSERT_EQ(ESRCH, pthread_setschedparam(dead_thread, policy, &param));
    304 }
    305 
    306 TEST(pthread, pthread_join__no_such_thread) {
    307   pthread_t dead_thread;
    308   MakeDeadThread(dead_thread);
    309 
    310   void* result;
    311   ASSERT_EQ(ESRCH, pthread_join(dead_thread, &result));
    312 }
    313 
    314 TEST(pthread, pthread_kill__no_such_thread) {
    315   pthread_t dead_thread;
    316   MakeDeadThread(dead_thread);
    317 
    318   ASSERT_EQ(ESRCH, pthread_kill(dead_thread, 0));
    319 }
    320