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