19d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes/* 29d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * Copyright (C) 2008 The Android Open Source Project 39d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * All rights reserved. 49d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * 59d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * Redistribution and use in source and binary forms, with or without 69d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * modification, are permitted provided that the following conditions 79d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * are met: 89d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * * Redistributions of source code must retain the above copyright 99d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * notice, this list of conditions and the following disclaimer. 109d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * * Redistributions in binary form must reproduce the above copyright 119d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * notice, this list of conditions and the following disclaimer in 129d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * the documentation and/or other materials provided with the 139d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * distribution. 149d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * 159d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 169d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 179d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 189d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 199d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 209d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 219d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 229d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 239d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 249d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 259d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 269d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes * SUCH DAMAGE. 279d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes */ 289d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 299d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes#include "pthread_internal.h" 309d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 318574a0670bf698b8d2f817098f9d825c4be03a68Yabin Cui#include <errno.h> 3275ef63d6cf83787233d1c45489c4ec03b0a67d16Dan Albert#include <stdlib.h> 338574a0670bf698b8d2f817098f9d825c4be03a68Yabin Cui#include <string.h> 348574a0670bf698b8d2f817098f9d825c4be03a68Yabin Cui#include <sys/mman.h> 3575ef63d6cf83787233d1c45489c4ec03b0a67d16Dan Albert 36c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes#include "private/bionic_futex.h" 37eb847bc8666842a3cfc9c06e8458ad1abebebaf0Elliott Hughes#include "private/bionic_tls.h" 388574a0670bf698b8d2f817098f9d825c4be03a68Yabin Cui#include "private/libc_logging.h" 39eb847bc8666842a3cfc9c06e8458ad1abebebaf0Elliott Hughes#include "private/ScopedPthreadMutexLocker.h" 409d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 41673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cuistatic pthread_internal_t* g_thread_list = NULL; 42673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cuistatic pthread_mutex_t g_thread_list_lock = PTHREAD_MUTEX_INITIALIZER; 43673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui 44673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cuipthread_t __pthread_internal_add(pthread_internal_t* thread) { 45673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui ScopedPthreadMutexLocker locker(&g_thread_list_lock); 46673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui 47673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui // We insert at the head. 48673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui thread->next = g_thread_list; 49673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui thread->prev = NULL; 50673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui if (thread->next != NULL) { 51673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui thread->next->prev = thread; 52673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui } 53673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui g_thread_list = thread; 54673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui return reinterpret_cast<pthread_t>(thread); 55673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui} 56673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui 57673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cuivoid __pthread_internal_remove(pthread_internal_t* thread) { 58673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui ScopedPthreadMutexLocker locker(&g_thread_list_lock); 599d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 609d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes if (thread->next != NULL) { 619d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes thread->next->prev = thread->prev; 629d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes } 639d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes if (thread->prev != NULL) { 649d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes thread->prev->next = thread->next; 659d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes } else { 661728b2396591853345507a063ed6075dfd251706Elliott Hughes g_thread_list = thread->next; 679d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes } 68673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui} 699d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 70673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cuistatic void __pthread_internal_free(pthread_internal_t* thread) { 71673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui if (thread->mmap_size != 0) { 72ba8dfc2669d658dc340eb8f9c9b40ca074f05047Yabin Cui // Free mapped space, including thread stack and pthread_internal_t. 73ba8dfc2669d658dc340eb8f9c9b40ca074f05047Yabin Cui munmap(thread->attr.stack_base, thread->mmap_size); 749d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes } 759d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 769d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 77673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cuivoid __pthread_internal_remove_and_free(pthread_internal_t* thread) { 78673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui __pthread_internal_remove(thread); 79673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui __pthread_internal_free(thread); 80673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui} 81673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui 82673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cuipthread_internal_t* __pthread_internal_find(pthread_t thread_id) { 83673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(thread_id); 844bc739a54c4ba9063e91bef06ff226dab118792dDimitry Ivanov 854bc739a54c4ba9063e91bef06ff226dab118792dDimitry Ivanov // check if thread is pthread_self() before acquiring the lock 864bc739a54c4ba9063e91bef06ff226dab118792dDimitry Ivanov if (thread == __get_thread()) { 874bc739a54c4ba9063e91bef06ff226dab118792dDimitry Ivanov return thread; 884bc739a54c4ba9063e91bef06ff226dab118792dDimitry Ivanov } 894bc739a54c4ba9063e91bef06ff226dab118792dDimitry Ivanov 90220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin Cui ScopedPthreadMutexLocker locker(&g_thread_list_lock); 919d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes 92220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin Cui for (pthread_internal_t* t = g_thread_list; t != NULL; t = t->next) { 93220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin Cui if (t == thread) { 94220b99bdc1c5f51825ac2a87062bc05fe3e0d722Yabin Cui return thread; 95673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui } 969d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes } 97673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui return NULL; 989d23e04c43dbb8480bea8be28b8a2f37423bec49Elliott Hughes} 99