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> 25140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui#include <stdio.h> 2670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes#include <sys/mman.h> 2757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes#include <sys/syscall.h> 2851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath#include <time.h> 294d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes#include <unistd.h> 30bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes 3108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui#include <atomic> 32f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui#include <regex> 33b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#include <vector> 3408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 35f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui#include <base/file.h> 36f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui#include <base/stringprintf.h> 37f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui 3817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "private/bionic_macros.h" 3917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "private/ScopeGuard.h" 4017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "BionicDeathTest.h" 4117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "ScopedSignalHandler.h" 4217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 43f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cuiextern "C" pid_t gettid(); 44f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui 45bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott HughesTEST(pthread, pthread_key_create) { 46bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes pthread_key_t key; 47bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 48bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 49bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes // Can't delete a key that's already been deleted. 50bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(EINVAL, pthread_key_delete(key)); 51bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes} 524d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 53c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, pthread_keys_max) { 546c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // POSIX says PTHREAD_KEYS_MAX should be at least _POSIX_THREAD_KEYS_MAX. 556c238f2926e69a950f0671ae5519584c20d84196Yabin Cui ASSERT_GE(PTHREAD_KEYS_MAX, _POSIX_THREAD_KEYS_MAX); 56c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 57718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes 586c238f2926e69a950f0671ae5519584c20d84196Yabin CuiTEST(pthread, sysconf_SC_THREAD_KEYS_MAX_eq_PTHREAD_KEYS_MAX) { 59c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX); 606c238f2926e69a950f0671ae5519584c20d84196Yabin Cui ASSERT_EQ(sysconf_max, PTHREAD_KEYS_MAX); 61c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 621887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes 63c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, pthread_key_many_distinct) { 646c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // As gtest uses pthread keys, we can't allocate exactly PTHREAD_KEYS_MAX 656c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // pthread keys, but We should be able to allocate at least this many keys. 666c238f2926e69a950f0671ae5519584c20d84196Yabin Cui int nkeys = PTHREAD_KEYS_MAX / 2; 6744b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes std::vector<pthread_key_t> keys; 68c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 69c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert auto scope_guard = make_scope_guard([&keys]{ 70c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (auto key : keys) { 71c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, pthread_key_delete(key)); 72c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 73c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert }); 74c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 75c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (int i = 0; i < nkeys; ++i) { 7644b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes pthread_key_t key; 776170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes // If this fails, it's likely that LIBC_PTHREAD_KEY_RESERVED_COUNT is wrong. 78c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << nkeys; 7944b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes keys.push_back(key); 80c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void*>(i))); 8144b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 8244b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 83c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (int i = keys.size() - 1; i >= 0; --i) { 84c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(reinterpret_cast<void*>(i), pthread_getspecific(keys.back())); 85c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert pthread_key_t key = keys.back(); 86c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.pop_back(); 87c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 88c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 89c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 90c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 916c238f2926e69a950f0671ae5519584c20d84196Yabin CuiTEST(pthread, pthread_key_not_exceed_PTHREAD_KEYS_MAX) { 92c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert std::vector<pthread_key_t> keys; 93c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int rv = 0; 946c238f2926e69a950f0671ae5519584c20d84196Yabin Cui 956c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // Pthread keys are used by gtest, so PTHREAD_KEYS_MAX should 966c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // be more than we are allowed to allocate now. 976c238f2926e69a950f0671ae5519584c20d84196Yabin Cui for (int i = 0; i < PTHREAD_KEYS_MAX; i++) { 98c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert pthread_key_t key; 99c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert rv = pthread_key_create(&key, NULL); 100c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert if (rv == EAGAIN) { 101c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert break; 102c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 103c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, rv); 104c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.push_back(key); 105c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 106c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 107c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // Don't leak keys. 108c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (auto key : keys) { 109c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, pthread_key_delete(key)); 11044b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 111c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.clear(); 112c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 113c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // We should have eventually reached the maximum number of keys and received 114c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // EAGAIN. 115c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(EAGAIN, rv); 11644b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes} 11744b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 118ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott HughesTEST(pthread, pthread_key_delete) { 119ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes void* expected = reinterpret_cast<void*>(1234); 120ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes pthread_key_t key; 121ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 122ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 123ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 124ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 125ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // After deletion, pthread_getspecific returns NULL. 126ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(NULL, pthread_getspecific(key)); 127ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // And you can't use pthread_setspecific with the deleted key. 128ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(EINVAL, pthread_setspecific(key, expected)); 129ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes} 130ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes 13140a521744825b6060960c296d5fb3da4c6593d94Elliott HughesTEST(pthread, pthread_key_fork) { 13240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* expected = reinterpret_cast<void*>(1234); 13340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_key_t key; 13440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 13540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 13640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 13740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 13840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pid_t pid = fork(); 13940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_NE(-1, pid) << strerror(errno); 14040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 14140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes if (pid == 0) { 14240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes // The surviving thread inherits all the forking thread's TLS values... 14340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 14440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes _exit(99); 14540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes } 14640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 14740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes int status; 14840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(pid, waitpid(pid, &status, 0)); 14940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_TRUE(WIFEXITED(status)); 15040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(99, WEXITSTATUS(status)); 15140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 15240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 1531d53ae2a01df5c85d23b01e44880103e118712f3Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 15440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 15540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 15640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughesstatic void* DirtyKeyFn(void* key) { 15740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes return pthread_getspecific(*reinterpret_cast<pthread_key_t*>(key)); 15840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 15940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16040a521744825b6060960c296d5fb3da4c6593d94Elliott HughesTEST(pthread, pthread_key_dirty) { 16140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_key_t key; 16240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 16340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes size_t stack_size = 128 * 1024; 16540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 16640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_NE(MAP_FAILED, stack); 16740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes memset(stack, 0xff, stack_size); 16840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_attr_t attr; 17040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 17140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size)); 17240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 17340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_t t; 17440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &attr, DirtyKeyFn, &key)); 17540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 17640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* result; 17740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 17840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(nullptr, result); // Not ~0! 17940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 18040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 1811d53ae2a01df5c85d23b01e44880103e118712f3Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 18240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 18340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 1845ddbb3f936ee44555a46020239e49ab45109a806Yabin CuiTEST(pthread, static_pthread_key_used_before_creation) { 1855ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui#if defined(__BIONIC__) 1865ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui // See http://b/19625804. The bug is about a static/global pthread key being used before creation. 1875ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui // So here tests if the static/global default value 0 can be detected as invalid key. 1885ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui static pthread_key_t key; 1895ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui ASSERT_EQ(nullptr, pthread_getspecific(key)); 1905ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui ASSERT_EQ(EINVAL, pthread_setspecific(key, nullptr)); 1915ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui ASSERT_EQ(EINVAL, pthread_key_delete(key)); 1925ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui#else 1935ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui GTEST_LOG_(INFO) << "This test tests bionic pthread key implementation detail.\n"; 1945ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui#endif 1955ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui} 1965ddbb3f936ee44555a46020239e49ab45109a806Yabin Cui 1974d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* IdFn(void* arg) { 1984d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return arg; 1994d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2004d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 201634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cuiclass SpinFunctionHelper { 202634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui public: 203634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper() { 204634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper::spin_flag_ = true; 205634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 206634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ~SpinFunctionHelper() { 207634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui UnSpin(); 208634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 209634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui auto GetFunction() -> void* (*)(void*) { 210634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui return SpinFunctionHelper::SpinFn; 211634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 2124d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 213634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui void UnSpin() { 214634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper::spin_flag_ = false; 21510ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov } 216634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 217634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui private: 218634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui static void* SpinFn(void*) { 219634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui while (spin_flag_) {} 220634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui return NULL; 221634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 222634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui static volatile bool spin_flag_; 223634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui}; 224634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 225634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui// It doesn't matter if spin_flag_ is used in several tests, 226634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui// because it is always set to false after each test. Each thread 227634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui// loops on spin_flag_ can find it becomes false at some time. 228634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cuivolatile bool SpinFunctionHelper::spin_flag_ = false; 22910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2304d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* JoinFn(void* arg) { 2314d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL)); 2324d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2334d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 23410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikovstatic void AssertDetached(pthread_t t, bool is_detached) { 23510ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_t attr; 23610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_getattr_np(t, &attr)); 23710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov int detach_state; 23810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &detach_state)); 23910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_destroy(&attr); 24010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(is_detached, (detach_state == PTHREAD_CREATE_DETACHED)); 24110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov} 24210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2439d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughesstatic void MakeDeadThread(pthread_t& t) { 2449d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, NULL)); 24534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(0, pthread_join(t, NULL)); 2469d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 2479d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 2484d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_create) { 2494d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* expected_result = reinterpret_cast<void*>(123); 2504d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // Can we create a thread? 2514d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t; 2524d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, expected_result)); 2534d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If we join, do we get the expected value back? 2544d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* result; 2554d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 2564d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(expected_result, result); 2574d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2584d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2593e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_create_EAGAIN) { 2603e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_attr_t attributes; 2613e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 2623e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, static_cast<size_t>(-1) & ~(getpagesize() - 1))); 2633e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 2643e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_t t; 2653e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(EAGAIN, pthread_create(&t, &attributes, IdFn, NULL)); 2663e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 2673e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 2684d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_join_after_detach) { 269634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 270634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 2714d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 272634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 2734d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2744d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // After a pthread_detach... 2754d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 27610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, true); 2774d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2784d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // ...pthread_join should fail. 27934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 2804d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2814d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2824d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_op_detach_after_join) { 283634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 28410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2854d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 286634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 2874d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2884d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If thread 2 is already waiting to join thread 1... 2894d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t2; 2904d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 2914d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 29210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov sleep(1); // (Give t2 a chance to call pthread_join.) 29310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 294bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui#if defined(__BIONIC__) 295bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui ASSERT_EQ(EINVAL, pthread_detach(t1)); 296bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui#else 2974d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 298bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui#endif 29910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, false); 30010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 301634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui spinhelper.UnSpin(); 3024d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 30310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 3044d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* join_result; 3054d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t2, &join_result)); 3065b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 3074d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 30814f19592ae7c819855052bcebc79de87069c2954Elliott Hughes 30914f19592ae7c819855052bcebc79de87069c2954Elliott HughesTEST(pthread, pthread_join_self) { 31034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), NULL)); 31114f19592ae7c819855052bcebc79de87069c2954Elliott Hughes} 3124f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 313877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstruct TestBug37410 { 314877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t main_thread; 315877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_t mutex; 3164f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 317877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void main() { 318877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410 data; 319877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes data.main_thread = pthread_self(); 320877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_init(&data.mutex, NULL)); 321877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 322877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 323877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t t; 324877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, TestBug37410::thread_fn, reinterpret_cast<void*>(&data))); 325877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 326877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Wait for the thread to be running... 327877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 328877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&data.mutex)); 329877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 330877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // ...and exit. 331877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_exit(NULL); 332877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 333877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 334877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes private: 335877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void* thread_fn(void* arg) { 336877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410* data = reinterpret_cast<TestBug37410*>(arg); 337877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 338877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Let the main thread know we're running. 339877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_unlock(&data->mutex); 340877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 341877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // And wait for the main thread to exit. 342877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_join(data->main_thread, NULL); 343877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 344877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes return NULL; 345877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 346877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}; 3474f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 3487fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to 3497fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// run this test (which exits normally) in its own process. 3509df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 3519df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cuiclass pthread_DeathTest : public BionicDeathTest {}; 3529df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 3539df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin CuiTEST_F(pthread_DeathTest, pthread_bug_37410) { 3544f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes // http://code.google.com/p/android/issues/detail?id=37410 355877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EXIT(TestBug37410::main(), ::testing::ExitedWithCode(0), ""); 3564f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes} 357c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 358c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughesstatic void* SignalHandlerFn(void* arg) { 359c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t wait_set; 360c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigfillset(&wait_set); 361c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg))); 362c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 363c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 364c5d028fc913de84a781bd61084bf7ae2182fd48eElliott HughesTEST(pthread, pthread_sigmask) { 36519e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 isn't blocked. 36619e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t original_set; 36719e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&original_set); 36819e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &original_set)); 36919e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_FALSE(sigismember(&original_set, SIGUSR1)); 37019e62325c268a668692e2b65fde2284079f369aaElliott Hughes 371c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Block SIGUSR1. 372c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t set; 373c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigemptyset(&set); 374c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigaddset(&set, SIGUSR1); 375c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, NULL)); 376c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 37719e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 is blocked. 37819e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t final_set; 37919e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 38019e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &final_set)); 38119e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 38219e62325c268a668692e2b65fde2284079f369aaElliott Hughes // ...and that sigprocmask agrees with pthread_sigmask. 38319e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 38419e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, sigprocmask(SIG_BLOCK, NULL, &final_set)); 38519e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 38619e62325c268a668692e2b65fde2284079f369aaElliott Hughes 387c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Spawn a thread that calls sigwait and tells us what it received. 388c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_t signal_thread; 389c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes int received_signal = -1; 390c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal)); 391c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 392c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Send that thread SIGUSR1. 393c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_kill(signal_thread, SIGUSR1); 394c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 395c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // See what it got. 396c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes void* join_result; 397c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_join(signal_thread, &join_result)); 398c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(SIGUSR1, received_signal); 3995b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 40019e62325c268a668692e2b65fde2284079f369aaElliott Hughes 40119e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Restore the original signal mask. 40219e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL)); 403c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 4045e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes 4053e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__too_long) { 406d1aea30b2ade504550f7bb7996c808b9af1c415dElliott Hughes // The limit is 15 characters --- the kernel's buffer is 16, but includes a NUL. 407d1aea30b2ade504550f7bb7996c808b9af1c415dElliott Hughes ASSERT_EQ(0, pthread_setname_np(pthread_self(), "123456789012345")); 408d1aea30b2ade504550f7bb7996c808b9af1c415dElliott Hughes ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "1234567890123456")); 4093e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 4103e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 4113e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__self) { 4123e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_setname_np(pthread_self(), "short 1")); 4133e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 4143e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 4153e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__other) { 416634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 417634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 418ed29e858d09906bc28e79d919af1d09f0538a464Elliott Hughes pthread_t t1; 419634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 420ed29e858d09906bc28e79d919af1d09f0538a464Elliott Hughes ASSERT_EQ(0, pthread_setname_np(t1, "short 2")); 4213e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 4223e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 423220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_setname_np__no_such_thread) { 4249d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4259d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4263e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 4273e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes // Call pthread_setname_np after thread has already exited. 42868d98d832b7935ed5be23836c481a14f00b19ef1Elliott Hughes ASSERT_EQ(ENOENT, pthread_setname_np(dead_thread, "short 3")); 4293e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 4309d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4319d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__0) { 4329d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes // Signal 0 just tests that the thread exists, so it's safe to call on ourselves. 4339d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), 0)); 4349d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4359d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4369d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__invalid_signal) { 4379d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(EINVAL, pthread_kill(pthread_self(), -1)); 4389d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4399d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 440fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughesstatic void pthread_kill__in_signal_handler_helper(int signal_number) { 441fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes static int count = 0; 442fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(SIGALRM, signal_number); 443fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes if (++count == 1) { 444fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes // Can we call pthread_kill from a signal handler? 445fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 446fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes } 447fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 448fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 449fae89fc4042ee4c360842234dfda7831c313bd44Elliott HughesTEST(pthread, pthread_kill__in_signal_handler) { 4504b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes ScopedSignalHandler ssh(SIGALRM, pthread_kill__in_signal_handler_helper); 451fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 452fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 453fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 454220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_detach__no_such_thread) { 4559d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4569d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4579d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4589d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_detach(dead_thread)); 4599d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4609d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4619b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff HaoTEST(pthread, pthread_getcpuclockid__clock_gettime) { 462634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 463634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 4649b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao pthread_t t; 465634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t, NULL, spinhelper.GetFunction(), NULL)); 4669b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 4679b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao clockid_t c; 4689b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, pthread_getcpuclockid(t, &c)); 4699b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao timespec ts; 4709b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, clock_gettime(c, &ts)); 4719b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao} 4729b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 473220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_getcpuclockid__no_such_thread) { 4749d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4759d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4769d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4779d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes clockid_t c; 4789d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getcpuclockid(dead_thread, &c)); 4799d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4809d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 481220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_getschedparam__no_such_thread) { 4829d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4839d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4849d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4859d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy; 4869d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 4879d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getschedparam(dead_thread, &policy, ¶m)); 4889d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4899d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 490220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_setschedparam__no_such_thread) { 4919d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4929d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4939d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4949d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy = 0; 4959d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 4969d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_setschedparam(dead_thread, policy, ¶m)); 4979d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4989d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 499220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_join__no_such_thread) { 5009d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 5019d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 5029d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 50334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(ESRCH, pthread_join(dead_thread, NULL)); 5049d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 5059d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 506220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_kill__no_such_thread) { 5079d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 5089d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 5099d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 5109d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_kill(dead_thread, 0)); 5119d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 5120f020d18b138e24b1fe34074808e07ac412f35a4msg 5130f020d18b138e24b1fe34074808e07ac412f35a4msgTEST(pthread, pthread_join__multijoin) { 514634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 5150f020d18b138e24b1fe34074808e07ac412f35a4msg 5160f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t1; 517634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 5180f020d18b138e24b1fe34074808e07ac412f35a4msg 5190f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t2; 5200f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 5210f020d18b138e24b1fe34074808e07ac412f35a4msg 5220f020d18b138e24b1fe34074808e07ac412f35a4msg sleep(1); // (Give t2 a chance to call pthread_join.) 5230f020d18b138e24b1fe34074808e07ac412f35a4msg 5240f020d18b138e24b1fe34074808e07ac412f35a4msg // Multiple joins to the same thread should fail. 5250f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 5260f020d18b138e24b1fe34074808e07ac412f35a4msg 527634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui spinhelper.UnSpin(); 5280f020d18b138e24b1fe34074808e07ac412f35a4msg 5290f020d18b138e24b1fe34074808e07ac412f35a4msg // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 5300f020d18b138e24b1fe34074808e07ac412f35a4msg void* join_result; 5310f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_join(t2, &join_result)); 5325b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 5330f020d18b138e24b1fe34074808e07ac412f35a4msg} 534b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 53570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott HughesTEST(pthread, pthread_join__race) { 53670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // http://b/11693195 --- pthread_join could return before the thread had actually exited. 53770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // If the joiner unmapped the thread's stack, that could lead to SIGSEGV in the thread. 53870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes for (size_t i = 0; i < 1024; ++i) { 53970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes size_t stack_size = 64*1024; 54070b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); 54170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 54270b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_t a; 54370b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_init(&a); 54470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_setstack(&a, stack, stack_size); 54570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 54670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_t t; 54770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &a, IdFn, NULL)); 54870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_join(t, NULL)); 54970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 55070b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes } 55170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes} 55270b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 553b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualGuardSizeFn(void* arg) { 554b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 555b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 556b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getguardsize(&attributes, reinterpret_cast<size_t*>(arg)); 557b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 558b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 559b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 560b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualGuardSize(const pthread_attr_t& attributes) { 561b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 562b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 563b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualGuardSizeFn, &result); 56434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 565b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 566b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 567b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 568b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualStackSizeFn(void* arg) { 569b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 570b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 571b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getstacksize(&attributes, reinterpret_cast<size_t*>(arg)); 572b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 573b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 574b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 575b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualStackSize(const pthread_attr_t& attributes) { 576b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 577b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 578b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualStackSizeFn, &result); 57934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 580b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 581b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 582b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 583b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setguardsize) { 584b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 585b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 586b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 587b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default guard size. 588b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_guard_size; 589b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &default_guard_size)); 590b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 591b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // No such thing as too small: will be rounded up to one page by pthread_create. 592b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 128)); 593b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t guard_size; 594b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 595b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(128U, guard_size); 596b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(4096U, GetActualGuardSize(attributes)); 597b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 598b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough and a multiple of the page size. 599b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024)); 600b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 601b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, guard_size); 602b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 603b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 604b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024 + 1)); 605b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 606b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, guard_size); 607b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 608b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 609b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setstacksize) { 610b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 611b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 612b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 613b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default stack size. 614b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_stack_size; 615b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &default_stack_size)); 616b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 617b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Too small. 618b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(EINVAL, pthread_attr_setstacksize(&attributes, 128)); 619b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t stack_size; 620b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 621b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(default_stack_size, stack_size); 622b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_GE(GetActualStackSize(attributes), default_stack_size); 623b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 624917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui // Large enough and a multiple of the page size; may be rounded up by pthread_create. 625b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024)); 626b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 627b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, stack_size); 628917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_GE(GetActualStackSize(attributes), 32*1024U); 629b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 630917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui // Large enough but not aligned; will be rounded up by pthread_create. 631b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024 + 1)); 632b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 633b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, stack_size); 634f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) 635917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_GT(GetActualStackSize(attributes), 32*1024U + 1); 636f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 637b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // glibc rounds down, in violation of POSIX. They document this in their BUGS section. 638b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 639f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 640b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 641c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 64276615dae93c18ac890e167c547a08c0228709a33Yabin CuiTEST(pthread, pthread_rwlockattr_smoke) { 64376615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_rwlockattr_t attr; 64476615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_init(&attr)); 64576615dae93c18ac890e167c547a08c0228709a33Yabin Cui 64676615dae93c18ac890e167c547a08c0228709a33Yabin Cui int pshared_value_array[] = {PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED}; 64776615dae93c18ac890e167c547a08c0228709a33Yabin Cui for (size_t i = 0; i < sizeof(pshared_value_array) / sizeof(pshared_value_array[0]); ++i) { 64876615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_setpshared(&attr, pshared_value_array[i])); 64976615dae93c18ac890e167c547a08c0228709a33Yabin Cui int pshared; 65076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_getpshared(&attr, &pshared)); 65176615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(pshared_value_array[i], pshared); 65276615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 65376615dae93c18ac890e167c547a08c0228709a33Yabin Cui 65476615dae93c18ac890e167c547a08c0228709a33Yabin Cui int kind_array[] = {PTHREAD_RWLOCK_PREFER_READER_NP, 65576615dae93c18ac890e167c547a08c0228709a33Yabin Cui PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP}; 65676615dae93c18ac890e167c547a08c0228709a33Yabin Cui for (size_t i = 0; i < sizeof(kind_array) / sizeof(kind_array[0]); ++i) { 65776615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_setkind_np(&attr, kind_array[i])); 65876615dae93c18ac890e167c547a08c0228709a33Yabin Cui int kind; 65976615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_getkind_np(&attr, &kind)); 66076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(kind_array[i], kind); 66176615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 66276615dae93c18ac890e167c547a08c0228709a33Yabin Cui 66376615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_destroy(&attr)); 66476615dae93c18ac890e167c547a08c0228709a33Yabin Cui} 66576615dae93c18ac890e167c547a08c0228709a33Yabin Cui 66676615dae93c18ac890e167c547a08c0228709a33Yabin CuiTEST(pthread, pthread_rwlock_init_same_as_PTHREAD_RWLOCK_INITIALIZER) { 66776615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_rwlock_t lock1 = PTHREAD_RWLOCK_INITIALIZER; 66876615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_rwlock_t lock2; 66976615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_init(&lock2, NULL)); 67076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, memcmp(&lock1, &lock2, sizeof(lock1))); 67176615dae93c18ac890e167c547a08c0228709a33Yabin Cui} 67276615dae93c18ac890e167c547a08c0228709a33Yabin Cui 673c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_rwlock_smoke) { 674c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_rwlock_t l; 675c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_init(&l, NULL)); 676c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 67776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Single read lock 678c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 679c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 680c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 68176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Multiple read lock 68276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 68376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 68476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 68576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 68676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 68776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Write lock 68892687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 68992687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 69076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 69176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock 69276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_trywrlock(&l)); 69376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 69476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&l)); 69576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 69676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 69776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try reader lock 69876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 69976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 70076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 70176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 70276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 70376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 70476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock after unlock 70576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 70676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 70776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 70876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "read after write" 70976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 71076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_rdlock(&l)); 71176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 71276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 71376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "write after write" 714c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 71576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_wrlock(&l)); 716c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 717c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 718c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_destroy(&l)); 719c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 720c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 721f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cuistatic void WaitUntilThreadSleep(std::atomic<pid_t>& pid) { 722f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui while (pid == 0) { 723f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui usleep(1000); 724f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui } 725f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui std::string filename = android::base::StringPrintf("/proc/%d/stat", pid.load()); 726f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui std::regex regex {R"(\s+S\s+)"}; 727f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui 728f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui while (true) { 729f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui std::string content; 730f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui ASSERT_TRUE(android::base::ReadFileToString(filename, &content)); 731f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui if (std::regex_search(content, regex)) { 732f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui break; 733f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui } 734f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui usleep(1000); 735f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui } 736f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui} 737f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui 73808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cuistruct RwlockWakeupHelperArg { 73908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui pthread_rwlock_t lock; 74008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui enum Progress { 74108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_INITIALIZED, 74208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_WAITING, 74308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_RELEASED, 74408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_ACCESSED 74508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui }; 74608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui std::atomic<Progress> progress; 747f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui std::atomic<pid_t> tid; 74808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui}; 74908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 75008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cuistatic void pthread_rwlock_reader_wakeup_writer_helper(RwlockWakeupHelperArg* arg) { 751f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui arg->tid = gettid(); 75208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); 75308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_WAITING; 75408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 75508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&arg->lock)); 75608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_wrlock(&arg->lock)); 75708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress); 75808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock)); 75908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 76008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED; 76108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 76208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 76308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin CuiTEST(pthread, pthread_rwlock_reader_wakeup_writer) { 76408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui RwlockWakeupHelperArg wakeup_arg; 76508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL)); 76608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock)); 76708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED; 768f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui wakeup_arg.tid = 0; 76908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 77008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui pthread_t thread; 77108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 77208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui reinterpret_cast<void* (*)(void*)>(pthread_rwlock_reader_wakeup_writer_helper), &wakeup_arg)); 773f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui WaitUntilThreadSleep(wakeup_arg.tid); 774f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress); 775f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui 77608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED; 77708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock)); 77808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 77908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 78008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress); 78108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock)); 78208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 78308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 78408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cuistatic void pthread_rwlock_writer_wakeup_reader_helper(RwlockWakeupHelperArg* arg) { 785f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui arg->tid = gettid(); 78608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); 78708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_WAITING; 78808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 78908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&arg->lock)); 79008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(&arg->lock)); 79108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress); 79208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock)); 79308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 79408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED; 79508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 79608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 79708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin CuiTEST(pthread, pthread_rwlock_writer_wakeup_reader) { 79808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui RwlockWakeupHelperArg wakeup_arg; 79908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL)); 80008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock)); 80108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED; 802f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui wakeup_arg.tid = 0; 80308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 80408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui pthread_t thread; 80508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 80608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui reinterpret_cast<void* (*)(void*)>(pthread_rwlock_writer_wakeup_reader_helper), &wakeup_arg)); 807f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui WaitUntilThreadSleep(wakeup_arg.tid); 808f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress); 809f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui 81008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED; 81108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock)); 81208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 81308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 81408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress); 81508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock)); 81608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 81708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 81876615dae93c18ac890e167c547a08c0228709a33Yabin Cuiclass RwlockKindTestHelper { 81976615dae93c18ac890e167c547a08c0228709a33Yabin Cui private: 82076615dae93c18ac890e167c547a08c0228709a33Yabin Cui struct ThreadArg { 82176615dae93c18ac890e167c547a08c0228709a33Yabin Cui RwlockKindTestHelper* helper; 82276615dae93c18ac890e167c547a08c0228709a33Yabin Cui std::atomic<pid_t>& tid; 82376615dae93c18ac890e167c547a08c0228709a33Yabin Cui 82476615dae93c18ac890e167c547a08c0228709a33Yabin Cui ThreadArg(RwlockKindTestHelper* helper, std::atomic<pid_t>& tid) 82576615dae93c18ac890e167c547a08c0228709a33Yabin Cui : helper(helper), tid(tid) { } 82676615dae93c18ac890e167c547a08c0228709a33Yabin Cui }; 82776615dae93c18ac890e167c547a08c0228709a33Yabin Cui 82876615dae93c18ac890e167c547a08c0228709a33Yabin Cui public: 82976615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_rwlock_t lock; 83076615dae93c18ac890e167c547a08c0228709a33Yabin Cui 83176615dae93c18ac890e167c547a08c0228709a33Yabin Cui public: 83276615dae93c18ac890e167c547a08c0228709a33Yabin Cui RwlockKindTestHelper(int kind_type) { 83376615dae93c18ac890e167c547a08c0228709a33Yabin Cui InitRwlock(kind_type); 83476615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 83576615dae93c18ac890e167c547a08c0228709a33Yabin Cui 83676615dae93c18ac890e167c547a08c0228709a33Yabin Cui ~RwlockKindTestHelper() { 83776615dae93c18ac890e167c547a08c0228709a33Yabin Cui DestroyRwlock(); 83876615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 83976615dae93c18ac890e167c547a08c0228709a33Yabin Cui 84076615dae93c18ac890e167c547a08c0228709a33Yabin Cui void CreateWriterThread(pthread_t& thread, std::atomic<pid_t>& tid) { 84176615dae93c18ac890e167c547a08c0228709a33Yabin Cui tid = 0; 84276615dae93c18ac890e167c547a08c0228709a33Yabin Cui ThreadArg* arg = new ThreadArg(this, tid); 84376615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 84476615dae93c18ac890e167c547a08c0228709a33Yabin Cui reinterpret_cast<void* (*)(void*)>(WriterThreadFn), arg)); 84576615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 84676615dae93c18ac890e167c547a08c0228709a33Yabin Cui 84776615dae93c18ac890e167c547a08c0228709a33Yabin Cui void CreateReaderThread(pthread_t& thread, std::atomic<pid_t>& tid) { 84876615dae93c18ac890e167c547a08c0228709a33Yabin Cui tid = 0; 84976615dae93c18ac890e167c547a08c0228709a33Yabin Cui ThreadArg* arg = new ThreadArg(this, tid); 85076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 85176615dae93c18ac890e167c547a08c0228709a33Yabin Cui reinterpret_cast<void* (*)(void*)>(ReaderThreadFn), arg)); 85276615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 85376615dae93c18ac890e167c547a08c0228709a33Yabin Cui 85476615dae93c18ac890e167c547a08c0228709a33Yabin Cui private: 85576615dae93c18ac890e167c547a08c0228709a33Yabin Cui void InitRwlock(int kind_type) { 85676615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_rwlockattr_t attr; 85776615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_init(&attr)); 85876615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_setkind_np(&attr, kind_type)); 85976615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_init(&lock, &attr)); 86076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlockattr_destroy(&attr)); 86176615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 86276615dae93c18ac890e167c547a08c0228709a33Yabin Cui 86376615dae93c18ac890e167c547a08c0228709a33Yabin Cui void DestroyRwlock() { 86476615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_destroy(&lock)); 86576615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 86676615dae93c18ac890e167c547a08c0228709a33Yabin Cui 86776615dae93c18ac890e167c547a08c0228709a33Yabin Cui static void WriterThreadFn(ThreadArg* arg) { 86876615dae93c18ac890e167c547a08c0228709a33Yabin Cui arg->tid = gettid(); 86976615dae93c18ac890e167c547a08c0228709a33Yabin Cui 87076615dae93c18ac890e167c547a08c0228709a33Yabin Cui RwlockKindTestHelper* helper = arg->helper; 87176615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_wrlock(&helper->lock)); 87276615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&helper->lock)); 87376615dae93c18ac890e167c547a08c0228709a33Yabin Cui delete arg; 87476615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 87576615dae93c18ac890e167c547a08c0228709a33Yabin Cui 87676615dae93c18ac890e167c547a08c0228709a33Yabin Cui static void ReaderThreadFn(ThreadArg* arg) { 87776615dae93c18ac890e167c547a08c0228709a33Yabin Cui arg->tid = gettid(); 87876615dae93c18ac890e167c547a08c0228709a33Yabin Cui 87976615dae93c18ac890e167c547a08c0228709a33Yabin Cui RwlockKindTestHelper* helper = arg->helper; 88076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(&helper->lock)); 88176615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&helper->lock)); 88276615dae93c18ac890e167c547a08c0228709a33Yabin Cui delete arg; 88376615dae93c18ac890e167c547a08c0228709a33Yabin Cui } 88476615dae93c18ac890e167c547a08c0228709a33Yabin Cui}; 88576615dae93c18ac890e167c547a08c0228709a33Yabin Cui 88676615dae93c18ac890e167c547a08c0228709a33Yabin CuiTEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_READER_NP) { 88776615dae93c18ac890e167c547a08c0228709a33Yabin Cui RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_READER_NP); 88876615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock)); 88976615dae93c18ac890e167c547a08c0228709a33Yabin Cui 89076615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_t writer_thread; 89176615dae93c18ac890e167c547a08c0228709a33Yabin Cui std::atomic<pid_t> writer_tid; 89276615dae93c18ac890e167c547a08c0228709a33Yabin Cui helper.CreateWriterThread(writer_thread, writer_tid); 89376615dae93c18ac890e167c547a08c0228709a33Yabin Cui WaitUntilThreadSleep(writer_tid); 89476615dae93c18ac890e167c547a08c0228709a33Yabin Cui 89576615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_t reader_thread; 89676615dae93c18ac890e167c547a08c0228709a33Yabin Cui std::atomic<pid_t> reader_tid; 89776615dae93c18ac890e167c547a08c0228709a33Yabin Cui helper.CreateReaderThread(reader_thread, reader_tid); 89876615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_join(reader_thread, NULL)); 89976615dae93c18ac890e167c547a08c0228709a33Yabin Cui 90076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock)); 90176615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_join(writer_thread, NULL)); 90276615dae93c18ac890e167c547a08c0228709a33Yabin Cui} 90376615dae93c18ac890e167c547a08c0228709a33Yabin Cui 90476615dae93c18ac890e167c547a08c0228709a33Yabin CuiTEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) { 90576615dae93c18ac890e167c547a08c0228709a33Yabin Cui RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); 90676615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock)); 90776615dae93c18ac890e167c547a08c0228709a33Yabin Cui 90876615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_t writer_thread; 90976615dae93c18ac890e167c547a08c0228709a33Yabin Cui std::atomic<pid_t> writer_tid; 91076615dae93c18ac890e167c547a08c0228709a33Yabin Cui helper.CreateWriterThread(writer_thread, writer_tid); 91176615dae93c18ac890e167c547a08c0228709a33Yabin Cui WaitUntilThreadSleep(writer_tid); 91276615dae93c18ac890e167c547a08c0228709a33Yabin Cui 91376615dae93c18ac890e167c547a08c0228709a33Yabin Cui pthread_t reader_thread; 91476615dae93c18ac890e167c547a08c0228709a33Yabin Cui std::atomic<pid_t> reader_tid; 91576615dae93c18ac890e167c547a08c0228709a33Yabin Cui helper.CreateReaderThread(reader_thread, reader_tid); 91676615dae93c18ac890e167c547a08c0228709a33Yabin Cui WaitUntilThreadSleep(reader_tid); 91776615dae93c18ac890e167c547a08c0228709a33Yabin Cui 91876615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock)); 91976615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_join(writer_thread, NULL)); 92076615dae93c18ac890e167c547a08c0228709a33Yabin Cui ASSERT_EQ(0, pthread_join(reader_thread, NULL)); 92176615dae93c18ac890e167c547a08c0228709a33Yabin Cui} 92276615dae93c18ac890e167c547a08c0228709a33Yabin Cui 9231728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_once_fn_call_count = 0; 924c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughesstatic void OnceFn() { 9251728b2396591853345507a063ed6075dfd251706Elliott Hughes ++g_once_fn_call_count; 926c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 927c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 928c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_once_smoke) { 929c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_once_t once_control = PTHREAD_ONCE_INIT; 930c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 931c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 9321728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(1, g_once_fn_call_count); 933c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 934c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 9353694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic std::string pthread_once_1934122_result = ""; 9363694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 9373694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine2() { 9383694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "2"; 9393694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 9403694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 9413694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine1() { 9423694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_2 = PTHREAD_ONCE_INIT; 9433694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "1"; 9443694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once(&once_control_2, &Routine2); 9453694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 9463694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 9473694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott HughesTEST(pthread, pthread_once_1934122) { 9483694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // Very old versions of Android couldn't call pthread_once from a 9493694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // pthread_once init routine. http://b/1934122. 9503694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_1 = PTHREAD_ONCE_INIT; 9513694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ(0, pthread_once(&once_control_1, &Routine1)); 9523694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ("12", pthread_once_1934122_result); 9533694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 9543694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 9551728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_prepare_calls = 0; 956ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanovstatic void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 1; } 957ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanovstatic void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 2; } 9581728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_parent_calls = 0; 959ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanovstatic void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 1; } 960ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanovstatic void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 2; } 9611728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_child_calls = 0; 962ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanovstatic void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 1; } 963ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanovstatic void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 2; } 964c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 96500e37818a704fdd3d5f6a59022eff3a29b03bcceDmitriy IvanovTEST(pthread, pthread_atfork_smoke) { 966cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); 967cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); 968c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 969cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov int pid = fork(); 970cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_NE(-1, pid) << strerror(errno); 971c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 972cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov // Child and parent calls are made in the order they were registered. 973cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov if (pid == 0) { 974ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanov ASSERT_EQ(12, g_atfork_child_calls); 975cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov _exit(0); 976cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov } 977ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanov ASSERT_EQ(12, g_atfork_parent_calls); 978c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 979cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov // Prepare calls are made in the reverse order. 980ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanov ASSERT_EQ(21, g_atfork_prepare_calls); 981ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanov int status; 982ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanov ASSERT_EQ(pid, waitpid(pid, &status, 0)); 983ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanov} 984ea295f68f1fae7c701baaa717f67296659d567acDmitriy Ivanov 985c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_attr_getscope) { 986c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_attr_t attr; 987c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 988c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 989c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes int scope; 990c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_getscope(&attr, &scope)); 991c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(PTHREAD_SCOPE_SYSTEM, scope); 992c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 99351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 99451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_init) { 99551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 99651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 99751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 99851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 99951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 100051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 100151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 100251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 100351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 100451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared); 100551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 100651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 100751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_setclock) { 100851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 100951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 101051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 101151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_REALTIME)); 101251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 101351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 101451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 101551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 101651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 101751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 101851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 101951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 102051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(EINVAL, pthread_condattr_setclock(&attr, CLOCK_PROCESS_CPUTIME_ID)); 102151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 102251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 102351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_cond_broadcast__preserves_condattr_flags) { 102432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui#if defined(__BIONIC__) 102551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 102651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 102751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 102851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 102951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); 103051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 103151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_cond_t cond_var; 103251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_init(&cond_var, &attr)); 103351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 103451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_signal(&cond_var)); 103551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_broadcast(&cond_var)); 103651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 103732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui attr = static_cast<pthread_condattr_t>(*reinterpret_cast<uint32_t*>(cond_var.__private)); 103851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 103951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 104051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 104151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 104251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 104351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared); 104432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui#else // !defined(__BIONIC__) 104532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n"; 104632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui#endif // !defined(__BIONIC__) 104732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui} 104832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 104932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cuiclass pthread_CondWakeupTest : public ::testing::Test { 105032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui protected: 105132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_mutex_t mutex; 105232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_cond_t cond; 105332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 105432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui enum Progress { 105532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui INITIALIZED, 105632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui WAITING, 105732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui SIGNALED, 105832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui FINISHED, 105932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui }; 106032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui std::atomic<Progress> progress; 106132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_t thread; 106232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 106332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui protected: 106432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui virtual void SetUp() { 106532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_init(&mutex, NULL)); 106632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_cond_init(&cond, NULL)); 106732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui progress = INITIALIZED; 106832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, 106932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_create(&thread, NULL, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), this)); 107032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 107132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 107232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui virtual void TearDown() { 107332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 107432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(FINISHED, progress); 107532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_cond_destroy(&cond)); 107632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_destroy(&mutex)); 107732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 107832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 107932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui void SleepUntilProgress(Progress expected_progress) { 108032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui while (progress != expected_progress) { 108132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui usleep(5000); 108232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 108332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui usleep(5000); 108432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 108532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 108632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui private: 108732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui static void WaitThreadFn(pthread_CondWakeupTest* test) { 108832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_lock(&test->mutex)); 108932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui test->progress = WAITING; 109032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui while (test->progress == WAITING) { 109132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_cond_wait(&test->cond, &test->mutex)); 109232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 109332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(SIGNALED, test->progress); 109432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui test->progress = FINISHED; 109532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&test->mutex)); 109632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 109732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui}; 109832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 109932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin CuiTEST_F(pthread_CondWakeupTest, signal) { 110032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui SleepUntilProgress(WAITING); 110132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui progress = SIGNALED; 110232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_cond_signal(&cond); 110332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui} 110432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 110532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin CuiTEST_F(pthread_CondWakeupTest, broadcast) { 110632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui SleepUntilProgress(WAITING); 110732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui progress = SIGNALED; 110832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_cond_broadcast(&cond); 110951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 11100e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 11110e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott HughesTEST(pthread, pthread_mutex_timedlock) { 11120e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes pthread_mutex_t m; 11130e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_init(&m, NULL)); 11140e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 11150e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is already locked, pthread_mutex_timedlock should time out. 11160e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&m)); 11170e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 11180e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes timespec ts; 11190e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 11200e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 11210e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(ETIMEDOUT, pthread_mutex_timedlock(&m, &ts)); 11220e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 11230e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is unlocked, pthread_mutex_timedlock should succeed. 11240e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 11250e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 11260e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 11270e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 11280e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_timedlock(&m, &ts)); 11290e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 11300e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 11310e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_destroy(&m)); 11320e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes} 113357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 113457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott HughesTEST(pthread, pthread_attr_getstack__main_thread) { 113557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // This test is only meaningful for the main thread, so make sure we're running on it! 113657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(getpid(), syscall(__NR_gettid)); 113757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 113857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Get the main thread's attributes. 113957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes pthread_attr_t attributes; 114057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 114157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 114257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Check that we correctly report that the main thread has no guard page. 114357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t guard_size; 114457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 114557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0U, guard_size); // The main thread has no guard page. 114657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 114757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Get the stack base and the stack size (both ways). 114857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes void* stack_base; 114957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t stack_size; 115057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 115157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t stack_size2; 115257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 115357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 115457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // The two methods of asking for the stack size should agree. 115557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 115657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 115757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // What does /proc/self/maps' [stack] line say? 11589e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes void* maps_stack_hi = NULL; 115957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes FILE* fp = fopen("/proc/self/maps", "r"); 116057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_TRUE(fp != NULL); 116157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes char line[BUFSIZ]; 116257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes while (fgets(line, sizeof(line), fp) != NULL) { 116357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes uintptr_t lo, hi; 116457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes char name[10]; 116557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name); 116657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes if (strcmp(name, "[stack]") == 0) { 11679e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes maps_stack_hi = reinterpret_cast<void*>(hi); 116857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes break; 116957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes } 117057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes } 117157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes fclose(fp); 117257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 11739e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // The stack size should correspond to RLIMIT_STACK. 11749e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes rlimit rl; 11759e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl)); 117627a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes uint64_t original_rlim_cur = rl.rlim_cur; 117727a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes#if defined(__BIONIC__) 117827a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes if (rl.rlim_cur == RLIM_INFINITY) { 117927a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB. 118027a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes } 118127a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes#endif 11829e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes EXPECT_EQ(rl.rlim_cur, stack_size); 118357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 1184d9ff7226613014056c9edd79a68dc5af939107a0Dmitriy Ivanov auto guard = make_scope_guard([&rl, original_rlim_cur]() { 118527a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes rl.rlim_cur = original_rlim_cur; 118627a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 118727a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes }); 118827a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes 11899e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size. 11909e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // Remember that the stack grows down (and is mapped in on demand), so the low address of the 11919e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // region isn't very interesting. 11929e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size); 119357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 119457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 11959e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // What if RLIMIT_STACK is smaller than the stack's current extent? 119657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 119757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already. 119857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_max = RLIM_INFINITY; 119957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 120057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 120157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 120257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 120357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 120457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 120557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 120657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(1024U, stack_size); 120757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 120857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 12099e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // What if RLIMIT_STACK isn't a whole number of pages? 121057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 121157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages. 121257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_max = RLIM_INFINITY; 121357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 121457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 121557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 121657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 121757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 121857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 121957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 122057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(6666U, stack_size); 122157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes} 12228fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 1223917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cuistatic void pthread_attr_getstack_18908062_helper(void*) { 1224917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui char local_variable; 1225917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_attr_t attributes; 1226917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_getattr_np(pthread_self(), &attributes); 1227917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui void* stack_base; 1228917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui size_t stack_size; 1229917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_attr_getstack(&attributes, &stack_base, &stack_size); 1230917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui 1231917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui // Test whether &local_variable is in [stack_base, stack_base + stack_size). 1232917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_LE(reinterpret_cast<char*>(stack_base), &local_variable); 1233917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_LT(&local_variable, reinterpret_cast<char*>(stack_base) + stack_size); 1234917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui} 1235917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui 1236917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui// Check whether something on stack is in the range of 1237917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui// [stack_base, stack_base + stack_size). see b/18908062. 1238917d390510e442b9b030d54992ebf41cc1e7f853Yabin CuiTEST(pthread, pthread_attr_getstack_18908062) { 1239917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_t t; 1240917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_EQ(0, pthread_create(&t, NULL, 1241917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui reinterpret_cast<void* (*)(void*)>(pthread_attr_getstack_18908062_helper), 1242917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui NULL)); 1243917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_join(t, NULL); 1244917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui} 1245917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui 12468fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#if defined(__BIONIC__) 12478fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughesstatic void* pthread_gettid_np_helper(void* arg) { 12488fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes *reinterpret_cast<pid_t*>(arg) = gettid(); 12498fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes return NULL; 12508fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes} 12518fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#endif 12528fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 12538fb639ca9118a6522723d0bc09db59b432a803a9Elliott HughesTEST(pthread, pthread_gettid_np) { 12548fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#if defined(__BIONIC__) 12558fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes ASSERT_EQ(gettid(), pthread_gettid_np(pthread_self())); 12568fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 12578fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pid_t t_gettid_result; 12588fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pthread_t t; 12598fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pthread_create(&t, NULL, pthread_gettid_np_helper, &t_gettid_result); 12608fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 12618fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pid_t t_pthread_gettid_np_result = pthread_gettid_np(t); 12628fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 126334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 12648fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 12658fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result); 12668fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#else 12678fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes GTEST_LOG_(INFO) << "This test does nothing.\n"; 12688fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#endif 12698fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes} 127034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 127134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughesstatic size_t cleanup_counter = 0; 127234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 12734199695657e9500db14ab40392e3715db1826002Derek Xuestatic void AbortCleanupRoutine(void*) { 127434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes abort(); 127534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 127634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 12774199695657e9500db14ab40392e3715db1826002Derek Xuestatic void CountCleanupRoutine(void*) { 127834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ++cleanup_counter; 127934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 128034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 12814199695657e9500db14ab40392e3715db1826002Derek Xuestatic void PthreadCleanupTester() { 128234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(CountCleanupRoutine, NULL); 128334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(CountCleanupRoutine, NULL); 128434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(AbortCleanupRoutine, NULL); 128534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 128634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(0); // Pop the abort without executing it. 128734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(1); // Pop one count while executing it. 128834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(1U, cleanup_counter); 128934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes // Exit while the other count is still on the cleanup stack. 129034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_exit(NULL); 129134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 129234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes // Calls to pthread_cleanup_pop/pthread_cleanup_push must always be balanced. 129334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(0); 129434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 129534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 12964199695657e9500db14ab40392e3715db1826002Derek Xuestatic void* PthreadCleanupStartRoutine(void*) { 129734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes PthreadCleanupTester(); 129834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes return NULL; 129934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 130034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 130134c987a6dd6816eff98bc25f627659550c2338dcElliott HughesTEST(pthread, pthread_cleanup_push__pthread_cleanup_pop) { 130234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_t t; 130334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, PthreadCleanupStartRoutine, NULL)); 130434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 130534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(2U, cleanup_counter); 130634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 13074199695657e9500db14ab40392e3715db1826002Derek Xue 13084199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, PTHREAD_MUTEX_DEFAULT_is_PTHREAD_MUTEX_NORMAL) { 13094199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_DEFAULT); 13104199695657e9500db14ab40392e3715db1826002Derek Xue} 13114199695657e9500db14ab40392e3715db1826002Derek Xue 13124199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutexattr_gettype) { 13134199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutexattr_t attr; 13144199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 13154199695657e9500db14ab40392e3715db1826002Derek Xue 13164199695657e9500db14ab40392e3715db1826002Derek Xue int attr_type; 13174199695657e9500db14ab40392e3715db1826002Derek Xue 13184199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)); 13194199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 13204199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_NORMAL, attr_type); 13214199695657e9500db14ab40392e3715db1826002Derek Xue 13224199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); 13234199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 13244199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_ERRORCHECK, attr_type); 13254199695657e9500db14ab40392e3715db1826002Derek Xue 13264199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); 13274199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 13284199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_RECURSIVE, attr_type); 13295b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 13305b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(0, pthread_mutexattr_destroy(&attr)); 13314199695657e9500db14ab40392e3715db1826002Derek Xue} 13324199695657e9500db14ab40392e3715db1826002Derek Xue 133317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cuistruct PthreadMutex { 133417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock; 133517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 133617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex(int mutex_type) { 133717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui init(mutex_type); 133817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 133917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 134017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ~PthreadMutex() { 134117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui destroy(); 134217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 134317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 134417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui private: 134517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui void init(int mutex_type) { 134617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutexattr_t attr; 134717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 134817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutexattr_settype(&attr, mutex_type)); 134917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_init(&lock, &attr)); 135017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutexattr_destroy(&attr)); 135117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 135217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 135317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui void destroy() { 135417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_destroy(&lock)); 135517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 135617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 135717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui DISALLOW_COPY_AND_ASSIGN(PthreadMutex); 135817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui}; 13594199695657e9500db14ab40392e3715db1826002Derek Xue 13605b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_lock_NORMAL) { 136117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m(PTHREAD_MUTEX_NORMAL); 13624199695657e9500db14ab40392e3715db1826002Derek Xue 136317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 136417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 13654199695657e9500db14ab40392e3715db1826002Derek Xue} 13664199695657e9500db14ab40392e3715db1826002Derek Xue 13674199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutex_lock_ERRORCHECK) { 136817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m(PTHREAD_MUTEX_ERRORCHECK); 13694199695657e9500db14ab40392e3715db1826002Derek Xue 137017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 137117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EDEADLK, pthread_mutex_lock(&m.lock)); 137217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 137317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_trylock(&m.lock)); 137417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock)); 137517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 137617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock)); 13774199695657e9500db14ab40392e3715db1826002Derek Xue} 13784199695657e9500db14ab40392e3715db1826002Derek Xue 13794199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutex_lock_RECURSIVE) { 138017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m(PTHREAD_MUTEX_RECURSIVE); 13814199695657e9500db14ab40392e3715db1826002Derek Xue 138217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 138317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 138417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 138517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 138617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_trylock(&m.lock)); 138717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 138817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock)); 138917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui} 139017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 139117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin CuiTEST(pthread, pthread_mutex_init_same_as_static_initializers) { 139217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock_normal = PTHREAD_MUTEX_INITIALIZER; 139317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m1(PTHREAD_MUTEX_NORMAL); 139417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, memcmp(&lock_normal, &m1.lock, sizeof(pthread_mutex_t))); 139517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_destroy(&lock_normal); 139617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 139717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock_errorcheck = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; 139817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m2(PTHREAD_MUTEX_ERRORCHECK); 139917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, memcmp(&lock_errorcheck, &m2.lock, sizeof(pthread_mutex_t))); 140017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_destroy(&lock_errorcheck); 140117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 140217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock_recursive = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 140317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m3(PTHREAD_MUTEX_RECURSIVE); 140417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t))); 140517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive)); 14064199695657e9500db14ab40392e3715db1826002Derek Xue} 14075b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cuiclass MutexWakeupHelper { 14085b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui private: 140917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m; 14105b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui enum Progress { 14115b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_INITIALIZED, 14125b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_WAITING, 14135b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_RELEASED, 14145b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_ACCESSED 14155b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui }; 14165b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui std::atomic<Progress> progress; 1417f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui std::atomic<pid_t> tid; 14185b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14195b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui static void thread_fn(MutexWakeupHelper* helper) { 1420f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui helper->tid = gettid(); 14215b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(LOCK_INITIALIZED, helper->progress); 14225b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui helper->progress = LOCK_WAITING; 14235b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 142417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&helper->m.lock)); 14255b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(LOCK_RELEASED, helper->progress); 142617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&helper->m.lock)); 14275b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14285b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui helper->progress = LOCK_ACCESSED; 14295b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui } 14305b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14315b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui public: 143217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper(int mutex_type) : m(mutex_type) { 143317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 143417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 143517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui void test() { 143617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 14375b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui progress = LOCK_INITIALIZED; 1438f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui tid = 0; 14395b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14405b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui pthread_t thread; 14415b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 14425b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui reinterpret_cast<void* (*)(void*)>(MutexWakeupHelper::thread_fn), this)); 14435b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 1444f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui WaitUntilThreadSleep(tid); 1445f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui ASSERT_EQ(LOCK_WAITING, progress); 1446f796985923e2d8308e00ed9567f36546dafb98d7Yabin Cui 14475b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui progress = LOCK_RELEASED; 144817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 14495b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14505b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 14515b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(LOCK_ACCESSED, progress); 14525b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui } 14535b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui}; 14545b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14555b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_NORMAL_wakeup) { 145617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper helper(PTHREAD_MUTEX_NORMAL); 145717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui helper.test(); 14585b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui} 14595b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14605b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_ERRORCHECK_wakeup) { 146117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper helper(PTHREAD_MUTEX_ERRORCHECK); 146217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui helper.test(); 14635b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui} 14645b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 14655b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_RECURSIVE_wakeup) { 146617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper helper(PTHREAD_MUTEX_RECURSIVE); 146717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui helper.test(); 14685b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui} 14695b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 1470140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin CuiTEST(pthread, pthread_mutex_owner_tid_limit) { 1471e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui#if defined(__BIONIC__) && !defined(__LP64__) 1472140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui FILE* fp = fopen("/proc/sys/kernel/pid_max", "r"); 1473140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui ASSERT_TRUE(fp != NULL); 1474140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui long pid_max; 1475140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui ASSERT_EQ(1, fscanf(fp, "%ld", &pid_max)); 1476140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui fclose(fp); 1477e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui // Bionic's pthread_mutex implementation on 32-bit devices uses 16 bits to represent owner tid. 1478140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui ASSERT_LE(pid_max, 65536); 1479e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui#else 1480e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui GTEST_LOG_(INFO) << "This test does nothing as 32-bit tid is supported by pthread_mutex.\n"; 1481e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui#endif 1482140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui} 1483b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1484b58457221364eaad039c2c49a42626b725e980d5Yabin Cuiclass StrictAlignmentAllocator { 1485b58457221364eaad039c2c49a42626b725e980d5Yabin Cui public: 1486b58457221364eaad039c2c49a42626b725e980d5Yabin Cui void* allocate(size_t size, size_t alignment) { 1487b58457221364eaad039c2c49a42626b725e980d5Yabin Cui char* p = new char[size + alignment * 2]; 1488b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocated_array.push_back(p); 1489b58457221364eaad039c2c49a42626b725e980d5Yabin Cui while (!is_strict_aligned(p, alignment)) { 1490b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ++p; 1491b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1492b58457221364eaad039c2c49a42626b725e980d5Yabin Cui return p; 1493b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1494b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1495b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ~StrictAlignmentAllocator() { 1496b58457221364eaad039c2c49a42626b725e980d5Yabin Cui for (auto& p : allocated_array) { 1497b58457221364eaad039c2c49a42626b725e980d5Yabin Cui delete [] p; 1498b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1499b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1500b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1501b58457221364eaad039c2c49a42626b725e980d5Yabin Cui private: 1502b58457221364eaad039c2c49a42626b725e980d5Yabin Cui bool is_strict_aligned(char* p, size_t alignment) { 1503b58457221364eaad039c2c49a42626b725e980d5Yabin Cui return (reinterpret_cast<uintptr_t>(p) % (alignment * 2)) == alignment; 1504b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1505b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1506b58457221364eaad039c2c49a42626b725e980d5Yabin Cui std::vector<char*> allocated_array; 1507b58457221364eaad039c2c49a42626b725e980d5Yabin Cui}; 1508b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1509b58457221364eaad039c2c49a42626b725e980d5Yabin CuiTEST(pthread, pthread_types_allow_four_bytes_alignment) { 1510b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#if defined(__BIONIC__) 1511b58457221364eaad039c2c49a42626b725e980d5Yabin Cui // For binary compatibility with old version, we need to allow 4-byte aligned data for pthread types. 1512b58457221364eaad039c2c49a42626b725e980d5Yabin Cui StrictAlignmentAllocator allocator; 1513b58457221364eaad039c2c49a42626b725e980d5Yabin Cui pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>( 1514b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocator.allocate(sizeof(pthread_mutex_t), 4)); 1515b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_init(mutex, NULL)); 1516b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_lock(mutex)); 1517b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_unlock(mutex)); 1518b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_destroy(mutex)); 1519b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1520b58457221364eaad039c2c49a42626b725e980d5Yabin Cui pthread_cond_t* cond = reinterpret_cast<pthread_cond_t*>( 1521b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocator.allocate(sizeof(pthread_cond_t), 4)); 1522b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_init(cond, NULL)); 1523b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_signal(cond)); 1524b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_broadcast(cond)); 1525b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_destroy(cond)); 1526b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1527b58457221364eaad039c2c49a42626b725e980d5Yabin Cui pthread_rwlock_t* rwlock = reinterpret_cast<pthread_rwlock_t*>( 1528b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocator.allocate(sizeof(pthread_rwlock_t), 4)); 1529b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_init(rwlock, NULL)); 1530b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(rwlock)); 1531b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(rwlock)); 1532b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_wrlock(rwlock)); 1533b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(rwlock)); 1534b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_destroy(rwlock)); 1535b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1536b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#else 1537b58457221364eaad039c2c49a42626b725e980d5Yabin Cui GTEST_LOG_(INFO) << "This test tests bionic implementation details."; 1538b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#endif 1539b58457221364eaad039c2c49a42626b725e980d5Yabin Cui} 1540511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris 1541511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher FerrisTEST(pthread, pthread_mutex_lock_null_32) { 1542511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#if defined(__BIONIC__) && !defined(__LP64__) 1543511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris ASSERT_EQ(EINVAL, pthread_mutex_lock(NULL)); 1544511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#else 1545511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices."; 1546511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#endif 1547511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris} 1548511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris 1549511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher FerrisTEST(pthread, pthread_mutex_unlock_null_32) { 1550511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#if defined(__BIONIC__) && !defined(__LP64__) 1551511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris ASSERT_EQ(EINVAL, pthread_mutex_unlock(NULL)); 1552511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#else 1553511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices."; 1554511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#endif 1555511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris} 1556511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris 1557511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher FerrisTEST_F(pthread_DeathTest, pthread_mutex_lock_null_64) { 1558511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#if defined(__BIONIC__) && defined(__LP64__) 1559511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris pthread_mutex_t* null_value = nullptr; 1560511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris ASSERT_EXIT(pthread_mutex_lock(null_value), testing::KilledBySignal(SIGSEGV), ""); 1561511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#else 1562511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices."; 1563511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#endif 1564511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris} 1565511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris 1566511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher FerrisTEST_F(pthread_DeathTest, pthread_mutex_unlock_null_64) { 1567511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#if defined(__BIONIC__) && defined(__LP64__) 1568511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris pthread_mutex_t* null_value = nullptr; 1569511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris ASSERT_EXIT(pthread_mutex_unlock(null_value), testing::KilledBySignal(SIGSEGV), ""); 1570511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#else 1571511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices."; 1572511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris#endif 1573511cfd9dc8cb41bca4920687c7d816ee916ee8e5Christopher Ferris} 1574