1bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes/* 2bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * Copyright (C) 2012 The Android Open Source Project 3bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * 4bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * you may not use this file except in compliance with the License. 6bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * You may obtain a copy of the License at 7bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * 8bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * 10bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * See the License for the specific language governing permissions and 14bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes * limitations under the License. 15bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes */ 16bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 17bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <gtest/gtest.h> 18bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 19bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <errno.h> 205b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes#include <inttypes.h> 21b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes#include <limits.h> 2204620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes#include <malloc.h> 23bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <pthread.h> 24f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#include <signal.h> 2570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes#include <sys/mman.h> 26642182341018b282148280a7bdb771493e15bd7dElliott Hughes#include <sys/syscall.h> 2751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#include <time.h> 284d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes#include <unistd.h> 29bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 305beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes#include "private/ScopeGuard.h" 314b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes#include "ScopedSignalHandler.h" 324b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes 33bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott HughesTEST(pthread, pthread_key_create) { 34bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes pthread_key_t key; 35bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 36bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 37bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes // Can't delete a key that's already been deleted. 38bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(EINVAL, pthread_key_delete(key)); 39bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes} 404d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 4144b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott HughesTEST(pthread, pthread_key_create_lots) { 42f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) // glibc uses keys internally that its sysconf value doesn't account for. 431887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes // POSIX says PTHREAD_KEYS_MAX should be at least 128. 441887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes ASSERT_GE(PTHREAD_KEYS_MAX, 128); 45718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes 46718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX); 47718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes 481887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes // sysconf shouldn't return a smaller value. 49718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes ASSERT_GE(sysconf_max, PTHREAD_KEYS_MAX); 501887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes 5144b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes // We can allocate _SC_THREAD_KEYS_MAX keys. 52718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes sysconf_max -= 2; // (Except that gtest takes two for itself.) 5344b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes std::vector<pthread_key_t> keys; 54718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes for (int i = 0; i < sysconf_max; ++i) { 5544b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes pthread_key_t key; 563e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes // If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is wrong. 57718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << sysconf_max; 5844b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes keys.push_back(key); 5944b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 6044b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 6144b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes // ...and that really is the maximum. 6244b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes pthread_key_t key; 6344b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes ASSERT_EQ(EAGAIN, pthread_key_create(&key, NULL)); 6444b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 6544b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes // (Don't leak all those keys!) 6644b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes for (size_t i = 0; i < keys.size(); ++i) { 6744b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes ASSERT_EQ(0, pthread_key_delete(keys[i])); 6844b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 69f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 70f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris GTEST_LOG_(INFO) << "This test does nothing.\n"; 71f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 7244b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes} 7344b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 74ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott HughesTEST(pthread, pthread_key_delete) { 75ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes void* expected = reinterpret_cast<void*>(1234); 76ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes pthread_key_t key; 77ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 78ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 79ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 80ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 81ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // After deletion, pthread_getspecific returns NULL. 82ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(NULL, pthread_getspecific(key)); 83ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // And you can't use pthread_setspecific with the deleted key. 84ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(EINVAL, pthread_setspecific(key, expected)); 85ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes} 86ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes 8711bf8a3025a7b5aee891c521255a7db1860e5b12Elliott HughesTEST(pthread, pthread_key_fork) { 8811bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes void* expected = reinterpret_cast<void*>(1234); 8911bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes pthread_key_t key; 9011bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 9111bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 9211bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 9311bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 9411bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes pid_t pid = fork(); 9511bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_NE(-1, pid) << strerror(errno); 9611bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 9711bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes if (pid == 0) { 9811bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes // The surviving thread inherits all the forking thread's TLS values... 9911bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 10011bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes _exit(99); 10111bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes } 10211bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 10311bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes int status; 10411bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(pid, waitpid(pid, &status, 0)); 10511bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_TRUE(WIFEXITED(status)); 10611bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(99, WEXITSTATUS(status)); 10711bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 10811bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 10911bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes} 11011bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 11111bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughesstatic void* DirtyKeyFn(void* key) { 11211bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes return pthread_getspecific(*reinterpret_cast<pthread_key_t*>(key)); 11311bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes} 11411bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 11511bf8a3025a7b5aee891c521255a7db1860e5b12Elliott HughesTEST(pthread, pthread_key_dirty) { 11611bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes pthread_key_t key; 11711bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 11811bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 11911bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes size_t stack_size = 128 * 1024; 12011bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 12111bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_NE(MAP_FAILED, stack); 12211bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes memset(stack, 0xff, stack_size); 12311bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 12411bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes pthread_attr_t attr; 12511bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 12611bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size)); 12711bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 12811bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes pthread_t t; 12911bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &attr, DirtyKeyFn, &key)); 13011bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 13111bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes void* result; 13211bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 13311bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(nullptr, result); // Not ~0! 13411bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 13511bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 13611bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes} 13711bf8a3025a7b5aee891c521255a7db1860e5b12Elliott Hughes 1384d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* IdFn(void* arg) { 1394d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return arg; 1404d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1414d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 1424d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* SleepFn(void* arg) { 1435b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes sleep(reinterpret_cast<uintptr_t>(arg)); 1444d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return NULL; 1454d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1464d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 14710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikovstatic void* SpinFn(void* arg) { 14810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov volatile bool* b = reinterpret_cast<volatile bool*>(arg); 14910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov while (!*b) { 15010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov } 15110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov return NULL; 15210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov} 15310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 1544d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* JoinFn(void* arg) { 1554d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL)); 1564d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1574d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 15810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikovstatic void AssertDetached(pthread_t t, bool is_detached) { 15910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_t attr; 16010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_getattr_np(t, &attr)); 16110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov int detach_state; 16210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &detach_state)); 16310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_destroy(&attr); 16410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(is_detached, (detach_state == PTHREAD_CREATE_DETACHED)); 16510ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov} 16610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 1679d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughesstatic void MakeDeadThread(pthread_t& t) { 1689d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, NULL)); 1699d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes void* result; 1709d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 1719d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 1729d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 1734d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_create) { 1744d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* expected_result = reinterpret_cast<void*>(123); 1754d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // Can we create a thread? 1764d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t; 1774d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, expected_result)); 1784d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If we join, do we get the expected value back? 1794d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* result; 1804d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 1814d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(expected_result, result); 1824d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1834d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 1843e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_create_EAGAIN) { 1853e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_attr_t attributes; 1863e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 1873e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, static_cast<size_t>(-1) & ~(getpagesize() - 1))); 1883e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 1893e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_t t; 1903e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(EAGAIN, pthread_create(&t, &attributes, IdFn, NULL)); 1913e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 1923e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 1934d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_join_after_detach) { 1944d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 1954d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); 1964d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 1974d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // After a pthread_detach... 1984d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 19910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, true); 2004d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2014d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // ...pthread_join should fail. 2024d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* result; 2034d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(EINVAL, pthread_join(t1, &result)); 2044d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2054d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2064d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_op_detach_after_join) { 20710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov bool done = false; 20810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2094d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 21010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done)); 2114d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2124d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If thread 2 is already waiting to join thread 1... 2134d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t2; 2144d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 2154d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 21610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov sleep(1); // (Give t2 a chance to call pthread_join.) 21710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 21810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov // ...a call to pthread_detach on thread 1 will "succeed" (silently fail)... 2194d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 22010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, false); 22110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 22210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov done = true; 2234d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 22410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 2254d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* join_result; 2264d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t2, &join_result)); 2275b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 2284d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 22914f19592ae7c819855052bcebc79de87069c2954Elliott Hughes 23014f19592ae7c819855052bcebc79de87069c2954Elliott HughesTEST(pthread, pthread_join_self) { 23114f19592ae7c819855052bcebc79de87069c2954Elliott Hughes void* result; 23214f19592ae7c819855052bcebc79de87069c2954Elliott Hughes ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), &result)); 23314f19592ae7c819855052bcebc79de87069c2954Elliott Hughes} 2344f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 235877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstruct TestBug37410 { 236877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t main_thread; 237877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_t mutex; 2384f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 239877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void main() { 240877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410 data; 241877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes data.main_thread = pthread_self(); 242877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_init(&data.mutex, NULL)); 243877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 244877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 245877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t t; 246877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, TestBug37410::thread_fn, reinterpret_cast<void*>(&data))); 247877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 248877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Wait for the thread to be running... 249877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 250877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&data.mutex)); 251877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 252877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // ...and exit. 253877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_exit(NULL); 254877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 255877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 256877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes private: 257877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void* thread_fn(void* arg) { 258877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410* data = reinterpret_cast<TestBug37410*>(arg); 259877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 260877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Let the main thread know we're running. 261877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_unlock(&data->mutex); 262877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 263877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // And wait for the main thread to exit. 264877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_join(data->main_thread, NULL); 265877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 266877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes return NULL; 267877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 268877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}; 2694f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 2707fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to 2717fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// run this test (which exits normally) in its own process. 2724f251bee5d51228217c1bf4dfc9219f3058bd3edElliott HughesTEST(pthread_DeathTest, pthread_bug_37410) { 2734f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes // http://code.google.com/p/android/issues/detail?id=37410 2744f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 275877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EXIT(TestBug37410::main(), ::testing::ExitedWithCode(0), ""); 2764f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes} 277c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 278c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughesstatic void* SignalHandlerFn(void* arg) { 279c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t wait_set; 280c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigfillset(&wait_set); 281c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg))); 282c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 283c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 284c5d028fc913de84a781bd61084bf7ae2182fd48eElliott HughesTEST(pthread, pthread_sigmask) { 28519e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 isn't blocked. 28619e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t original_set; 28719e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&original_set); 28819e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &original_set)); 28919e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_FALSE(sigismember(&original_set, SIGUSR1)); 29019e62325c268a668692e2b65fde2284079f369aaElliott Hughes 291c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Block SIGUSR1. 292c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t set; 293c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigemptyset(&set); 294c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigaddset(&set, SIGUSR1); 295c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, NULL)); 296c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 29719e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 is blocked. 29819e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t final_set; 29919e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 30019e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &final_set)); 30119e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 30219e62325c268a668692e2b65fde2284079f369aaElliott Hughes // ...and that sigprocmask agrees with pthread_sigmask. 30319e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 30419e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, sigprocmask(SIG_BLOCK, NULL, &final_set)); 30519e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 30619e62325c268a668692e2b65fde2284079f369aaElliott Hughes 307c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Spawn a thread that calls sigwait and tells us what it received. 308c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_t signal_thread; 309c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes int received_signal = -1; 310c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal)); 311c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 312c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Send that thread SIGUSR1. 313c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_kill(signal_thread, SIGUSR1); 314c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 315c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // See what it got. 316c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes void* join_result; 317c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_join(signal_thread, &join_result)); 318c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(SIGUSR1, received_signal); 3195b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 32019e62325c268a668692e2b65fde2284079f369aaElliott Hughes 32119e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Restore the original signal mask. 32219e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL)); 323c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 3245e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes 3253e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__too_long) { 326f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 3273e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "this name is far too long for linux")); 328f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 329f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris GTEST_LOG_(INFO) << "This test does nothing.\n"; 330f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 3313e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3323e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3333e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__self) { 334f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 3353e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_setname_np(pthread_self(), "short 1")); 336f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 337f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris GTEST_LOG_(INFO) << "This test does nothing.\n"; 338f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 3393e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3403e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3413e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__other) { 342f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 34340eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes // Emulator kernels don't currently support setting the name of other threads. 34440eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes char* filename = NULL; 34540eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes asprintf(&filename, "/proc/self/task/%d/comm", gettid()); 34640eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes struct stat sb; 34740eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes bool has_comm = (stat(filename, &sb) != -1); 34840eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes free(filename); 34940eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes 35040eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes if (has_comm) { 35140eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes pthread_t t1; 35240eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); 35340eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes ASSERT_EQ(0, pthread_setname_np(t1, "short 2")); 35440eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes } else { 35540eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes fprintf(stderr, "skipping test: this kernel doesn't have /proc/self/task/tid/comm files!\n"); 35640eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes } 357f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 358f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris GTEST_LOG_(INFO) << "This test does nothing.\n"; 359f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 3603e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3613e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3623e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__no_such_thread) { 363f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) // Not all build servers have a new enough glibc? TODO: remove when they're on gprecise. 3649d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 3659d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 3663e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3673e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes // Call pthread_setname_np after thread has already exited. 368a41ba2f0bfc4fce1ce8f06a9c289102c440c929dElliott Hughes ASSERT_EQ(ESRCH, pthread_setname_np(dead_thread, "short 3")); 369f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 370f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris GTEST_LOG_(INFO) << "This test does nothing.\n"; 371f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 3723e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3739d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 3749d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__0) { 3759d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes // Signal 0 just tests that the thread exists, so it's safe to call on ourselves. 3769d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), 0)); 3779d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 3789d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 3799d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__invalid_signal) { 3809d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(EINVAL, pthread_kill(pthread_self(), -1)); 3819d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 3829d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 383fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughesstatic void pthread_kill__in_signal_handler_helper(int signal_number) { 384fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes static int count = 0; 385fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(SIGALRM, signal_number); 386fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes if (++count == 1) { 387fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes // Can we call pthread_kill from a signal handler? 388fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 389fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes } 390fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 391fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 392fae89fc4042ee4c360842234dfda7831c313bd44Elliott HughesTEST(pthread, pthread_kill__in_signal_handler) { 3934b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes ScopedSignalHandler ssh(SIGALRM, pthread_kill__in_signal_handler_helper); 394fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 395fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 396fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 3979d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_detach__no_such_thread) { 3989d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 3999d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4009d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4019d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_detach(dead_thread)); 4029d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4039d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 40404620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott HughesTEST(pthread, pthread_detach__leak) { 40518d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris size_t initial_bytes = 0; 40618d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris // Run this loop more than once since the first loop causes some memory 40718d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris // to be allocated permenantly. Run an extra loop to help catch any subtle 40818d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris // memory leaks. 40918d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris for (size_t loop = 0; loop < 3; loop++) { 41018d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris // Set the initial bytes on the second loop since the memory in use 41118d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris // should have stabilized. 41218d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris if (loop == 1) { 41318d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris initial_bytes = mallinfo().uordblks; 41418d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris } 41518d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris 41618d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris pthread_attr_t attr; 41718d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris ASSERT_EQ(0, pthread_attr_init(&attr)); 41818d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); 41918d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris 42018d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris std::vector<pthread_t> threads; 42118d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris for (size_t i = 0; i < 32; ++i) { 42218d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris pthread_t t; 42318d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL)); 42418d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris threads.push_back(t); 42518d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris } 42618d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris 42718d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris sleep(1); 42818d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris 42918d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris for (size_t i = 0; i < 32; ++i) { 43018d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris ASSERT_EQ(0, pthread_detach(threads[i])) << i; 43118d93f2793fad393b6aa6eae6afe1054958339d5Christopher Ferris } 43204620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes } 43304620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 43404620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes size_t final_bytes = mallinfo().uordblks; 43504620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes int leaked_bytes = (final_bytes - initial_bytes); 43604620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 43704620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes // User code (like this test) doesn't know how large pthread_internal_t is. 43804620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes // We can be pretty sure it's more than 128 bytes. 43904620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes ASSERT_LT(leaked_bytes, 32 /*threads*/ * 128 /*bytes*/); 44004620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes} 44104620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 4429b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff HaoTEST(pthread, pthread_getcpuclockid__clock_gettime) { 4439b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao pthread_t t; 4449b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, pthread_create(&t, NULL, SleepFn, reinterpret_cast<void*>(5))); 4459b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 4469b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao clockid_t c; 4479b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, pthread_getcpuclockid(t, &c)); 4489b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao timespec ts; 4499b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, clock_gettime(c, &ts)); 4509b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao} 4519b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 4529d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_getcpuclockid__no_such_thread) { 4539d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4549d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4559d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4569d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes clockid_t c; 4579d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getcpuclockid(dead_thread, &c)); 4589d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4599d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4609d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_getschedparam__no_such_thread) { 4619d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4629d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4639d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4649d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy; 4659d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 4669d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getschedparam(dead_thread, &policy, ¶m)); 4679d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4689d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4699d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_setschedparam__no_such_thread) { 4709d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4719d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4729d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4739d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy = 0; 4749d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 4759d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_setschedparam(dead_thread, policy, ¶m)); 4769d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4779d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4789d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_join__no_such_thread) { 4799d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4809d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4819d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4829d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes void* result; 4839d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_join(dead_thread, &result)); 4849d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4859d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4869d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__no_such_thread) { 4879d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4889d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4899d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4909d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_kill(dead_thread, 0)); 4919d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4920f020d18b138e24b1fe34074808e07ac412f35a4msg 4930f020d18b138e24b1fe34074808e07ac412f35a4msgTEST(pthread, pthread_join__multijoin) { 4940f020d18b138e24b1fe34074808e07ac412f35a4msg bool done = false; 4950f020d18b138e24b1fe34074808e07ac412f35a4msg 4960f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t1; 4970f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done)); 4980f020d18b138e24b1fe34074808e07ac412f35a4msg 4990f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t2; 5000f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 5010f020d18b138e24b1fe34074808e07ac412f35a4msg 5020f020d18b138e24b1fe34074808e07ac412f35a4msg sleep(1); // (Give t2 a chance to call pthread_join.) 5030f020d18b138e24b1fe34074808e07ac412f35a4msg 5040f020d18b138e24b1fe34074808e07ac412f35a4msg // Multiple joins to the same thread should fail. 5050f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 5060f020d18b138e24b1fe34074808e07ac412f35a4msg 5070f020d18b138e24b1fe34074808e07ac412f35a4msg done = true; 5080f020d18b138e24b1fe34074808e07ac412f35a4msg 5090f020d18b138e24b1fe34074808e07ac412f35a4msg // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 5100f020d18b138e24b1fe34074808e07ac412f35a4msg void* join_result; 5110f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_join(t2, &join_result)); 5125b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 5130f020d18b138e24b1fe34074808e07ac412f35a4msg} 514b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 51570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott HughesTEST(pthread, pthread_join__race) { 51670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // http://b/11693195 --- pthread_join could return before the thread had actually exited. 51770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // If the joiner unmapped the thread's stack, that could lead to SIGSEGV in the thread. 51870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes for (size_t i = 0; i < 1024; ++i) { 51970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes size_t stack_size = 64*1024; 52070b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); 52170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 52270b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_t a; 52370b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_init(&a); 52470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_setstack(&a, stack, stack_size); 52570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 52670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_t t; 52770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &a, IdFn, NULL)); 52870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_join(t, NULL)); 52970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 53070b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes } 53170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes} 53270b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 533b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualGuardSizeFn(void* arg) { 534b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 535b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 536b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getguardsize(&attributes, reinterpret_cast<size_t*>(arg)); 537b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 538b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 539b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 540b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualGuardSize(const pthread_attr_t& attributes) { 541b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 542b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 543b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualGuardSizeFn, &result); 544b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes void* join_result; 545b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_join(t, &join_result); 546b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 547b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 548b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 549b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualStackSizeFn(void* arg) { 550b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 551b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 552b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getstacksize(&attributes, reinterpret_cast<size_t*>(arg)); 553b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 554b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 555b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 556b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualStackSize(const pthread_attr_t& attributes) { 557b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 558b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 559b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualStackSizeFn, &result); 560b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes void* join_result; 561b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_join(t, &join_result); 562b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 563b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 564b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 565b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setguardsize) { 566b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 567b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 568b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 569b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default guard size. 570b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_guard_size; 571b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &default_guard_size)); 572b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 573b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // No such thing as too small: will be rounded up to one page by pthread_create. 574b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 128)); 575b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t guard_size; 576b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 577b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(128U, guard_size); 578b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(4096U, GetActualGuardSize(attributes)); 579b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 580b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough and a multiple of the page size. 581b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024)); 582b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 583b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, guard_size); 584b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 585b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 586b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024 + 1)); 587b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 588b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, guard_size); 589b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 590b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 591b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setstacksize) { 592b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 593b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 594b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 595b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default stack size. 596b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_stack_size; 597b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &default_stack_size)); 598b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 599b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Too small. 600b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(EINVAL, pthread_attr_setstacksize(&attributes, 128)); 601b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t stack_size; 602b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 603b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(default_stack_size, stack_size); 604b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_GE(GetActualStackSize(attributes), default_stack_size); 605b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 606b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough and a multiple of the page size. 607b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024)); 608b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 609b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, stack_size); 610b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 611b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 612b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 613b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024 + 1)); 614b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 615b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, stack_size); 616f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) 617b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Bionic rounds up, which is what POSIX allows. 618b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), (32 + 4)*1024U); 619f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 620b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // glibc rounds down, in violation of POSIX. They document this in their BUGS section. 621b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 622f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 623b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 624c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 625c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_rwlock_smoke) { 626c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_rwlock_t l; 627c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_init(&l, NULL)); 628c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 62976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Single read lock 630c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 631c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 632c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 63376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Multiple read lock 63476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 63576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 63676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 63776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 63876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 63976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Write lock 64092687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 64192687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 64276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 64376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock 64476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_trywrlock(&l)); 64576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 64676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&l)); 64776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 64876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 64976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try reader lock 65076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 65176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 65276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 65376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 65476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 65576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 65676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock after unlock 65776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 65876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 65976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 66076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle#ifdef __BIONIC__ 66176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "read after write" 66276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 66376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_rdlock(&l)); 66476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 66576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 66676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "write after write" 667c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 66876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_wrlock(&l)); 669c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 67076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle#endif 671c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 672c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_destroy(&l)); 673c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 674c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 6751728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_once_fn_call_count = 0; 676c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughesstatic void OnceFn() { 6771728b2396591853345507a063ed6075dfd251706Elliott Hughes ++g_once_fn_call_count; 678c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 679c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 680c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_once_smoke) { 681c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_once_t once_control = PTHREAD_ONCE_INIT; 682c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 683c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 6841728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(1, g_once_fn_call_count); 685c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 686c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 6873694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic std::string pthread_once_1934122_result = ""; 6883694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 6893694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine2() { 6903694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "2"; 6913694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 6923694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 6933694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine1() { 6943694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_2 = PTHREAD_ONCE_INIT; 6953694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "1"; 6963694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once(&once_control_2, &Routine2); 6973694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 6983694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 6993694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott HughesTEST(pthread, pthread_once_1934122) { 7003694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // Very old versions of Android couldn't call pthread_once from a 7013694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // pthread_once init routine. http://b/1934122. 7023694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_1 = PTHREAD_ONCE_INIT; 7033694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ(0, pthread_once(&once_control_1, &Routine1)); 7043694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ("12", pthread_once_1934122_result); 7053694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 7063694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 7071728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_prepare_calls = 0; 7081728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls << 4) | 1; } 7091728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls << 4) | 2; } 7101728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_parent_calls = 0; 7111728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls << 4) | 1; } 7121728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls << 4) | 2; } 7131728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_child_calls = 0; 7141728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls << 4) | 1; } 7151728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls << 4) | 2; } 716c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 717c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_atfork) { 718c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); 719c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); 720c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 721c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes int pid = fork(); 722c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_NE(-1, pid) << strerror(errno); 723c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 724c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes // Child and parent calls are made in the order they were registered. 725c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes if (pid == 0) { 7261728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(0x12, g_atfork_child_calls); 727c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes _exit(0); 728c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes } 7291728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(0x12, g_atfork_parent_calls); 730c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 731c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes // Prepare calls are made in the reverse order. 7321728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(0x21, g_atfork_prepare_calls); 733c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 734c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 735c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_attr_getscope) { 736c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_attr_t attr; 737c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 738c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 739c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes int scope; 740c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_getscope(&attr, &scope)); 741c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(PTHREAD_SCOPE_SYSTEM, scope); 742c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 74351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 74451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_init) { 74551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 74651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 74751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 74851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 74951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 75051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 75151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 75251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 75351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 75451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared); 75551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 75651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 75751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_setclock) { 75851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 75951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 76051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 76151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_REALTIME)); 76251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 76351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 76451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 76551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 76651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 76751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 76851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 76951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 77051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(EINVAL, pthread_condattr_setclock(&attr, CLOCK_PROCESS_CPUTIME_ID)); 77151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 77251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 77351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_cond_broadcast__preserves_condattr_flags) { 77451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#if defined(__BIONIC__) // This tests a bionic implementation detail. 77551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 77651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 77751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 77851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 77951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); 78051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 78151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_cond_t cond_var; 78251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_init(&cond_var, &attr)); 78351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 78451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_signal(&cond_var)); 78551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_broadcast(&cond_var)); 78651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 78751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath attr = static_cast<pthread_condattr_t>(cond_var.value); 78851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 78951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 79051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 79151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 79251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 79351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared); 79451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#else // __BIONIC__ 79551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath GTEST_LOG_(INFO) << "This test does nothing.\n"; 79651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#endif // __BIONIC__ 79751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 7980e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 7990e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott HughesTEST(pthread, pthread_mutex_timedlock) { 8000e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes pthread_mutex_t m; 8010e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_init(&m, NULL)); 8020e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8030e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is already locked, pthread_mutex_timedlock should time out. 8040e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&m)); 8050e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8060e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes timespec ts; 8070e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 8080e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 8090e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(ETIMEDOUT, pthread_mutex_timedlock(&m, &ts)); 8100e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8110e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is unlocked, pthread_mutex_timedlock should succeed. 8120e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 8130e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8140e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 8150e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 8160e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_timedlock(&m, &ts)); 8170e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8180e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 8190e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_destroy(&m)); 8200e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes} 821642182341018b282148280a7bdb771493e15bd7dElliott Hughes 822642182341018b282148280a7bdb771493e15bd7dElliott HughesTEST(pthread, pthread_attr_getstack__main_thread) { 823642182341018b282148280a7bdb771493e15bd7dElliott Hughes // This test is only meaningful for the main thread, so make sure we're running on it! 824642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(getpid(), syscall(__NR_gettid)); 825642182341018b282148280a7bdb771493e15bd7dElliott Hughes 826642182341018b282148280a7bdb771493e15bd7dElliott Hughes // Get the main thread's attributes. 827642182341018b282148280a7bdb771493e15bd7dElliott Hughes pthread_attr_t attributes; 828642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 829642182341018b282148280a7bdb771493e15bd7dElliott Hughes 830642182341018b282148280a7bdb771493e15bd7dElliott Hughes // Check that we correctly report that the main thread has no guard page. 831642182341018b282148280a7bdb771493e15bd7dElliott Hughes size_t guard_size; 832642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 833642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0U, guard_size); // The main thread has no guard page. 834642182341018b282148280a7bdb771493e15bd7dElliott Hughes 835642182341018b282148280a7bdb771493e15bd7dElliott Hughes // Get the stack base and the stack size (both ways). 836642182341018b282148280a7bdb771493e15bd7dElliott Hughes void* stack_base; 837642182341018b282148280a7bdb771493e15bd7dElliott Hughes size_t stack_size; 838642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 839642182341018b282148280a7bdb771493e15bd7dElliott Hughes size_t stack_size2; 840642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 841642182341018b282148280a7bdb771493e15bd7dElliott Hughes 842642182341018b282148280a7bdb771493e15bd7dElliott Hughes // The two methods of asking for the stack size should agree. 843642182341018b282148280a7bdb771493e15bd7dElliott Hughes EXPECT_EQ(stack_size, stack_size2); 844642182341018b282148280a7bdb771493e15bd7dElliott Hughes 845642182341018b282148280a7bdb771493e15bd7dElliott Hughes // What does /proc/self/maps' [stack] line say? 84667f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes void* maps_stack_hi = NULL; 847642182341018b282148280a7bdb771493e15bd7dElliott Hughes FILE* fp = fopen("/proc/self/maps", "r"); 848642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_TRUE(fp != NULL); 849642182341018b282148280a7bdb771493e15bd7dElliott Hughes char line[BUFSIZ]; 850642182341018b282148280a7bdb771493e15bd7dElliott Hughes while (fgets(line, sizeof(line), fp) != NULL) { 851642182341018b282148280a7bdb771493e15bd7dElliott Hughes uintptr_t lo, hi; 852642182341018b282148280a7bdb771493e15bd7dElliott Hughes char name[10]; 853642182341018b282148280a7bdb771493e15bd7dElliott Hughes sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name); 854642182341018b282148280a7bdb771493e15bd7dElliott Hughes if (strcmp(name, "[stack]") == 0) { 85567f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes maps_stack_hi = reinterpret_cast<void*>(hi); 856642182341018b282148280a7bdb771493e15bd7dElliott Hughes break; 857642182341018b282148280a7bdb771493e15bd7dElliott Hughes } 858642182341018b282148280a7bdb771493e15bd7dElliott Hughes } 859642182341018b282148280a7bdb771493e15bd7dElliott Hughes fclose(fp); 860642182341018b282148280a7bdb771493e15bd7dElliott Hughes 86167f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes // The stack size should correspond to RLIMIT_STACK. 86267f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes rlimit rl; 86367f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl)); 8645beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes uint64_t original_rlim_cur = rl.rlim_cur; 8655beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes#if defined(__BIONIC__) 8665beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes if (rl.rlim_cur == RLIM_INFINITY) { 8675beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB. 8685beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes } 8695beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes#endif 87067f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes EXPECT_EQ(rl.rlim_cur, stack_size); 871642182341018b282148280a7bdb771493e15bd7dElliott Hughes 8725beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes auto guard = create_scope_guard([&rl, original_rlim_cur]() { 8735beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes rl.rlim_cur = original_rlim_cur; 8745beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 8755beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes }); 8765beddb7d642524ecb6655ab2823caf2add679917Elliott Hughes 87767f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size. 87867f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes // Remember that the stack grows down (and is mapped in on demand), so the low address of the 87967f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes // region isn't very interesting. 88067f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size); 881642182341018b282148280a7bdb771493e15bd7dElliott Hughes 882642182341018b282148280a7bdb771493e15bd7dElliott Hughes // 88367f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes // What if RLIMIT_STACK is smaller than the stack's current extent? 884642182341018b282148280a7bdb771493e15bd7dElliott Hughes // 885642182341018b282148280a7bdb771493e15bd7dElliott Hughes rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already. 886642182341018b282148280a7bdb771493e15bd7dElliott Hughes rl.rlim_max = RLIM_INFINITY; 887642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 888642182341018b282148280a7bdb771493e15bd7dElliott Hughes 889642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 890642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 891642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 892642182341018b282148280a7bdb771493e15bd7dElliott Hughes 893642182341018b282148280a7bdb771493e15bd7dElliott Hughes EXPECT_EQ(stack_size, stack_size2); 894642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(1024U, stack_size); 895642182341018b282148280a7bdb771493e15bd7dElliott Hughes 896642182341018b282148280a7bdb771493e15bd7dElliott Hughes // 89767f1f3b171ecd5f68f51465bbe4b8c8440bb6b2eElliott Hughes // What if RLIMIT_STACK isn't a whole number of pages? 898642182341018b282148280a7bdb771493e15bd7dElliott Hughes // 899642182341018b282148280a7bdb771493e15bd7dElliott Hughes rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages. 900642182341018b282148280a7bdb771493e15bd7dElliott Hughes rl.rlim_max = RLIM_INFINITY; 901642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 902642182341018b282148280a7bdb771493e15bd7dElliott Hughes 903642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 904642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 905642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 906642182341018b282148280a7bdb771493e15bd7dElliott Hughes 907642182341018b282148280a7bdb771493e15bd7dElliott Hughes EXPECT_EQ(stack_size, stack_size2); 908642182341018b282148280a7bdb771493e15bd7dElliott Hughes ASSERT_EQ(6666U, stack_size); 909642182341018b282148280a7bdb771493e15bd7dElliott Hughes} 910