pthread_test.cpp revision e69c24543db577d8b219ab74b0ba7566e0f13b38
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> 32b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#include <vector> 3308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 3417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "private/bionic_macros.h" 3517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "private/ScopeGuard.h" 3617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "BionicDeathTest.h" 3717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui#include "ScopedSignalHandler.h" 3817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 39bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott HughesTEST(pthread, pthread_key_create) { 40bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes pthread_key_t key; 41bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 42bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 43bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes // Can't delete a key that's already been deleted. 44bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes ASSERT_EQ(EINVAL, pthread_key_delete(key)); 45bfeab1bbe7e8d0c08b7e3f46aedab64e3b2bf706Elliott Hughes} 464d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 47c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, pthread_keys_max) { 486c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // POSIX says PTHREAD_KEYS_MAX should be at least _POSIX_THREAD_KEYS_MAX. 496c238f2926e69a950f0671ae5519584c20d84196Yabin Cui ASSERT_GE(PTHREAD_KEYS_MAX, _POSIX_THREAD_KEYS_MAX); 50c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 51718a5b5495ae7726aabd2f8a748da9f391d12b98Elliott Hughes 526c238f2926e69a950f0671ae5519584c20d84196Yabin CuiTEST(pthread, sysconf_SC_THREAD_KEYS_MAX_eq_PTHREAD_KEYS_MAX) { 53c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX); 546c238f2926e69a950f0671ae5519584c20d84196Yabin Cui ASSERT_EQ(sysconf_max, PTHREAD_KEYS_MAX); 55c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 561887621de8a48eece8a05f2400ddd783b9833147Elliott Hughes 57c4bcc75f094206f3a6af767a5f6033ad44253b70Dan AlbertTEST(pthread, pthread_key_many_distinct) { 586c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // As gtest uses pthread keys, we can't allocate exactly PTHREAD_KEYS_MAX 596c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // pthread keys, but We should be able to allocate at least this many keys. 606c238f2926e69a950f0671ae5519584c20d84196Yabin Cui int nkeys = PTHREAD_KEYS_MAX / 2; 6144b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes std::vector<pthread_key_t> keys; 62c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 63c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert auto scope_guard = make_scope_guard([&keys]{ 64c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (auto key : keys) { 65c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, pthread_key_delete(key)); 66c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 67c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert }); 68c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 69c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (int i = 0; i < nkeys; ++i) { 7044b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes pthread_key_t key; 71c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is 72c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // wrong. 73c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << nkeys; 7444b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes keys.push_back(key); 75c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void*>(i))); 7644b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 7744b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 78c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (int i = keys.size() - 1; i >= 0; --i) { 79c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(reinterpret_cast<void*>(i), pthread_getspecific(keys.back())); 80c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert pthread_key_t key = keys.back(); 81c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.pop_back(); 82c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 83c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 84c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert} 85c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 866c238f2926e69a950f0671ae5519584c20d84196Yabin CuiTEST(pthread, pthread_key_not_exceed_PTHREAD_KEYS_MAX) { 87c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert std::vector<pthread_key_t> keys; 88c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert int rv = 0; 896c238f2926e69a950f0671ae5519584c20d84196Yabin Cui 906c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // Pthread keys are used by gtest, so PTHREAD_KEYS_MAX should 916c238f2926e69a950f0671ae5519584c20d84196Yabin Cui // be more than we are allowed to allocate now. 926c238f2926e69a950f0671ae5519584c20d84196Yabin Cui for (int i = 0; i < PTHREAD_KEYS_MAX; i++) { 93c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert pthread_key_t key; 94c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert rv = pthread_key_create(&key, NULL); 95c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert if (rv == EAGAIN) { 96c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert break; 97c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 98c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, rv); 99c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.push_back(key); 100c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert } 101c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 102c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // Don't leak keys. 103c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert for (auto key : keys) { 104c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert EXPECT_EQ(0, pthread_key_delete(key)); 10544b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes } 106c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert keys.clear(); 107c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert 108c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // We should have eventually reached the maximum number of keys and received 109c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert // EAGAIN. 110c4bcc75f094206f3a6af767a5f6033ad44253b70Dan Albert ASSERT_EQ(EAGAIN, rv); 11144b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes} 11244b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 113ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott HughesTEST(pthread, pthread_key_delete) { 114ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes void* expected = reinterpret_cast<void*>(1234); 115ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes pthread_key_t key; 116ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 117ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 118ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 119ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(0, pthread_key_delete(key)); 120ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // After deletion, pthread_getspecific returns NULL. 121ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(NULL, pthread_getspecific(key)); 122ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes // And you can't use pthread_setspecific with the deleted key. 123ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes ASSERT_EQ(EINVAL, pthread_setspecific(key, expected)); 124ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes} 125ebb770f90d9a8d7f75a9d8b0e6a96ded96c617afElliott Hughes 12640a521744825b6060960c296d5fb3da4c6593d94Elliott HughesTEST(pthread, pthread_key_fork) { 12740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* expected = reinterpret_cast<void*>(1234); 12840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_key_t key; 12940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 13040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_setspecific(key, expected)); 13140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 13240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 13340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pid_t pid = fork(); 13440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_NE(-1, pid) << strerror(errno); 13540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 13640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes if (pid == 0) { 13740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes // The surviving thread inherits all the forking thread's TLS values... 13840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 13940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes _exit(99); 14040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes } 14140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 14240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes int status; 14340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(pid, waitpid(pid, &status, 0)); 14440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_TRUE(WIFEXITED(status)); 14540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(99, WEXITSTATUS(status)); 14640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 14740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(expected, pthread_getspecific(key)); 1481d53ae2a01df5c85d23b01e44880103e118712f3Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 14940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 15040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 15140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughesstatic void* DirtyKeyFn(void* key) { 15240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes return pthread_getspecific(*reinterpret_cast<pthread_key_t*>(key)); 15340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 15440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 15540a521744825b6060960c296d5fb3da4c6593d94Elliott HughesTEST(pthread, pthread_key_dirty) { 15640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_key_t key; 15740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_key_create(&key, NULL)); 15840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 15940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes size_t stack_size = 128 * 1024; 16040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 16140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_NE(MAP_FAILED, stack); 16240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes memset(stack, 0xff, stack_size); 16340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_attr_t attr; 16540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 16640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size)); 16740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 16840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes pthread_t t; 16940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &attr, DirtyKeyFn, &key)); 17040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 17140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes void* result; 17240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 17340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(nullptr, result); // Not ~0! 17440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 17540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 1761d53ae2a01df5c85d23b01e44880103e118712f3Dan Albert ASSERT_EQ(0, pthread_key_delete(key)); 17740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes} 17840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 1794d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* IdFn(void* arg) { 1804d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return arg; 1814d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 1824d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 183634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cuiclass SpinFunctionHelper { 184634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui public: 185634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper() { 186634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper::spin_flag_ = true; 187634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 188634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ~SpinFunctionHelper() { 189634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui UnSpin(); 190634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 191634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui auto GetFunction() -> void* (*)(void*) { 192634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui return SpinFunctionHelper::SpinFn; 193634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 1944d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 195634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui void UnSpin() { 196634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper::spin_flag_ = false; 19710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov } 198634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 199634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui private: 200634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui static void* SpinFn(void*) { 201634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui while (spin_flag_) {} 202634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui return NULL; 203634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui } 204634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui static volatile bool spin_flag_; 205634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui}; 206634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 207634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui// It doesn't matter if spin_flag_ is used in several tests, 208634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui// because it is always set to false after each test. Each thread 209634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui// loops on spin_flag_ can find it becomes false at some time. 210634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cuivolatile bool SpinFunctionHelper::spin_flag_ = false; 21110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2124d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughesstatic void* JoinFn(void* arg) { 2134d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL)); 2144d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2154d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 21610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikovstatic void AssertDetached(pthread_t t, bool is_detached) { 21710ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_t attr; 21810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_getattr_np(t, &attr)); 21910ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov int detach_state; 22010ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &detach_state)); 22110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov pthread_attr_destroy(&attr); 22210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov ASSERT_EQ(is_detached, (detach_state == PTHREAD_CREATE_DETACHED)); 22310ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov} 22410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2259d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughesstatic void MakeDeadThread(pthread_t& t) { 2269d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, NULL)); 22734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(0, pthread_join(t, NULL)); 2289d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 2299d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 2304d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_create) { 2314d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* expected_result = reinterpret_cast<void*>(123); 2324d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // Can we create a thread? 2334d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t; 2344d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, IdFn, expected_result)); 2354d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If we join, do we get the expected value back? 2364d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* result; 2374d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 2384d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(expected_result, result); 2394d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2404d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2413e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_create_EAGAIN) { 2423e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_attr_t attributes; 2433e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 2443e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, static_cast<size_t>(-1) & ~(getpagesize() - 1))); 2453e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 2463e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes pthread_t t; 2473e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(EAGAIN, pthread_create(&t, &attributes, IdFn, NULL)); 2483e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 2493e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 2504d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_join_after_detach) { 251634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 252634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 2534d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 254634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 2554d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2564d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // After a pthread_detach... 2574d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 25810ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, true); 2594d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2604d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // ...pthread_join should fail. 26134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 2624d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 2634d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2644d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott HughesTEST(pthread, pthread_no_op_detach_after_join) { 265634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 26610ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 2674d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t1; 268634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 2694d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 2704d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes // If thread 2 is already waiting to join thread 1... 2714d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes pthread_t t2; 2724d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 2734d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 27410ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov sleep(1); // (Give t2 a chance to call pthread_join.) 27510ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 276bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui#if defined(__BIONIC__) 277bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui ASSERT_EQ(EINVAL, pthread_detach(t1)); 278bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui#else 2794d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_detach(t1)); 280bbb0432a33787f1a627abb396fe343a7943ac7bcYabin Cui#endif 28110ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov AssertDetached(t1, false); 28210ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov 283634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui spinhelper.UnSpin(); 2844d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes 28510ce96944eaea4c459392952652fdb24742c9c29Sergey Melnikov // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 2864d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes void* join_result; 2874d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes ASSERT_EQ(0, pthread_join(t2, &join_result)); 2885b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 2894d014e15b44d3e8d1b0189bc9bb7b0d0685e5af8Elliott Hughes} 29014f19592ae7c819855052bcebc79de87069c2954Elliott Hughes 29114f19592ae7c819855052bcebc79de87069c2954Elliott HughesTEST(pthread, pthread_join_self) { 29234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), NULL)); 29314f19592ae7c819855052bcebc79de87069c2954Elliott Hughes} 2944f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 295877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstruct TestBug37410 { 296877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t main_thread; 297877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_t mutex; 2984f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 299877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void main() { 300877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410 data; 301877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes data.main_thread = pthread_self(); 302877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_init(&data.mutex, NULL)); 303877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 304877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 305877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_t t; 306877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, TestBug37410::thread_fn, reinterpret_cast<void*>(&data))); 307877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 308877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Wait for the thread to be running... 309877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&data.mutex)); 310877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&data.mutex)); 311877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 312877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // ...and exit. 313877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_exit(NULL); 314877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 315877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 316877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes private: 317877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes static void* thread_fn(void* arg) { 318877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes TestBug37410* data = reinterpret_cast<TestBug37410*>(arg); 319877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 320877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // Let the main thread know we're running. 321877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_mutex_unlock(&data->mutex); 322877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 323877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes // And wait for the main thread to exit. 324877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_join(data->main_thread, NULL); 325877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 326877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes return NULL; 327877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes } 328877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}; 3294f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes 3307fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to 3317fd803cdfa873c01138dcbd614ec92418169b1c2Elliott Hughes// run this test (which exits normally) in its own process. 3329df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 3339df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cuiclass pthread_DeathTest : public BionicDeathTest {}; 3349df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin Cui 3359df70403d95f5cfe6824e38a9a6c35f9b9bbc76aYabin CuiTEST_F(pthread_DeathTest, pthread_bug_37410) { 3364f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes // http://code.google.com/p/android/issues/detail?id=37410 337877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes ASSERT_EXIT(TestBug37410::main(), ::testing::ExitedWithCode(0), ""); 3384f251bee5d51228217c1bf4dfc9219f3058bd3edElliott Hughes} 339c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 340c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughesstatic void* SignalHandlerFn(void* arg) { 341c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t wait_set; 342c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigfillset(&wait_set); 343c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg))); 344c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 345c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 346c5d028fc913de84a781bd61084bf7ae2182fd48eElliott HughesTEST(pthread, pthread_sigmask) { 34719e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 isn't blocked. 34819e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t original_set; 34919e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&original_set); 35019e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &original_set)); 35119e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_FALSE(sigismember(&original_set, SIGUSR1)); 35219e62325c268a668692e2b65fde2284079f369aaElliott Hughes 353c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Block SIGUSR1. 354c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t set; 355c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigemptyset(&set); 356c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigaddset(&set, SIGUSR1); 357c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, NULL)); 358c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 35919e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Check that SIGUSR1 is blocked. 36019e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigset_t final_set; 36119e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 36219e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &final_set)); 36319e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 36419e62325c268a668692e2b65fde2284079f369aaElliott Hughes // ...and that sigprocmask agrees with pthread_sigmask. 36519e62325c268a668692e2b65fde2284079f369aaElliott Hughes sigemptyset(&final_set); 36619e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, sigprocmask(SIG_BLOCK, NULL, &final_set)); 36719e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_TRUE(sigismember(&final_set, SIGUSR1)); 36819e62325c268a668692e2b65fde2284079f369aaElliott Hughes 369c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Spawn a thread that calls sigwait and tells us what it received. 370c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_t signal_thread; 371c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes int received_signal = -1; 372c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal)); 373c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 374c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // Send that thread SIGUSR1. 375c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes pthread_kill(signal_thread, SIGUSR1); 376c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 377c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes // See what it got. 378c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes void* join_result; 379c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, pthread_join(signal_thread, &join_result)); 380c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(SIGUSR1, received_signal); 3815b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 38219e62325c268a668692e2b65fde2284079f369aaElliott Hughes 38319e62325c268a668692e2b65fde2284079f369aaElliott Hughes // Restore the original signal mask. 38419e62325c268a668692e2b65fde2284079f369aaElliott Hughes ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL)); 385c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 3865e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes 3873e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__too_long) { 3883e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "this name is far too long for linux")); 3893e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3903e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3913e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__self) { 3923e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes ASSERT_EQ(0, pthread_setname_np(pthread_self(), "short 1")); 3933e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 3943e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 3953e898476c7230b60a0f76968e64ff25f475b48c0Elliott HughesTEST(pthread, pthread_setname_np__other) { 396634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 397634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 398ed29e858d09906bc28e79d919af1d09f0538a464Elliott Hughes pthread_t t1; 399634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 400ed29e858d09906bc28e79d919af1d09f0538a464Elliott Hughes ASSERT_EQ(0, pthread_setname_np(t1, "short 2")); 4013e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 4023e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 403220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_setname_np__no_such_thread) { 4049d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4059d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4063e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 4073e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes // Call pthread_setname_np after thread has already exited. 40868d98d832b7935ed5be23836c481a14f00b19ef1Elliott Hughes ASSERT_EQ(ENOENT, pthread_setname_np(dead_thread, "short 3")); 4093e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes} 4109d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4119d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__0) { 4129d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes // Signal 0 just tests that the thread exists, so it's safe to call on ourselves. 4139d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), 0)); 4149d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4159d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4169d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott HughesTEST(pthread, pthread_kill__invalid_signal) { 4179d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(EINVAL, pthread_kill(pthread_self(), -1)); 4189d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4199d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 420fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughesstatic void pthread_kill__in_signal_handler_helper(int signal_number) { 421fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes static int count = 0; 422fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(SIGALRM, signal_number); 423fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes if (++count == 1) { 424fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes // Can we call pthread_kill from a signal handler? 425fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 426fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes } 427fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 428fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 429fae89fc4042ee4c360842234dfda7831c313bd44Elliott HughesTEST(pthread, pthread_kill__in_signal_handler) { 4304b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes ScopedSignalHandler ssh(SIGALRM, pthread_kill__in_signal_handler_helper); 431fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); 432fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 433fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 434220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_detach__no_such_thread) { 4359d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4369d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4379d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4389d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_detach(dead_thread)); 4399d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4409d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 44119e246dda6772ffc532b1762cd7870d6c3b01c12Yabin CuiTEST(pthread, pthread_detach_no_leak) { 442e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris size_t initial_bytes = 0; 443e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // Run this loop more than once since the first loop causes some memory 444e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // to be allocated permenantly. Run an extra loop to help catch any subtle 445e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // memory leaks. 446e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris for (size_t loop = 0; loop < 3; loop++) { 447e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // Set the initial bytes on the second loop since the memory in use 448e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris // should have stabilized. 449e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris if (loop == 1) { 450e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris initial_bytes = mallinfo().uordblks; 451e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris } 452e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 453e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris pthread_attr_t attr; 454e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_attr_init(&attr)); 455e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); 456e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 457e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris std::vector<pthread_t> threads; 458e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris for (size_t i = 0; i < 32; ++i) { 459e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris pthread_t t; 460e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL)); 461e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris threads.push_back(t); 462e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris } 463e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 464e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris sleep(1); 465e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris 466e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris for (size_t i = 0; i < 32; ++i) { 467e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris ASSERT_EQ(0, pthread_detach(threads[i])) << i; 468e380960813bbb6e05d820eb75885556a1c4bf6acChristopher Ferris } 46904620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes } 47004620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 47104620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes size_t final_bytes = mallinfo().uordblks; 47204620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes int leaked_bytes = (final_bytes - initial_bytes); 47304620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 47419e246dda6772ffc532b1762cd7870d6c3b01c12Yabin Cui ASSERT_EQ(0, leaked_bytes); 47504620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes} 47604620a3cd7bdea0d1b421c8772ba3f06839bbe9cElliott Hughes 4779b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff HaoTEST(pthread, pthread_getcpuclockid__clock_gettime) { 478634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 479634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 4809b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao pthread_t t; 481634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t, NULL, spinhelper.GetFunction(), NULL)); 4829b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 4839b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao clockid_t c; 4849b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, pthread_getcpuclockid(t, &c)); 4859b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao timespec ts; 4869b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao ASSERT_EQ(0, clock_gettime(c, &ts)); 4879b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao} 4889b06cc3c1b2c4e2b08582f3fc9393a05aa589766Jeff Hao 489220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_getcpuclockid__no_such_thread) { 4909d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4919d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 4929d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 4939d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes clockid_t c; 4949d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getcpuclockid(dead_thread, &c)); 4959d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 4969d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 497220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_getschedparam__no_such_thread) { 4989d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 4999d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 5009d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 5019d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy; 5029d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 5039d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_getschedparam(dead_thread, &policy, ¶m)); 5049d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 5059d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 506220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_setschedparam__no_such_thread) { 5079d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 5089d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 5099d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 5109d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes int policy = 0; 5119d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes sched_param param; 5129d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_setschedparam(dead_thread, policy, ¶m)); 5139d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 5149d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 515220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_join__no_such_thread) { 5169d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 5179d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 5189d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 51934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(ESRCH, pthread_join(dead_thread, NULL)); 5209d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 5219d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 522220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin CuiTEST(pthread, pthread_kill__no_such_thread) { 5239d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes pthread_t dead_thread; 5249d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes MakeDeadThread(dead_thread); 5259d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 5269d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes ASSERT_EQ(ESRCH, pthread_kill(dead_thread, 0)); 5279d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 5280f020d18b138e24b1fe34074808e07ac412f35a4msg 5290f020d18b138e24b1fe34074808e07ac412f35a4msgTEST(pthread, pthread_join__multijoin) { 530634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui SpinFunctionHelper spinhelper; 5310f020d18b138e24b1fe34074808e07ac412f35a4msg 5320f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t1; 533634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL)); 5340f020d18b138e24b1fe34074808e07ac412f35a4msg 5350f020d18b138e24b1fe34074808e07ac412f35a4msg pthread_t t2; 5360f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1))); 5370f020d18b138e24b1fe34074808e07ac412f35a4msg 5380f020d18b138e24b1fe34074808e07ac412f35a4msg sleep(1); // (Give t2 a chance to call pthread_join.) 5390f020d18b138e24b1fe34074808e07ac412f35a4msg 5400f020d18b138e24b1fe34074808e07ac412f35a4msg // Multiple joins to the same thread should fail. 5410f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(EINVAL, pthread_join(t1, NULL)); 5420f020d18b138e24b1fe34074808e07ac412f35a4msg 543634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui spinhelper.UnSpin(); 5440f020d18b138e24b1fe34074808e07ac412f35a4msg 5450f020d18b138e24b1fe34074808e07ac412f35a4msg // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes). 5460f020d18b138e24b1fe34074808e07ac412f35a4msg void* join_result; 5470f020d18b138e24b1fe34074808e07ac412f35a4msg ASSERT_EQ(0, pthread_join(t2, &join_result)); 5485b9310e502003e584bcb3a028ca3db7aa4d3f01bElliott Hughes ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result)); 5490f020d18b138e24b1fe34074808e07ac412f35a4msg} 550b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 55170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott HughesTEST(pthread, pthread_join__race) { 55270b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // http://b/11693195 --- pthread_join could return before the thread had actually exited. 55370b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes // If the joiner unmapped the thread's stack, that could lead to SIGSEGV in the thread. 55470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes for (size_t i = 0; i < 1024; ++i) { 55570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes size_t stack_size = 64*1024; 55670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); 55770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 55870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_t a; 55970b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_init(&a); 56070b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_attr_setstack(&a, stack, stack_size); 56170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 56270b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes pthread_t t; 56370b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_create(&t, &a, IdFn, NULL)); 56470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, pthread_join(t, NULL)); 56570b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes ASSERT_EQ(0, munmap(stack, stack_size)); 56670b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes } 56770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes} 56870b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes 569b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualGuardSizeFn(void* arg) { 570b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 571b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 572b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getguardsize(&attributes, reinterpret_cast<size_t*>(arg)); 573b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 574b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 575b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 576b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualGuardSize(const pthread_attr_t& attributes) { 577b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 578b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 579b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualGuardSizeFn, &result); 58034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 581b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 582b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 583b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 584b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic void* GetActualStackSizeFn(void* arg) { 585b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 586b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_getattr_np(pthread_self(), &attributes); 587b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_getstacksize(&attributes, reinterpret_cast<size_t*>(arg)); 588b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return NULL; 589b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 590b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 591b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughesstatic size_t GetActualStackSize(const pthread_attr_t& attributes) { 592b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t result; 593b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_t t; 594b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_create(&t, &attributes, GetActualStackSizeFn, &result); 59534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 596b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes return result; 597b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 598b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 599b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setguardsize) { 600b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 601b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 602b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 603b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default guard size. 604b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_guard_size; 605b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &default_guard_size)); 606b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 607b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // No such thing as too small: will be rounded up to one page by pthread_create. 608b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 128)); 609b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t guard_size; 610b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 611b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(128U, guard_size); 612b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(4096U, GetActualGuardSize(attributes)); 613b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 614b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough and a multiple of the page size. 615b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024)); 616b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 617b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, guard_size); 618b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 619b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Large enough but not a multiple of the page size; will be rounded up by pthread_create. 620b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024 + 1)); 621b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 622b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, guard_size); 623b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 624b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 625b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott HughesTEST(pthread, pthread_attr_setstacksize) { 626b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes pthread_attr_t attributes; 627b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_init(&attributes)); 628b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 629b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Get the default stack size. 630b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t default_stack_size; 631b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &default_stack_size)); 632b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 633b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // Too small. 634b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(EINVAL, pthread_attr_setstacksize(&attributes, 128)); 635b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes size_t stack_size; 636b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 637b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(default_stack_size, stack_size); 638b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_GE(GetActualStackSize(attributes), default_stack_size); 639b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 640917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui // Large enough and a multiple of the page size; may be rounded up by pthread_create. 641b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024)); 642b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 643b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U, stack_size); 644917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_GE(GetActualStackSize(attributes), 32*1024U); 645b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes 646917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui // Large enough but not aligned; will be rounded up by pthread_create. 647b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024 + 1)); 648b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); 649b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(32*1024U + 1, stack_size); 650f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(__BIONIC__) 651917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_GT(GetActualStackSize(attributes), 32*1024U + 1); 652f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else // __BIONIC__ 653b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes // glibc rounds down, in violation of POSIX. They document this in their BUGS section. 654b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); 655f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif // __BIONIC__ 656b95cf0d23a1db3b7c37bd98b0c86196796c9b029Elliott Hughes} 657c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 658c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_rwlock_smoke) { 659c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_rwlock_t l; 660c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_init(&l, NULL)); 661c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 66276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Single read lock 663c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 664c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 665c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 66676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Multiple read lock 66776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 66876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_rdlock(&l)); 66976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 67076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 67176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 67276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Write lock 67392687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 67492687e41bcf108957944dafa80a9bfda219bfb0fCalin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 67576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 67676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock 67776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_trywrlock(&l)); 67876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 67976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&l)); 68076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 68176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 68276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try reader lock 68376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 68476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l)); 68576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l)); 68676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 68776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 68876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 68976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // Try writer lock after unlock 69076f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 69176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 69276f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 69376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle#ifdef __BIONIC__ 69476f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "read after write" 69576f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 69676f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_rdlock(&l)); 69776f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 69876f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle 69976f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle // EDEADLK in "write after write" 700c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_wrlock(&l)); 70176f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle ASSERT_EQ(EDEADLK, pthread_rwlock_wrlock(&l)); 702c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_unlock(&l)); 70376f352eec12d8938101e5ae33429c72797c3aa23Calin Juravle#endif 704c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 705c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_rwlock_destroy(&l)); 706c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 707c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 70808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cuistruct RwlockWakeupHelperArg { 70908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui pthread_rwlock_t lock; 71008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui enum Progress { 71108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_INITIALIZED, 71208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_WAITING, 71308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_RELEASED, 71408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui LOCK_ACCESSED 71508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui }; 71608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui std::atomic<Progress> progress; 71708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui}; 71808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 71908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cuistatic void pthread_rwlock_reader_wakeup_writer_helper(RwlockWakeupHelperArg* arg) { 72008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); 72108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_WAITING; 72208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 72308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&arg->lock)); 72408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_wrlock(&arg->lock)); 72508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress); 72608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock)); 72708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 72808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED; 72908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 73008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 73108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin CuiTEST(pthread, pthread_rwlock_reader_wakeup_writer) { 73208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui RwlockWakeupHelperArg wakeup_arg; 73308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL)); 73408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock)); 73508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED; 73608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 73708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui pthread_t thread; 73808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 73908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui reinterpret_cast<void* (*)(void*)>(pthread_rwlock_reader_wakeup_writer_helper), &wakeup_arg)); 7405b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui while (wakeup_arg.progress != RwlockWakeupHelperArg::LOCK_WAITING) { 7415b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui usleep(5000); 7425b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui } 7435b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui usleep(5000); 74408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED; 74508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock)); 74608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 74708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 74808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress); 74908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock)); 75008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 75108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 75208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cuistatic void pthread_rwlock_writer_wakeup_reader_helper(RwlockWakeupHelperArg* arg) { 75308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); 75408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_WAITING; 75508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 75608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&arg->lock)); 75708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(&arg->lock)); 75808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress); 75908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock)); 76008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 76108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED; 76208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 76308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 76408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin CuiTEST(pthread, pthread_rwlock_writer_wakeup_reader) { 76508ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui RwlockWakeupHelperArg wakeup_arg; 76608ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL)); 76708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock)); 76808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED; 76908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 77008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui pthread_t thread; 77108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 77208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui reinterpret_cast<void* (*)(void*)>(pthread_rwlock_writer_wakeup_reader_helper), &wakeup_arg)); 7735b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui while (wakeup_arg.progress != RwlockWakeupHelperArg::LOCK_WAITING) { 7745b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui usleep(5000); 7755b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui } 7765b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui usleep(5000); 77708ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED; 77808ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock)); 77908ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 78008ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 78108ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress); 78208ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock)); 78308ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui} 78408ee8d2030fbc73c4c144e819dd68806b0351cbeYabin Cui 7851728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_once_fn_call_count = 0; 786c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughesstatic void OnceFn() { 7871728b2396591853345507a063ed6075dfd251706Elliott Hughes ++g_once_fn_call_count; 788c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 789c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 790c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_once_smoke) { 791c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_once_t once_control = PTHREAD_ONCE_INIT; 792c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 793c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_once(&once_control, OnceFn)); 7941728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(1, g_once_fn_call_count); 795c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 796c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 7973694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic std::string pthread_once_1934122_result = ""; 7983694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 7993694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine2() { 8003694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "2"; 8013694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 8023694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 8033694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughesstatic void Routine1() { 8043694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_2 = PTHREAD_ONCE_INIT; 8053694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_1934122_result += "1"; 8063694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once(&once_control_2, &Routine2); 8073694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 8083694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 8093694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott HughesTEST(pthread, pthread_once_1934122) { 8103694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // Very old versions of Android couldn't call pthread_once from a 8113694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes // pthread_once init routine. http://b/1934122. 8123694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes pthread_once_t once_control_1 = PTHREAD_ONCE_INIT; 8133694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ(0, pthread_once(&once_control_1, &Routine1)); 8143694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes ASSERT_EQ("12", pthread_once_1934122_result); 8153694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes} 8163694ec6c4b644064f7e00b898cd11e138e4f6c09Elliott Hughes 8171728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_prepare_calls = 0; 8181728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls << 4) | 1; } 8191728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls << 4) | 2; } 8201728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_parent_calls = 0; 8211728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls << 4) | 1; } 8221728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls << 4) | 2; } 8231728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_atfork_child_calls = 0; 8241728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls << 4) | 1; } 8251728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls << 4) | 2; } 826c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 82700e37818a704fdd3d5f6a59022eff3a29b03bcceDmitriy IvanovTEST(pthread, pthread_atfork_smoke) { 828cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); 829cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); 830c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 831cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov int pid = fork(); 832cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_NE(-1, pid) << strerror(errno); 833c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 834cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov // Child and parent calls are made in the order they were registered. 835cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov if (pid == 0) { 836cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_EQ(0x12, g_atfork_child_calls); 837cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov _exit(0); 838cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov } 839cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_EQ(0x12, g_atfork_parent_calls); 840c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 841cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov // Prepare calls are made in the reverse order. 842cb0443c0fa07e4c049f426e3041894df522732dfDmitriy Ivanov ASSERT_EQ(0x21, g_atfork_prepare_calls); 843c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 844c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 845c3f114037dbf028896310609fd28cf2b3da99c4dElliott HughesTEST(pthread, pthread_attr_getscope) { 846c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes pthread_attr_t attr; 847c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_init(&attr)); 848c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes 849c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes int scope; 850c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(0, pthread_attr_getscope(&attr, &scope)); 851c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes ASSERT_EQ(PTHREAD_SCOPE_SYSTEM, scope); 852c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes} 85351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 85451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_init) { 85551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 85651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 85751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 85851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 85951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 86051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 86151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 86251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 86351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 86451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared); 86551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 86651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 86751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_condattr_setclock) { 86851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 86951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 87051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 87151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_REALTIME)); 87251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 87351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 87451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_REALTIME, clock); 87551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 87651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 87751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 87851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 87951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 88051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(EINVAL, pthread_condattr_setclock(&attr, CLOCK_PROCESS_CPUTIME_ID)); 88151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 88251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 88351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan KamathTEST(pthread, pthread_cond_broadcast__preserves_condattr_flags) { 88432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui#if defined(__BIONIC__) 88551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_t attr; 88651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_condattr_init(&attr); 88751e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 88851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); 88951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); 89051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 89151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath pthread_cond_t cond_var; 89251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_init(&cond_var, &attr)); 89351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 89451e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_signal(&cond_var)); 89551e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_cond_broadcast(&cond_var)); 89651e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath 89732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui attr = static_cast<pthread_condattr_t>(*reinterpret_cast<uint32_t*>(cond_var.__private)); 89851e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath clockid_t clock; 89951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); 90051e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(CLOCK_MONOTONIC, clock); 90151e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath int pshared; 90251e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared)); 90351e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared); 90432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui#else // !defined(__BIONIC__) 90532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n"; 90632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui#endif // !defined(__BIONIC__) 90732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui} 90832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 90932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cuiclass pthread_CondWakeupTest : public ::testing::Test { 91032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui protected: 91132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_mutex_t mutex; 91232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_cond_t cond; 91332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 91432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui enum Progress { 91532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui INITIALIZED, 91632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui WAITING, 91732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui SIGNALED, 91832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui FINISHED, 91932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui }; 92032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui std::atomic<Progress> progress; 92132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_t thread; 92232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 92332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui protected: 92432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui virtual void SetUp() { 92532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_init(&mutex, NULL)); 92632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_cond_init(&cond, NULL)); 92732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui progress = INITIALIZED; 92832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, 92932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_create(&thread, NULL, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), this)); 93032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 93132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 93232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui virtual void TearDown() { 93332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 93432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(FINISHED, progress); 93532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_cond_destroy(&cond)); 93632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_destroy(&mutex)); 93732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 93832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 93932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui void SleepUntilProgress(Progress expected_progress) { 94032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui while (progress != expected_progress) { 94132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui usleep(5000); 94232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 94332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui usleep(5000); 94432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 94532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 94632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui private: 94732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui static void WaitThreadFn(pthread_CondWakeupTest* test) { 94832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_lock(&test->mutex)); 94932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui test->progress = WAITING; 95032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui while (test->progress == WAITING) { 95132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_cond_wait(&test->cond, &test->mutex)); 95232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 95332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(SIGNALED, test->progress); 95432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui test->progress = FINISHED; 95532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&test->mutex)); 95632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui } 95732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui}; 95832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 95932651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin CuiTEST_F(pthread_CondWakeupTest, signal) { 96032651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui SleepUntilProgress(WAITING); 96132651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui progress = SIGNALED; 96232651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_cond_signal(&cond); 96332651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui} 96432651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui 96532651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin CuiTEST_F(pthread_CondWakeupTest, broadcast) { 96632651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui SleepUntilProgress(WAITING); 96732651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui progress = SIGNALED; 96832651b8e8e453391c7aaca47cd885e94d54d0bf4Yabin Cui pthread_cond_broadcast(&cond); 96951e6cb33e3d7c2f44864d356a2a8e66317688f55Narayan Kamath} 9700e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 9710e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott HughesTEST(pthread, pthread_mutex_timedlock) { 9720e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes pthread_mutex_t m; 9730e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_init(&m, NULL)); 9740e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 9750e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is already locked, pthread_mutex_timedlock should time out. 9760e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_lock(&m)); 9770e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 9780e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes timespec ts; 9790e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 9800e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 9810e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(ETIMEDOUT, pthread_mutex_timedlock(&m, &ts)); 9820e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 9830e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes // If the mutex is unlocked, pthread_mutex_timedlock should succeed. 9840e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 9850e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 9860e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); 9870e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ts.tv_nsec += 1; 9880e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_timedlock(&m, &ts)); 9890e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes 9900e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_unlock(&m)); 9910e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes ASSERT_EQ(0, pthread_mutex_destroy(&m)); 9920e714a5b41451e84c5ded93a42c9a4b0a9440691Elliott Hughes} 99357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 99457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott HughesTEST(pthread, pthread_attr_getstack__main_thread) { 99557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // This test is only meaningful for the main thread, so make sure we're running on it! 99657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(getpid(), syscall(__NR_gettid)); 99757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 99857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Get the main thread's attributes. 99957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes pthread_attr_t attributes; 100057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 100157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 100257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Check that we correctly report that the main thread has no guard page. 100357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t guard_size; 100457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size)); 100557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0U, guard_size); // The main thread has no guard page. 100657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 100757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // Get the stack base and the stack size (both ways). 100857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes void* stack_base; 100957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t stack_size; 101057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 101157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes size_t stack_size2; 101257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 101357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 101457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // The two methods of asking for the stack size should agree. 101557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 101657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 101757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // What does /proc/self/maps' [stack] line say? 10189e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes void* maps_stack_hi = NULL; 101957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes FILE* fp = fopen("/proc/self/maps", "r"); 102057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_TRUE(fp != NULL); 102157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes char line[BUFSIZ]; 102257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes while (fgets(line, sizeof(line), fp) != NULL) { 102357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes uintptr_t lo, hi; 102457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes char name[10]; 102557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name); 102657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes if (strcmp(name, "[stack]") == 0) { 10279e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes maps_stack_hi = reinterpret_cast<void*>(hi); 102857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes break; 102957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes } 103057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes } 103157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes fclose(fp); 103257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 10339e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // The stack size should correspond to RLIMIT_STACK. 10349e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes rlimit rl; 10359e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl)); 103627a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes uint64_t original_rlim_cur = rl.rlim_cur; 103727a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes#if defined(__BIONIC__) 103827a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes if (rl.rlim_cur == RLIM_INFINITY) { 103927a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB. 104027a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes } 104127a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes#endif 10429e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes EXPECT_EQ(rl.rlim_cur, stack_size); 104357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 1044d9ff7226613014056c9edd79a68dc5af939107a0Dmitriy Ivanov auto guard = make_scope_guard([&rl, original_rlim_cur]() { 104527a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes rl.rlim_cur = original_rlim_cur; 104627a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 104727a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes }); 104827a9aed81978af792cb06035a1619c8141a5fb5bElliott Hughes 10499e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size. 10509e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // Remember that the stack grows down (and is mapped in on demand), so the low address of the 10519e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // region isn't very interesting. 10529e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size); 105357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 105457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 10559e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // What if RLIMIT_STACK is smaller than the stack's current extent? 105657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 105757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already. 105857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_max = RLIM_INFINITY; 105957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 106057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 106157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 106257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 106357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 106457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 106557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 106657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(1024U, stack_size); 106757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 106857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 10699e4ffa7032eaab308876b8e3da86b05c3c613878Elliott Hughes // What if RLIMIT_STACK isn't a whole number of pages? 107057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes // 107157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages. 107257b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes rl.rlim_max = RLIM_INFINITY; 107357b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); 107457b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 107557b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes)); 107657b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size)); 107757b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2)); 107857b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes 107957b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes EXPECT_EQ(stack_size, stack_size2); 108057b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes ASSERT_EQ(6666U, stack_size); 108157b7a6110e7e8b446fc23cce4765ff625ee0a105Elliott Hughes} 10828fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 1083917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cuistatic void pthread_attr_getstack_18908062_helper(void*) { 1084917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui char local_variable; 1085917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_attr_t attributes; 1086917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_getattr_np(pthread_self(), &attributes); 1087917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui void* stack_base; 1088917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui size_t stack_size; 1089917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_attr_getstack(&attributes, &stack_base, &stack_size); 1090917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui 1091917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui // Test whether &local_variable is in [stack_base, stack_base + stack_size). 1092917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_LE(reinterpret_cast<char*>(stack_base), &local_variable); 1093917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_LT(&local_variable, reinterpret_cast<char*>(stack_base) + stack_size); 1094917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui} 1095917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui 1096917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui// Check whether something on stack is in the range of 1097917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui// [stack_base, stack_base + stack_size). see b/18908062. 1098917d390510e442b9b030d54992ebf41cc1e7f853Yabin CuiTEST(pthread, pthread_attr_getstack_18908062) { 1099917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_t t; 1100917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui ASSERT_EQ(0, pthread_create(&t, NULL, 1101917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui reinterpret_cast<void* (*)(void*)>(pthread_attr_getstack_18908062_helper), 1102917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui NULL)); 1103917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui pthread_join(t, NULL); 1104917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui} 1105917d390510e442b9b030d54992ebf41cc1e7f853Yabin Cui 11068fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#if defined(__BIONIC__) 11078fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughesstatic void* pthread_gettid_np_helper(void* arg) { 11088fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes *reinterpret_cast<pid_t*>(arg) = gettid(); 11098fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes return NULL; 11108fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes} 11118fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#endif 11128fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 11138fb639ca9118a6522723d0bc09db59b432a803a9Elliott HughesTEST(pthread, pthread_gettid_np) { 11148fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#if defined(__BIONIC__) 11158fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes ASSERT_EQ(gettid(), pthread_gettid_np(pthread_self())); 11168fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 11178fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pid_t t_gettid_result; 11188fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pthread_t t; 11198fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pthread_create(&t, NULL, pthread_gettid_np_helper, &t_gettid_result); 11208fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 11218fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes pid_t t_pthread_gettid_np_result = pthread_gettid_np(t); 11228fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 112334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 11248fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes 11258fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result); 11268fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#else 11278fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes GTEST_LOG_(INFO) << "This test does nothing.\n"; 11288fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes#endif 11298fb639ca9118a6522723d0bc09db59b432a803a9Elliott Hughes} 113034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 113134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughesstatic size_t cleanup_counter = 0; 113234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 11334199695657e9500db14ab40392e3715db1826002Derek Xuestatic void AbortCleanupRoutine(void*) { 113434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes abort(); 113534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 113634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 11374199695657e9500db14ab40392e3715db1826002Derek Xuestatic void CountCleanupRoutine(void*) { 113834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ++cleanup_counter; 113934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 114034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 11414199695657e9500db14ab40392e3715db1826002Derek Xuestatic void PthreadCleanupTester() { 114234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(CountCleanupRoutine, NULL); 114334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(CountCleanupRoutine, NULL); 114434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_push(AbortCleanupRoutine, NULL); 114534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 114634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(0); // Pop the abort without executing it. 114734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(1); // Pop one count while executing it. 114834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(1U, cleanup_counter); 114934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes // Exit while the other count is still on the cleanup stack. 115034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_exit(NULL); 115134c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 115234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes // Calls to pthread_cleanup_pop/pthread_cleanup_push must always be balanced. 115334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_cleanup_pop(0); 115434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 115534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 11564199695657e9500db14ab40392e3715db1826002Derek Xuestatic void* PthreadCleanupStartRoutine(void*) { 115734c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes PthreadCleanupTester(); 115834c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes return NULL; 115934c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 116034c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes 116134c987a6dd6816eff98bc25f627659550c2338dcElliott HughesTEST(pthread, pthread_cleanup_push__pthread_cleanup_pop) { 116234c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_t t; 116334c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, PthreadCleanupStartRoutine, NULL)); 116434c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes pthread_join(t, NULL); 116534c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes ASSERT_EQ(2U, cleanup_counter); 116634c987a6dd6816eff98bc25f627659550c2338dcElliott Hughes} 11674199695657e9500db14ab40392e3715db1826002Derek Xue 11684199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, PTHREAD_MUTEX_DEFAULT_is_PTHREAD_MUTEX_NORMAL) { 11694199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_DEFAULT); 11704199695657e9500db14ab40392e3715db1826002Derek Xue} 11714199695657e9500db14ab40392e3715db1826002Derek Xue 11724199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutexattr_gettype) { 11734199695657e9500db14ab40392e3715db1826002Derek Xue pthread_mutexattr_t attr; 11744199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 11754199695657e9500db14ab40392e3715db1826002Derek Xue 11764199695657e9500db14ab40392e3715db1826002Derek Xue int attr_type; 11774199695657e9500db14ab40392e3715db1826002Derek Xue 11784199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)); 11794199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 11804199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_NORMAL, attr_type); 11814199695657e9500db14ab40392e3715db1826002Derek Xue 11824199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); 11834199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 11844199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_ERRORCHECK, attr_type); 11854199695657e9500db14ab40392e3715db1826002Derek Xue 11864199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); 11874199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type)); 11884199695657e9500db14ab40392e3715db1826002Derek Xue ASSERT_EQ(PTHREAD_MUTEX_RECURSIVE, attr_type); 11895b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 11905b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(0, pthread_mutexattr_destroy(&attr)); 11914199695657e9500db14ab40392e3715db1826002Derek Xue} 11924199695657e9500db14ab40392e3715db1826002Derek Xue 119317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cuistruct PthreadMutex { 119417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock; 119517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 119617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex(int mutex_type) { 119717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui init(mutex_type); 119817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 119917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 120017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ~PthreadMutex() { 120117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui destroy(); 120217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 120317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 120417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui private: 120517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui void init(int mutex_type) { 120617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutexattr_t attr; 120717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutexattr_init(&attr)); 120817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutexattr_settype(&attr, mutex_type)); 120917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_init(&lock, &attr)); 121017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutexattr_destroy(&attr)); 121117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 121217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 121317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui void destroy() { 121417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_destroy(&lock)); 121517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 121617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 121717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui DISALLOW_COPY_AND_ASSIGN(PthreadMutex); 121817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui}; 12194199695657e9500db14ab40392e3715db1826002Derek Xue 12205b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_lock_NORMAL) { 122117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m(PTHREAD_MUTEX_NORMAL); 12224199695657e9500db14ab40392e3715db1826002Derek Xue 122317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 122417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 12254199695657e9500db14ab40392e3715db1826002Derek Xue} 12264199695657e9500db14ab40392e3715db1826002Derek Xue 12274199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutex_lock_ERRORCHECK) { 122817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m(PTHREAD_MUTEX_ERRORCHECK); 12294199695657e9500db14ab40392e3715db1826002Derek Xue 123017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 123117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EDEADLK, pthread_mutex_lock(&m.lock)); 123217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 123317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_trylock(&m.lock)); 123417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock)); 123517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 123617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock)); 12374199695657e9500db14ab40392e3715db1826002Derek Xue} 12384199695657e9500db14ab40392e3715db1826002Derek Xue 12394199695657e9500db14ab40392e3715db1826002Derek XueTEST(pthread, pthread_mutex_lock_RECURSIVE) { 124017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m(PTHREAD_MUTEX_RECURSIVE); 12414199695657e9500db14ab40392e3715db1826002Derek Xue 124217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 124317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 124417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 124517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 124617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_trylock(&m.lock)); 124717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 124817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock)); 124917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui} 125017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 125117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin CuiTEST(pthread, pthread_mutex_init_same_as_static_initializers) { 125217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock_normal = PTHREAD_MUTEX_INITIALIZER; 125317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m1(PTHREAD_MUTEX_NORMAL); 125417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, memcmp(&lock_normal, &m1.lock, sizeof(pthread_mutex_t))); 125517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_destroy(&lock_normal); 125617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 125717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock_errorcheck = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; 125817393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m2(PTHREAD_MUTEX_ERRORCHECK); 125917393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, memcmp(&lock_errorcheck, &m2.lock, sizeof(pthread_mutex_t))); 126017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_destroy(&lock_errorcheck); 126117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 126217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui pthread_mutex_t lock_recursive = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 126317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m3(PTHREAD_MUTEX_RECURSIVE); 126417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t))); 126517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive)); 12664199695657e9500db14ab40392e3715db1826002Derek Xue} 1267140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui 12685b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cuiclass MutexWakeupHelper { 12695b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui private: 127017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui PthreadMutex m; 12715b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui enum Progress { 12725b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_INITIALIZED, 12735b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_WAITING, 12745b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_RELEASED, 12755b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui LOCK_ACCESSED 12765b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui }; 12775b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui std::atomic<Progress> progress; 12785b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 12795b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui static void thread_fn(MutexWakeupHelper* helper) { 12805b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(LOCK_INITIALIZED, helper->progress); 12815b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui helper->progress = LOCK_WAITING; 12825b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 128317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&helper->m.lock)); 12845b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(LOCK_RELEASED, helper->progress); 128517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&helper->m.lock)); 12865b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 12875b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui helper->progress = LOCK_ACCESSED; 12885b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui } 12895b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 12905b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui public: 129117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper(int mutex_type) : m(mutex_type) { 129217393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui } 129317393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui 129417393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui void test() { 129517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_lock(&m.lock)); 12965b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui progress = LOCK_INITIALIZED; 12975b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 12985b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui pthread_t thread; 12995b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(0, pthread_create(&thread, NULL, 13005b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui reinterpret_cast<void* (*)(void*)>(MutexWakeupHelper::thread_fn), this)); 13015b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 13025b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui while (progress != LOCK_WAITING) { 13035b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui usleep(5000); 13045b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui } 13055b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui usleep(5000); 13065b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui progress = LOCK_RELEASED; 130717393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui ASSERT_EQ(0, pthread_mutex_unlock(&m.lock)); 13085b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 13095b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(0, pthread_join(thread, NULL)); 13105b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui ASSERT_EQ(LOCK_ACCESSED, progress); 13115b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui } 13125b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui}; 13135b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 13145b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_NORMAL_wakeup) { 131517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper helper(PTHREAD_MUTEX_NORMAL); 131617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui helper.test(); 13175b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui} 13185b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 13195b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_ERRORCHECK_wakeup) { 132017393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper helper(PTHREAD_MUTEX_ERRORCHECK); 132117393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui helper.test(); 13225b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui} 13235b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 13245b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin CuiTEST(pthread, pthread_mutex_RECURSIVE_wakeup) { 132517393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui MutexWakeupHelper helper(PTHREAD_MUTEX_RECURSIVE); 132617393b06bab9cb3e95d0f466a56c746de19b8eeeYabin Cui helper.test(); 13275b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui} 13285b8e7cd957f9380e93c3aee84962d157fe0bc526Yabin Cui 1329140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin CuiTEST(pthread, pthread_mutex_owner_tid_limit) { 1330e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui#if defined(__BIONIC__) && !defined(__LP64__) 1331140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui FILE* fp = fopen("/proc/sys/kernel/pid_max", "r"); 1332140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui ASSERT_TRUE(fp != NULL); 1333140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui long pid_max; 1334140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui ASSERT_EQ(1, fscanf(fp, "%ld", &pid_max)); 1335140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui fclose(fp); 1336e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui // Bionic's pthread_mutex implementation on 32-bit devices uses 16 bits to represent owner tid. 1337140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui ASSERT_LE(pid_max, 65536); 1338e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui#else 1339e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui GTEST_LOG_(INFO) << "This test does nothing as 32-bit tid is supported by pthread_mutex.\n"; 1340e69c24543db577d8b219ab74b0ba7566e0f13b38Yabin Cui#endif 1341140f3678f0f21eeda5916e9b8de87b93fd660a61Yabin Cui} 1342b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1343b58457221364eaad039c2c49a42626b725e980d5Yabin Cuiclass StrictAlignmentAllocator { 1344b58457221364eaad039c2c49a42626b725e980d5Yabin Cui public: 1345b58457221364eaad039c2c49a42626b725e980d5Yabin Cui void* allocate(size_t size, size_t alignment) { 1346b58457221364eaad039c2c49a42626b725e980d5Yabin Cui char* p = new char[size + alignment * 2]; 1347b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocated_array.push_back(p); 1348b58457221364eaad039c2c49a42626b725e980d5Yabin Cui while (!is_strict_aligned(p, alignment)) { 1349b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ++p; 1350b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1351b58457221364eaad039c2c49a42626b725e980d5Yabin Cui return p; 1352b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1353b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1354b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ~StrictAlignmentAllocator() { 1355b58457221364eaad039c2c49a42626b725e980d5Yabin Cui for (auto& p : allocated_array) { 1356b58457221364eaad039c2c49a42626b725e980d5Yabin Cui delete [] p; 1357b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1358b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1359b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1360b58457221364eaad039c2c49a42626b725e980d5Yabin Cui private: 1361b58457221364eaad039c2c49a42626b725e980d5Yabin Cui bool is_strict_aligned(char* p, size_t alignment) { 1362b58457221364eaad039c2c49a42626b725e980d5Yabin Cui return (reinterpret_cast<uintptr_t>(p) % (alignment * 2)) == alignment; 1363b58457221364eaad039c2c49a42626b725e980d5Yabin Cui } 1364b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1365b58457221364eaad039c2c49a42626b725e980d5Yabin Cui std::vector<char*> allocated_array; 1366b58457221364eaad039c2c49a42626b725e980d5Yabin Cui}; 1367b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1368b58457221364eaad039c2c49a42626b725e980d5Yabin CuiTEST(pthread, pthread_types_allow_four_bytes_alignment) { 1369b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#if defined(__BIONIC__) 1370b58457221364eaad039c2c49a42626b725e980d5Yabin Cui // For binary compatibility with old version, we need to allow 4-byte aligned data for pthread types. 1371b58457221364eaad039c2c49a42626b725e980d5Yabin Cui StrictAlignmentAllocator allocator; 1372b58457221364eaad039c2c49a42626b725e980d5Yabin Cui pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>( 1373b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocator.allocate(sizeof(pthread_mutex_t), 4)); 1374b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_init(mutex, NULL)); 1375b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_lock(mutex)); 1376b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_unlock(mutex)); 1377b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_mutex_destroy(mutex)); 1378b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1379b58457221364eaad039c2c49a42626b725e980d5Yabin Cui pthread_cond_t* cond = reinterpret_cast<pthread_cond_t*>( 1380b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocator.allocate(sizeof(pthread_cond_t), 4)); 1381b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_init(cond, NULL)); 1382b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_signal(cond)); 1383b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_broadcast(cond)); 1384b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_cond_destroy(cond)); 1385b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1386b58457221364eaad039c2c49a42626b725e980d5Yabin Cui pthread_rwlock_t* rwlock = reinterpret_cast<pthread_rwlock_t*>( 1387b58457221364eaad039c2c49a42626b725e980d5Yabin Cui allocator.allocate(sizeof(pthread_rwlock_t), 4)); 1388b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_init(rwlock, NULL)); 1389b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_rdlock(rwlock)); 1390b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(rwlock)); 1391b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_wrlock(rwlock)); 1392b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_unlock(rwlock)); 1393b58457221364eaad039c2c49a42626b725e980d5Yabin Cui ASSERT_EQ(0, pthread_rwlock_destroy(rwlock)); 1394b58457221364eaad039c2c49a42626b725e980d5Yabin Cui 1395b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#else 1396b58457221364eaad039c2c49a42626b725e980d5Yabin Cui GTEST_LOG_(INFO) << "This test tests bionic implementation details."; 1397b58457221364eaad039c2c49a42626b725e980d5Yabin Cui#endif 1398b58457221364eaad039c2c49a42626b725e980d5Yabin Cui} 1399