pthread_test.cpp revision 68d98d832b7935ed5be23836c481a14f00b19ef1
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 199df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui#include "private/ScopeGuard.h" 209df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui#include "BionicDeathTest.h" 219df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui#include "ScopedSignalHandler.h" 229df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 23bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <errno.h> 245b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes#include <inttypes.h> 25b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes#include <limits.h> 2604620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes#include <malloc.h> 27bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes#include <pthread.h> 28f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#include <signal.h> 2970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes#include <sys/mman.h> 3057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes#include <sys/syscall.h> 3151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#include <time.h> 324d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes#include <unistd.h> 33bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 344b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes 35bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott HughesTEST(pthread, pthread_key_create) { 36bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes pthread_key_t key; 37bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 38bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 39bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes // Can't delete a key that's already been deleted. 40bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(EINVAL, pthread_key_delete(key)); 41bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes} 424d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 43c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, pthread_keys_max) { 441887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes // POSIX says PTHREAD_KEYS_MAX should be at least 128. 451887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes ASSERT_GE(PTHREAD_KEYS_MAX, 128); 46c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 47718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes 48c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, _SC_THREAD_KEYS_MAX_big_enough_for_POSIX) { 491887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes // sysconf shouldn't return a smaller value. 50c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX); 51718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes ASSERT_GE(sysconf_max, PTHREAD_KEYS_MAX); 52c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 531887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes 54c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, pthread_key_many_distinct) { 55c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // We should be able to allocate at least this many keys. 56c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int nkeys = sysconf(_SC_THREAD_KEYS_MAX) / 2; 5744b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes std::vector<pthread_key_t> keys; 58c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 59c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert auto scope_guard = make_scope_guard([&keys]{ 60c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (auto key : keys) { 61c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, pthread_key_delete(key)); 62c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 63c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert }); 64c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 65c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (int i = 0; i < nkeys; ++i) { 6644b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes pthread_key_t key; 67c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is 68c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // wrong. 69c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << nkeys; 7044b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes keys.push_back(key); 71c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void*>(i))); 7244b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 7344b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 74c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (int i = keys.size() - 1; i >= 0; --i) { 75c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(reinterpret_cast<void*>(i), pthread_getspecific(keys.back())); 76c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert pthread_key_t key = keys.back(); 77c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.pop_back(); 78c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 79c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 80c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 81c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 82c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, pthread_key_EAGAIN) { 83c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX); 8444b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 85c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert std::vector<pthread_key_t> keys; 86c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int rv = 0; 87c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // Two keys are used by gtest, so sysconf_max should be more than we are 88c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // allowed to allocate now. 89c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (int i = 0; i < sysconf_max; i++) { 90c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert pthread_key_t key; 91c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert rv = pthread_key_create(&key, NULL); 92c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert if (rv == EAGAIN) { 93c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert break; 94c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 95c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, rv); 96c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.push_back(key); 97c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 98c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 99c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // Don't leak keys. 100c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (auto key : keys) { 101c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, pthread_key_delete(key)); 10244b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 103c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.clear(); 104c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 105c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // We should have eventually reached the maximum number of keys and received 106c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // EAGAIN. 107c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(EAGAIN, rv); 10844b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes} 10944b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 110ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott HughesTEST(pthread, pthread_key_delete) { 111ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes void* expected = reinterpret_cast<void*>(1234); 112ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes pthread_key_t key; 113ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 114ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 115ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 116ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 117ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // After deletion, pthread_getspecific returns NULL. 118ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(NULL, pthread_getspecific(key)); 119ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // And you can't use pthread_setspecific with the deleted key. 120ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(EINVAL, pthread_setspecific(key, expected)); 121ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes} 122ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes 12340a521744825b6060960c296d5fb3da4c6593d94Elliott HughesTEST(pthread, pthread_key_fork) { 12440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* expected = reinterpret_cast<void*>(1234); 12540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_key_t key; 12640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 12740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 12840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 12940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 13040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pid_t pid = fork(); 13140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_NE(-1, pid) << strerror(errno); 13240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 13340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes if (pid == 0) { 13440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes // The surviving thread inherits all the forking thread's TLS values... 13540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 13640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes _exit(99); 13740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes } 13840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 13940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes int status; 14040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(pid, waitpid(pid, &status, 0)); 14140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_TRUE(WIFEXITED(status)); 14240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(99, WEXITSTATUS(status)); 14340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 14440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 1451d53ae2a01df5c85d23b01e44880103e118712f3Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 14640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 14740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 14840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughesstatic void* DirtyKeyFn(void* key) { 14940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes return pthread_getspecific(*reinterpret_cast<pthread_key_t*>(key)); 15040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 15140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 15240a521744825b6060960c296d5fb3da4c6593d94Elliott HughesTEST(pthread, pthread_key_dirty) { 15340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_key_t key; 15440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 15540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 15640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes size_t stack_size = 128 * 1024; 15740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 15840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_NE(MAP_FAILED, stack); 15940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes memset(stack, 0xff, stack_size); 16040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_attr_t attr; 16240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 16340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size)); 16440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_t t; 16640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &attr, DirtyKeyFn, &key)); 16740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* result; 16940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 17040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(nullptr, result); // Not ~0! 17140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 17240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 1731d53ae2a01df5c85d23b01e44880103e118712f3Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 17440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 17540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 1764d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* IdFn(void* arg) { 1774d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return arg; 1784d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1794d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 1804d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* SleepFn(void* arg) { 1815b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes sleep(reinterpret_cast<uintptr_t>(arg)); 1824d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return NULL; 1834d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1844d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 18510ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikovstatic void* SpinFn(void* arg) { 18610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov volatile bool* b = reinterpret_cast<volatile bool*>(arg); 18710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov while (!*b) { 18810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov } 18910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov return NULL; 19010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov} 19110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 1924d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* JoinFn(void* arg) { 1934d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL)); 1944d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1954d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 19610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikovstatic void AssertDetached(pthread_t t, bool is_detached) { 19710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_t attr; 19810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_getattr_np(t, &attr)); 19910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov int detach_state; 20010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &detach_state)); 20110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_destroy(&attr); 20210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(is_detached, (detach_state == PTHREAD_CREATE_DETACHED)); 20310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov} 20410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2059d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughesstatic void MakeDeadThread(pthread_t& t) { 2069d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, NULL)); 20734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(0, pthread_join(t, NULL)); 2089d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 2099d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 2104d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_create) { 2114d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* expected_result = reinterpret_cast<void*>(123); 2124d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // Can we create a thread? 2134d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t; 2144d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, expected_result)); 2154d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If we join, do we get the expected value back? 2164d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* result; 2174d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 2184d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(expected_result, result); 2194d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2204d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2213e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_create_EAGAIN) { 2223e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_attr_t attributes; 2233e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 2243e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, static_cast<size_t>(-1) & ~(getpagesize() - 1))); 2253e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 2263e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_t t; 2273e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(EAGAIN, pthread_create(&t, &attributes, IdFn, NULL)); 2283e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 2293e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 2304d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_join_after_detach) { 2314d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 2324d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); 2334d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2344d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // After a pthread_detach... 2354d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 23610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, true); 2374d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2384d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // ...pthread_join should fail. 23934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 2404d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2414d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2424d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_op_detach_after_join) { 24310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov bool done = false; 24410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2454d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 24610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done)); 2474d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2484d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If thread 2 is already waiting to join thread 1... 2494d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t2; 2504d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 2514d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 25210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov sleep(1); // (Give t2 a chance to call pthread_join.) 25310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 25410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov // ...a call to pthread_detach on thread 1 will "succeed" (silently fail)... 2554d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 25610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, false); 25710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 25810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov done = true; 2594d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 26010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 2614d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* join_result; 2624d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t2, &join_result)); 2635b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 2644d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 26514f19592ae7c819855052bcebc79de87069c2954Elliott Hughes 26614f19592ae7c819855052bcebc79de87069c2954Elliott HughesTEST(pthread, pthread_join_self) { 26734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), NULL)); 26814f19592ae7c819855052bcebc79de87069c2954Elliott Hughes} 2694f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 270877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstruct TestBug37410 { 271877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t main_thread; 272877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_t mutex; 2734f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 274877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void main() { 275877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410 data; 276877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes data.main_thread = pthread_self(); 277877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_init(&data.mutex, NULL)); 278877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 279877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 280877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t t; 281877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, TestBug37410::thread_fn, reinterpret_cast<void*>(&data))); 282877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 283877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Wait for the thread to be running... 284877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 285877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&data.mutex)); 286877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 287877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // ...and exit. 288877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_exit(NULL); 289877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 290877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 291877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes private: 292877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void* thread_fn(void* arg) { 293877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410* data = reinterpret_cast<TestBug37410*>(arg); 294877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 295877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Let the main thread know we're running. 296877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_unlock(&data->mutex); 297877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 298877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // And wait for the main thread to exit. 299877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_join(data->main_thread, NULL); 300877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 301877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes return NULL; 302877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 303877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}; 3044f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 3057fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to 3067fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// run this test (which exits normally) in its own process. 3079df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 3089df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cuiclass pthread_DeathTest : public BionicDeathTest {}; 3099df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 3109df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin CuiTEST_F(pthread_DeathTest, pthread_bug_37410) { 3114f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes // http://code.google.com/p/android/issues/detail?id=37410 312877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EXIT(TestBug37410::main(), ::testing::ExitedWithCode(0), ""); 3134f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes} 314c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 315c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughesstatic void* SignalHandlerFn(void* arg) { 316c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t wait_set; 317c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigfillset(&wait_set); 318c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg))); 319c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 320c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 321c5d028fc913de84a781bd61084bf7ae2182fd48eElliott HughesTEST(pthread, pthread_sigmask) { 32219e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 isn't blocked. 32319e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t original_set; 32419e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&original_set); 32519e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &original_set)); 32619e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_FALSE(sigismember(&original_set, SIGUSR1)); 32719e62325c268a668692e2b65fde2284079f369aaElliott Hughes 328c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Block SIGUSR1. 329c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t set; 330c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigemptyset(&set); 331c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigaddset(&set, SIGUSR1); 332c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, NULL)); 333c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 33419e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 is blocked. 33519e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t final_set; 33619e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 33719e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &final_set)); 33819e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 33919e62325c268a668692e2b65fde2284079f369aaElliott Hughes // ...and that sigprocmask agrees with pthread_sigmask. 34019e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 34119e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, sigprocmask(SIG_BLOCK, NULL, &final_set)); 34219e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 34319e62325c268a668692e2b65fde2284079f369aaElliott Hughes 344c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Spawn a thread that calls sigwait and tells us what it received. 345c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_t signal_thread; 346c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes int received_signal = -1; 347c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal)); 348c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 349c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Send that thread SIGUSR1. 350c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_kill(signal_thread, SIGUSR1); 351c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 352c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // See what it got. 353c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes void* join_result; 354c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_join(signal_thread, &join_result)); 355c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(SIGUSR1, received_signal); 3565b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 35719e62325c268a668692e2b65fde2284079f369aaElliott Hughes 35819e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Restore the original signal mask. 35919e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL)); 360c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 3615e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes 3623e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__too_long) { 3633e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "this name is far too long for linux")); 3643e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3653e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3663e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__self) { 3673e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_setname_np(pthread_self(), "short 1")); 3683e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3693e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3703e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__other) { 371ed29e858d09906bc28e79d919af1d09f0538a464Elliott Hughes pthread_t t1; 372ed29e858d09906bc28e79d919af1d09f0538a464Elliott Hughes ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5))); 373ed29e858d09906bc28e79d919af1d09f0538a464Elliott Hughes ASSERT_EQ(0, pthread_setname_np(t1, "short 2")); 3743e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3753e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3763e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__no_such_thread) { 3779d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 3789d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 3793e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3803e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes // Call pthread_setname_np after thread has already exited. 38168d98d832b7935ed5be23836c481a14f00b19ef1Elliott Hughes ASSERT_EQ(ENOENT, pthread_setname_np(dead_thread, "short 3")); 3823e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3839d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 3849d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__0) { 3859d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes // Signal 0 just tests that the thread exists, so it's safe to call on ourselves. 3869d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), 0)); 3879d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 3889d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 3899d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__invalid_signal) { 3909d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(EINVAL, pthread_kill(pthread_self(), -1)); 3919d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 3929d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 393fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughesstatic void pthread_kill__in_signal_handler_helper(int signal_number) { 394fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes static int count = 0; 395fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(SIGALRM, signal_number); 396fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes if (++count == 1) { 397fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes // Can we call pthread_kill from a signal handler? 398fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 399fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes } 400fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 401fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 402fae89fc4042ee4c360842234dfda7831c313bd44Elliott HughesTEST(pthread, pthread_kill__in_signal_handler) { 4034b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes ScopedSignalHandler ssh(SIGALRM, pthread_kill__in_signal_handler_helper); 404fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 405fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 406fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 4079d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_detach__no_such_thread) { 4089d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4099d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4109d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4119d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_detach(dead_thread)); 4129d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4139d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 41404620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott HughesTEST(pthread, pthread_detach__leak) { 415e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris size_t initial_bytes = 0; 416e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // Run this loop more than once since the first loop causes some memory 417e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // to be allocated permenantly. Run an extra loop to help catch any subtle 418e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // memory leaks. 419e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris for (size_t loop = 0; loop < 3; loop++) { 420e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // Set the initial bytes on the second loop since the memory in use 421e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // should have stabilized. 422e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris if (loop == 1) { 423e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris initial_bytes = mallinfo().uordblks; 424e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris } 425e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 426e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris pthread_attr_t attr; 427e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_attr_init(&attr)); 428e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); 429e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 430e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris std::vector<pthread_t> threads; 431e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris for (size_t i = 0; i < 32; ++i) { 432e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris pthread_t t; 433e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL)); 434e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris threads.push_back(t); 435e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris } 436e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 437e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris sleep(1); 438e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 439e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris for (size_t i = 0; i < 32; ++i) { 440e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_detach(threads[i])) << i; 441e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris } 44204620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes } 44304620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 44404620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes size_t final_bytes = mallinfo().uordblks; 44504620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes int leaked_bytes = (final_bytes - initial_bytes); 44604620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 44704620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes // User code (like this test) doesn't know how large pthread_internal_t is. 44804620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes // We can be pretty sure it's more than 128 bytes. 44904620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes ASSERT_LT(leaked_bytes, 32 /*threads*/ * 128 /*bytes*/); 45004620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes} 45104620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 4529b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff HaoTEST(pthread, pthread_getcpuclockid__clock_gettime) { 4539b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao pthread_t t; 4549b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, pthread_create(&t, NULL, SleepFn, reinterpret_cast<void*>(5))); 4559b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 4569b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao clockid_t c; 4579b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, pthread_getcpuclockid(t, &c)); 4589b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao timespec ts; 4599b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, clock_gettime(c, &ts)); 4609b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao} 4619b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 4629d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_getcpuclockid__no_such_thread) { 4639d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4649d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4659d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4669d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes clockid_t c; 4679d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getcpuclockid(dead_thread, &c)); 4689d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4699d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4709d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_getschedparam__no_such_thread) { 4719d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4729d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4739d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4749d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy; 4759d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 4769d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getschedparam(dead_thread, &policy, ¶m)); 4779d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4789d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4799d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_setschedparam__no_such_thread) { 4809d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4819d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4829d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4839d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy = 0; 4849d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 4859d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_setschedparam(dead_thread, policy, ¶m)); 4869d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4879d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4889d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_join__no_such_thread) { 4899d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4909d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4919d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 49234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(ESRCH, pthread_join(dead_thread, NULL)); 4939d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4949d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4959d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__no_such_thread) { 4969d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4979d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4989d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4999d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_kill(dead_thread, 0)); 5009d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 5010f020d18b138e24b1fe34074808e07ac412f35a4msg 5020f020d18b138e24b1fe34074808e07ac412f35a4msgTEST(pthread, pthread_join__multijoin) { 5030f020d18b138e24b1fe34074808e07ac412f35a4msg bool done = false; 5040f020d18b138e24b1fe34074808e07ac412f35a4msg 5050f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t1; 5060f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done)); 5070f020d18b138e24b1fe34074808e07ac412f35a4msg 5080f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t2; 5090f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 5100f020d18b138e24b1fe34074808e07ac412f35a4msg 5110f020d18b138e24b1fe34074808e07ac412f35a4msg sleep(1); // (Give t2 a chance to call pthread_join.) 5120f020d18b138e24b1fe34074808e07ac412f35a4msg 5130f020d18b138e24b1fe34074808e07ac412f35a4msg // Multiple joins to the same thread should fail. 5140f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 5150f020d18b138e24b1fe34074808e07ac412f35a4msg 5160f020d18b138e24b1fe34074808e07ac412f35a4msg done = true; 5170f020d18b138e24b1fe34074808e07ac412f35a4msg 5180f020d18b138e24b1fe34074808e07ac412f35a4msg // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 5190f020d18b138e24b1fe34074808e07ac412f35a4msg void* join_result; 5200f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_join(t2, &join_result)); 5215b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 5220f020d18b138e24b1fe34074808e07ac412f35a4msg} 523b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 52470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott HughesTEST(pthread, pthread_join__race) { 52570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // http://b/11693195 --- pthread_join could return before the thread had actually exited. 52670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // If the joiner unmapped the thread's stack, that could lead to SIGSEGV in the thread. 52770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes for (size_t i = 0; i < 1024; ++i) { 52870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes size_t stack_size = 64*1024; 52970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); 53070b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 53170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_t a; 53270b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_init(&a); 53370b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_setstack(&a, stack, stack_size); 53470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 53570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_t t; 53670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &a, IdFn, NULL)); 53770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_join(t, NULL)); 53870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 53970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes } 54070b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes} 54170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 542b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualGuardSizeFn(void* arg) { 543b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 544b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 545b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getguardsize(&attributes, reinterpret_cast<size_t*>(arg)); 546b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 547b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 548b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 549b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualGuardSize(const pthread_attr_t& attributes) { 550b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 551b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 552b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualGuardSizeFn, &result); 55334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 554b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 555b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 556b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 557b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualStackSizeFn(void* arg) { 558b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 559b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 560b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getstacksize(&attributes, reinterpret_cast<size_t*>(arg)); 561b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 562b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 563b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 564b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualStackSize(const pthread_attr_t& attributes) { 565b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 566b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 567b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualStackSizeFn, &result); 56834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 569b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 570b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 571b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 572b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setguardsize) { 573b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 574b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 575b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 576b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default guard size. 577b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_guard_size; 578b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &default_guard_size)); 579b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 580b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // No such thing as too small: will be rounded up to one page by pthread_create. 581b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 128)); 582b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t guard_size; 583b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 584b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(128U, guard_size); 585b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(4096U, GetActualGuardSize(attributes)); 586b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 587b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough and a multiple of the page size. 588b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024)); 589b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 590b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, guard_size); 591b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 592b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 593b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024 + 1)); 594b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 595b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, guard_size); 596b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 597b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 598b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setstacksize) { 599b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 600b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 601b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 602b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default stack size. 603b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_stack_size; 604b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &default_stack_size)); 605b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 606b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Too small. 607b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(EINVAL, pthread_attr_setstacksize(&attributes, 128)); 608b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t stack_size; 609b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 610b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(default_stack_size, stack_size); 611b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_GE(GetActualStackSize(attributes), default_stack_size); 612b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 613b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough and a multiple of the page size. 614b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024)); 615b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 616b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, stack_size); 617b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 618b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 619b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 620b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024 + 1)); 621b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 622b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, stack_size); 623f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) 624b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Bionic rounds up, which is what POSIX allows. 625b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), (32 + 4)*1024U); 626f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 627b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // glibc rounds down, in violation of POSIX. They document this in their BUGS section. 628b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 629f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 630b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 631c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 632c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_rwlock_smoke) { 633c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_rwlock_t l; 634c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_init(&l, NULL)); 635c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 63676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Single read lock 637c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 638c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 639c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 64076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Multiple read lock 64176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 64276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 64376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 64476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 64576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 64676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Write lock 64792687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 64892687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 64976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 65076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock 65176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_trywrlock(&l)); 65276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 65376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&l)); 65476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 65576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 65676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try reader lock 65776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 65876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 65976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 66076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 66176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 66276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 66376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock after unlock 66476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 66576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 66676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 66776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle#ifdef __BIONIC__ 66876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "read after write" 66976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 67076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_rdlock(&l)); 67176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 67276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 67376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "write after write" 674c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 67576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_wrlock(&l)); 676c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 67776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle#endif 678c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 679c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_destroy(&l)); 680c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 681c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 6821728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_once_fn_call_count = 0; 683c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughesstatic void OnceFn() { 6841728b2396591853345507a063ed6075dfd251706Elliott Hughes ++g_once_fn_call_count; 685c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 686c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 687c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_once_smoke) { 688c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_once_t once_control = PTHREAD_ONCE_INIT; 689c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 690c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 6911728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(1, g_once_fn_call_count); 692c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 693c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 6943694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic std::string pthread_once_1934122_result = ""; 6953694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 6963694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine2() { 6973694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "2"; 6983694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 6993694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 7003694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine1() { 7013694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_2 = PTHREAD_ONCE_INIT; 7023694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "1"; 7033694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once(&once_control_2, &Routine2); 7043694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 7053694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 7063694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott HughesTEST(pthread, pthread_once_1934122) { 7073694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // Very old versions of Android couldn't call pthread_once from a 7083694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // pthread_once init routine. http://b/1934122. 7093694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_1 = PTHREAD_ONCE_INIT; 7103694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ(0, pthread_once(&once_control_1, &Routine1)); 7113694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ("12", pthread_once_1934122_result); 7123694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 7133694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 7141728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_prepare_calls = 0; 7151728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls << 4) | 1; } 7161728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls << 4) | 2; } 7171728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_parent_calls = 0; 7181728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls << 4) | 1; } 7191728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls << 4) | 2; } 7201728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_child_calls = 0; 7211728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls << 4) | 1; } 7221728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls << 4) | 2; } 723c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 724c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_atfork) { 725c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); 726c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); 727c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 728c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes int pid = fork(); 729c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_NE(-1, pid) << strerror(errno); 730c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 731c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes // Child and parent calls are made in the order they were registered. 732c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes if (pid == 0) { 7331728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(0x12, g_atfork_child_calls); 734c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes _exit(0); 735c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes } 7361728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(0x12, g_atfork_parent_calls); 737c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 738c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes // Prepare calls are made in the reverse order. 7391728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(0x21, g_atfork_prepare_calls); 740c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 741c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 742c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_attr_getscope) { 743c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_attr_t attr; 744c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 745c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 746c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes int scope; 747c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_getscope(&attr, &scope)); 748c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(PTHREAD_SCOPE_SYSTEM, scope); 749c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 75051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 75151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_init) { 75251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 75351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 75451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 75551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 75651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 75751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 75851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 75951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 76051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 76151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared); 76251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 76351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 76451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_setclock) { 76551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 76651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 76751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 76851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_REALTIME)); 76951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 77051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 77151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 77251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 77351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 77451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 77551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 77651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 77751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(EINVAL, pthread_condattr_setclock(&attr, CLOCK_PROCESS_CPUTIME_ID)); 77851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 77951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 78051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_cond_broadcast__preserves_condattr_flags) { 78151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#if defined(__BIONIC__) // This tests a bionic implementation detail. 78251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 78351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 78451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 78551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 78651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); 78751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 78851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_cond_t cond_var; 78951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_init(&cond_var, &attr)); 79051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 79151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_signal(&cond_var)); 79251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_broadcast(&cond_var)); 79351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 79451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath attr = static_cast<pthread_condattr_t>(cond_var.value); 79551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 79651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 79751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 79851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 79951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 80051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared); 80151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#else // __BIONIC__ 80251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath GTEST_LOG_(INFO) << "This test does nothing.\n"; 80351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#endif // __BIONIC__ 80451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 8050e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8060e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott HughesTEST(pthread, pthread_mutex_timedlock) { 8070e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes pthread_mutex_t m; 8080e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_init(&m, NULL)); 8090e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8100e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is already locked, pthread_mutex_timedlock should time out. 8110e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&m)); 8120e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8130e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes timespec ts; 8140e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 8150e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 8160e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(ETIMEDOUT, pthread_mutex_timedlock(&m, &ts)); 8170e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8180e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is unlocked, pthread_mutex_timedlock should succeed. 8190e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 8200e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8210e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 8220e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 8230e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_timedlock(&m, &ts)); 8240e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 8250e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 8260e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_destroy(&m)); 8270e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes} 82857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 82957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott HughesTEST(pthread, pthread_attr_getstack__main_thread) { 83057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // This test is only meaningful for the main thread, so make sure we're running on it! 83157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(getpid(), syscall(__NR_gettid)); 83257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 83357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Get the main thread's attributes. 83457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes pthread_attr_t attributes; 83557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 83657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 83757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Check that we correctly report that the main thread has no guard page. 83857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t guard_size; 83957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 84057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0U, guard_size); // The main thread has no guard page. 84157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 84257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Get the stack base and the stack size (both ways). 84357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes void* stack_base; 84457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t stack_size; 84557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 84657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t stack_size2; 84757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 84857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 84957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // The two methods of asking for the stack size should agree. 85057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 85157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 85257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // What does /proc/self/maps' [stack] line say? 8539e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes void* maps_stack_hi = NULL; 85457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes FILE* fp = fopen("/proc/self/maps", "r"); 85557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_TRUE(fp != NULL); 85657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes char line[BUFSIZ]; 85757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes while (fgets(line, sizeof(line), fp) != NULL) { 85857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes uintptr_t lo, hi; 85957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes char name[10]; 86057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name); 86157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes if (strcmp(name, "[stack]") == 0) { 8629e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes maps_stack_hi = reinterpret_cast<void*>(hi); 86357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes break; 86457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes } 86557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes } 86657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes fclose(fp); 86757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 8689e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // The stack size should correspond to RLIMIT_STACK. 8699e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes rlimit rl; 8709e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl)); 87127a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes uint64_t original_rlim_cur = rl.rlim_cur; 87227a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes#if defined(__BIONIC__) 87327a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes if (rl.rlim_cur == RLIM_INFINITY) { 87427a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB. 87527a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes } 87627a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes#endif 8779e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes EXPECT_EQ(rl.rlim_cur, stack_size); 87857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 879d9ff7226613014056c9edd79a68dc5af939107a0Dmitriy Ivanov auto guard = make_scope_guard([&rl, original_rlim_cur]() { 88027a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes rl.rlim_cur = original_rlim_cur; 88127a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 88227a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes }); 88327a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes 8849e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size. 8859e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // Remember that the stack grows down (and is mapped in on demand), so the low address of the 8869e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // region isn't very interesting. 8879e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size); 88857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 88957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 8909e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // What if RLIMIT_STACK is smaller than the stack's current extent? 89157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 89257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already. 89357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_max = RLIM_INFINITY; 89457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 89557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 89657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 89757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 89857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 89957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 90057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 90157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(1024U, stack_size); 90257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 90357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 9049e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // What if RLIMIT_STACK isn't a whole number of pages? 90557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 90657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages. 90757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_max = RLIM_INFINITY; 90857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 90957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 91057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 91157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 91257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 91357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 91457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 91557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(6666U, stack_size); 91657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes} 9178fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 9188fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#if defined(__BIONIC__) 9198fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughesstatic void* pthread_gettid_np_helper(void* arg) { 9208fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes *reinterpret_cast<pid_t*>(arg) = gettid(); 9218fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes return NULL; 9228fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes} 9238fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#endif 9248fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 9258fb639ca9118a6522723d0bc09db59b432a803a9Elliott HughesTEST(pthread, pthread_gettid_np) { 9268fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#if defined(__BIONIC__) 9278fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes ASSERT_EQ(gettid(), pthread_gettid_np(pthread_self())); 9288fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 9298fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pid_t t_gettid_result; 9308fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pthread_t t; 9318fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pthread_create(&t, NULL, pthread_gettid_np_helper, &t_gettid_result); 9328fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 9338fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pid_t t_pthread_gettid_np_result = pthread_gettid_np(t); 9348fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 93534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 9368fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 9378fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result); 9388fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#else 9398fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes GTEST_LOG_(INFO) << "This test does nothing.\n"; 9408fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#endif 9418fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes} 94234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 94334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughesstatic size_t cleanup_counter = 0; 94434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 9454199695657e9500db14ab40392e3715db1826002Derek Xuestatic void AbortCleanupRoutine(void*) { 94634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes abort(); 94734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 94834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 9494199695657e9500db14ab40392e3715db1826002Derek Xuestatic void CountCleanupRoutine(void*) { 95034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ++cleanup_counter; 95134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 95234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 9534199695657e9500db14ab40392e3715db1826002Derek Xuestatic void PthreadCleanupTester() { 95434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(CountCleanupRoutine, NULL); 95534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(CountCleanupRoutine, NULL); 95634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(AbortCleanupRoutine, NULL); 95734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 95834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(0); // Pop the abort without executing it. 95934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(1); // Pop one count while executing it. 96034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(1U, cleanup_counter); 96134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes // Exit while the other count is still on the cleanup stack. 96234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_exit(NULL); 96334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 96434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes // Calls to pthread_cleanup_pop/pthread_cleanup_push must always be balanced. 96534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(0); 96634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 96734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 9684199695657e9500db14ab40392e3715db1826002Derek Xuestatic void* PthreadCleanupStartRoutine(void*) { 96934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes PthreadCleanupTester(); 97034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes return NULL; 97134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 97234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 97334c987a6dd6816eff98bc25f627659550c2338dcElliott HughesTEST(pthread, pthread_cleanup_push__pthread_cleanup_pop) { 97434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_t t; 97534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, PthreadCleanupStartRoutine, NULL)); 97634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 97734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(2U, cleanup_counter); 97834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 9794199695657e9500db14ab40392e3715db1826002Derek Xue 9804199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, PTHREAD_MUTEX_DEFAULT_is_PTHREAD_MUTEX_NORMAL) { 9814199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_DEFAULT); 9824199695657e9500db14ab40392e3715db1826002Derek Xue} 9834199695657e9500db14ab40392e3715db1826002Derek Xue 9844199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutexattr_gettype) { 9854199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutexattr_t attr; 9864199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 9874199695657e9500db14ab40392e3715db1826002Derek Xue 9884199695657e9500db14ab40392e3715db1826002Derek Xue int attr_type; 9894199695657e9500db14ab40392e3715db1826002Derek Xue 9904199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)); 9914199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 9924199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_NORMAL, attr_type); 9934199695657e9500db14ab40392e3715db1826002Derek Xue 9944199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); 9954199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 9964199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_ERRORCHECK, attr_type); 9974199695657e9500db14ab40392e3715db1826002Derek Xue 9984199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); 9994199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 10004199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_RECURSIVE, attr_type); 10014199695657e9500db14ab40392e3715db1826002Derek Xue} 10024199695657e9500db14ab40392e3715db1826002Derek Xue 10034199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutex_lock_NORMAL) { 10044199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutexattr_t attr; 10054199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 10064199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)); 10074199695657e9500db14ab40392e3715db1826002Derek Xue 10084199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutex_t lock; 10094199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_init(&lock, &attr)); 10104199695657e9500db14ab40392e3715db1826002Derek Xue 10114199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_lock(&lock)); 10124199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_unlock(&lock)); 10134199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_destroy(&lock)); 10144199695657e9500db14ab40392e3715db1826002Derek Xue} 10154199695657e9500db14ab40392e3715db1826002Derek Xue 10164199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutex_lock_ERRORCHECK) { 10174199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutexattr_t attr; 10184199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 10194199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); 10204199695657e9500db14ab40392e3715db1826002Derek Xue 10214199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutex_t lock; 10224199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_init(&lock, &attr)); 10234199695657e9500db14ab40392e3715db1826002Derek Xue 10244199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_lock(&lock)); 10254199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(EDEADLK, pthread_mutex_lock(&lock)); 10264199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_unlock(&lock)); 10274199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_trylock(&lock)); 10284199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(EBUSY, pthread_mutex_trylock(&lock)); 10294199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_unlock(&lock)); 10304199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(EPERM, pthread_mutex_unlock(&lock)); 10314199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_destroy(&lock)); 10324199695657e9500db14ab40392e3715db1826002Derek Xue} 10334199695657e9500db14ab40392e3715db1826002Derek Xue 10344199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutex_lock_RECURSIVE) { 10354199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutexattr_t attr; 10364199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 10374199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); 10384199695657e9500db14ab40392e3715db1826002Derek Xue 10394199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutex_t lock; 10404199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_init(&lock, &attr)); 10414199695657e9500db14ab40392e3715db1826002Derek Xue 10424199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_lock(&lock)); 10434199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_lock(&lock)); 10444199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_unlock(&lock)); 10454199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_unlock(&lock)); 10464199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_trylock(&lock)); 10474199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_unlock(&lock)); 10484199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(EPERM, pthread_mutex_unlock(&lock)); 10494199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutex_destroy(&lock)); 10504199695657e9500db14ab40392e3715db1826002Derek Xue} 1051