1c7561b931e249acf3768ead77638545b0ccaa8f1njn 2c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 3c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- The thread state. m_threadstate.c ---*/ 4c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 5c7561b931e249acf3768ead77638545b0ccaa8f1njn 6c7561b931e249acf3768ead77638545b0ccaa8f1njn/* 7c7561b931e249acf3768ead77638545b0ccaa8f1njn This file is part of Valgrind, a dynamic binary instrumentation 8c7561b931e249acf3768ead77638545b0ccaa8f1njn framework. 9c7561b931e249acf3768ead77638545b0ccaa8f1njn 10ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2000-2017 Julian Seward 11c7561b931e249acf3768ead77638545b0ccaa8f1njn jseward@acm.org 12c7561b931e249acf3768ead77638545b0ccaa8f1njn 13c7561b931e249acf3768ead77638545b0ccaa8f1njn This program is free software; you can redistribute it and/or 14c7561b931e249acf3768ead77638545b0ccaa8f1njn modify it under the terms of the GNU General Public License as 15c7561b931e249acf3768ead77638545b0ccaa8f1njn published by the Free Software Foundation; either version 2 of the 16c7561b931e249acf3768ead77638545b0ccaa8f1njn License, or (at your option) any later version. 17c7561b931e249acf3768ead77638545b0ccaa8f1njn 18c7561b931e249acf3768ead77638545b0ccaa8f1njn This program is distributed in the hope that it will be useful, but 19c7561b931e249acf3768ead77638545b0ccaa8f1njn WITHOUT ANY WARRANTY; without even the implied warranty of 20c7561b931e249acf3768ead77638545b0ccaa8f1njn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21c7561b931e249acf3768ead77638545b0ccaa8f1njn General Public License for more details. 22c7561b931e249acf3768ead77638545b0ccaa8f1njn 23c7561b931e249acf3768ead77638545b0ccaa8f1njn You should have received a copy of the GNU General Public License 24c7561b931e249acf3768ead77638545b0ccaa8f1njn along with this program; if not, write to the Free Software 25c7561b931e249acf3768ead77638545b0ccaa8f1njn Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26c7561b931e249acf3768ead77638545b0ccaa8f1njn 02111-1307, USA. 27c7561b931e249acf3768ead77638545b0ccaa8f1njn 28c7561b931e249acf3768ead77638545b0ccaa8f1njn The GNU General Public License is contained in the file COPYING. 29c7561b931e249acf3768ead77638545b0ccaa8f1njn*/ 30c7561b931e249acf3768ead77638545b0ccaa8f1njn 31c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h" 324cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 33c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_threadstate.h" 341e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian#include "pub_core_mallocfree.h" // VG_(malloc) 35c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_libcassert.h" 36c91f58449e6fc2a4ce0851639a342c4277612fbbflorian#include "pub_core_inner.h" 3727233e99d0964be703299c7f83396f1864d7b5d0bart#if defined(ENABLE_INNER_CLIENT_REQUEST) 3827233e99d0964be703299c7f83396f1864d7b5d0bart#include "helgrind/helgrind.h" 3927233e99d0964be703299c7f83396f1864d7b5d0bart#endif 40c7561b931e249acf3768ead77638545b0ccaa8f1njn 41c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 42c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- Data structures. ---*/ 43c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 44c7561b931e249acf3768ead77638545b0ccaa8f1njn 45c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadId VG_(running_tid) = VG_INVALID_THREADID; 46c7561b931e249acf3768ead77638545b0ccaa8f1njn 471e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianThreadState *VG_(threads); 481e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianUInt VG_N_THREADS; 49c7561b931e249acf3768ead77638545b0ccaa8f1njn 50ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott HughesThreadState *VG_(inner_threads); 51ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 52c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 53c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- Operations. ---*/ 54c7561b931e249acf3768ead77638545b0ccaa8f1njn/*------------------------------------------------------------*/ 55c7561b931e249acf3768ead77638545b0ccaa8f1njn 5627233e99d0964be703299c7f83396f1864d7b5d0bartvoid VG_(init_Threads)(void) 5727233e99d0964be703299c7f83396f1864d7b5d0bart{ 5827233e99d0964be703299c7f83396f1864d7b5d0bart ThreadId tid; 591e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian 604e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe VG_(threads) = VG_(arena_memalign) (VG_AR_CORE, "init_Threads", 614e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe LibVEX_GUEST_STATE_ALIGN, 624e4ded74e620334a719286db7b5bf86fa7bcbcaephilippe VG_N_THREADS * sizeof VG_(threads)[0]); 6327233e99d0964be703299c7f83396f1864d7b5d0bart 6492e2c648864a53081be2f8d843c31b18a2252808bart for (tid = 1; tid < VG_N_THREADS; tid++) { 6592e2c648864a53081be2f8d843c31b18a2252808bart INNER_REQUEST( 6692e2c648864a53081be2f8d843c31b18a2252808bart ANNOTATE_BENIGN_RACE_SIZED(&VG_(threads)[tid].status, 6792e2c648864a53081be2f8d843c31b18a2252808bart sizeof(VG_(threads)[tid].status), "")); 6892e2c648864a53081be2f8d843c31b18a2252808bart INNER_REQUEST( 6992e2c648864a53081be2f8d843c31b18a2252808bart ANNOTATE_BENIGN_RACE_SIZED(&VG_(threads)[tid].os_state.exitcode, 7092e2c648864a53081be2f8d843c31b18a2252808bart sizeof(VG_(threads)[tid].os_state.exitcode), 7192e2c648864a53081be2f8d843c31b18a2252808bart "")); 7292e2c648864a53081be2f8d843c31b18a2252808bart } 73ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes INNER_REQUEST(VALGRIND_INNER_THREADS(VG_(threads))); 7427233e99d0964be703299c7f83396f1864d7b5d0bart} 7527233e99d0964be703299c7f83396f1864d7b5d0bart 76c7561b931e249acf3768ead77638545b0ccaa8f1njnconst HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status ) 77c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 78c7561b931e249acf3768ead77638545b0ccaa8f1njn switch (status) { 79c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Empty: return "VgTs_Empty"; 80c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Init: return "VgTs_Init"; 81c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Runnable: return "VgTs_Runnable"; 82c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_WaitSys: return "VgTs_WaitSys"; 83c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Yielding: return "VgTs_Yielding"; 84c7561b931e249acf3768ead77638545b0ccaa8f1njn case VgTs_Zombie: return "VgTs_Zombie"; 85c7561b931e249acf3768ead77638545b0ccaa8f1njn default: return "VgTs_???"; 86c7561b931e249acf3768ead77638545b0ccaa8f1njn } 87c7561b931e249acf3768ead77638545b0ccaa8f1njn} 88c7561b931e249acf3768ead77638545b0ccaa8f1njn 89b8ba0310d94b421f6522f1a816f85653e795f5d8philippeconst HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode ) 90b8ba0310d94b421f6522f1a816f85653e795f5d8philippe{ 91b8ba0310d94b421f6522f1a816f85653e795f5d8philippe switch (retcode) { 92b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_None: return "VgSrc_None"; 93b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_ExitThread: return "VgSrc_ExitThread"; 94b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_ExitProcess: return "VgSrc_ExitProcess"; 95b8ba0310d94b421f6522f1a816f85653e795f5d8philippe case VgSrc_FatalSig: return "VgSrc_FatalSig"; 96b8ba0310d94b421f6522f1a816f85653e795f5d8philippe default: return "VgSrc_???"; 97b8ba0310d94b421f6522f1a816f85653e795f5d8philippe } 98b8ba0310d94b421f6522f1a816f85653e795f5d8philippe} 99b8ba0310d94b421f6522f1a816f85653e795f5d8philippe 100c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadState *VG_(get_ThreadState)(ThreadId tid) 101c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 102c7561b931e249acf3768ead77638545b0ccaa8f1njn vg_assert(tid >= 0 && tid < VG_N_THREADS); 10313ac35b96f354b790c5aaface07d78988734201dsewardj vg_assert(VG_(threads)[tid].tid == tid); 104c7561b931e249acf3768ead77638545b0ccaa8f1njn return &VG_(threads)[tid]; 105c7561b931e249acf3768ead77638545b0ccaa8f1njn} 106c7561b931e249acf3768ead77638545b0ccaa8f1njn 107c7561b931e249acf3768ead77638545b0ccaa8f1njnBool VG_(is_valid_tid) ( ThreadId tid ) 108c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 109c7561b931e249acf3768ead77638545b0ccaa8f1njn /* tid is unsigned, hence no < 0 test. */ 110c7561b931e249acf3768ead77638545b0ccaa8f1njn if (tid == 0) return False; 111c7561b931e249acf3768ead77638545b0ccaa8f1njn if (tid >= VG_N_THREADS) return False; 112c7561b931e249acf3768ead77638545b0ccaa8f1njn if (VG_(threads)[tid].status == VgTs_Empty) return False; 113c7561b931e249acf3768ead77638545b0ccaa8f1njn return True; 114c7561b931e249acf3768ead77638545b0ccaa8f1njn} 115c7561b931e249acf3768ead77638545b0ccaa8f1njn 116c7561b931e249acf3768ead77638545b0ccaa8f1njn// This function is for tools to call. 117c7561b931e249acf3768ead77638545b0ccaa8f1njnThreadId VG_(get_running_tid)(void) 118c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 119c7561b931e249acf3768ead77638545b0ccaa8f1njn return VG_(running_tid); 120c7561b931e249acf3768ead77638545b0ccaa8f1njn} 121c7561b931e249acf3768ead77638545b0ccaa8f1njn 122c7561b931e249acf3768ead77638545b0ccaa8f1njnBool VG_(is_running_thread)(ThreadId tid) 123c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 124c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadState *tst = VG_(get_ThreadState)(tid); 125c7561b931e249acf3768ead77638545b0ccaa8f1njn 126c7561b931e249acf3768ead77638545b0ccaa8f1njn return 127c7561b931e249acf3768ead77638545b0ccaa8f1njn// tst->os_state.lwpid == VG_(gettid)() && // check we're this tid 128c7561b931e249acf3768ead77638545b0ccaa8f1njn VG_(running_tid) == tid && // and that we've got the lock 129c7561b931e249acf3768ead77638545b0ccaa8f1njn tst->status == VgTs_Runnable; // and we're runnable 130c7561b931e249acf3768ead77638545b0ccaa8f1njn} 131c7561b931e249acf3768ead77638545b0ccaa8f1njn 132c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Return true if the thread is still alive but in the process of exiting. */ 133c7561b931e249acf3768ead77638545b0ccaa8f1njninline Bool VG_(is_exiting)(ThreadId tid) 134c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 135c7561b931e249acf3768ead77638545b0ccaa8f1njn vg_assert(VG_(is_valid_tid)(tid)); 136c7561b931e249acf3768ead77638545b0ccaa8f1njn return VG_(threads)[tid].exitreason != VgSrc_None; 137c7561b931e249acf3768ead77638545b0ccaa8f1njn} 138c7561b931e249acf3768ead77638545b0ccaa8f1njn 139c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Return the number of non-dead Threads */ 140c7561b931e249acf3768ead77638545b0ccaa8f1njnInt VG_(count_living_threads)(void) 141c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 142c7561b931e249acf3768ead77638545b0ccaa8f1njn Int count = 0; 143c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadId tid; 144c7561b931e249acf3768ead77638545b0ccaa8f1njn 145c7561b931e249acf3768ead77638545b0ccaa8f1njn for(tid = 1; tid < VG_N_THREADS; tid++) 146c7561b931e249acf3768ead77638545b0ccaa8f1njn if (VG_(threads)[tid].status != VgTs_Empty && 147c7561b931e249acf3768ead77638545b0ccaa8f1njn VG_(threads)[tid].status != VgTs_Zombie) 148c7561b931e249acf3768ead77638545b0ccaa8f1njn count++; 149c7561b931e249acf3768ead77638545b0ccaa8f1njn 150c7561b931e249acf3768ead77638545b0ccaa8f1njn return count; 151c7561b931e249acf3768ead77638545b0ccaa8f1njn} 152c7561b931e249acf3768ead77638545b0ccaa8f1njn 153d8a725e012a2af94bf265043a08d09c83b89b403sewardj/* Return the number of threads in VgTs_Runnable state */ 154d8a725e012a2af94bf265043a08d09c83b89b403sewardjInt VG_(count_runnable_threads)(void) 155d8a725e012a2af94bf265043a08d09c83b89b403sewardj{ 156d8a725e012a2af94bf265043a08d09c83b89b403sewardj Int count = 0; 157d8a725e012a2af94bf265043a08d09c83b89b403sewardj ThreadId tid; 158d8a725e012a2af94bf265043a08d09c83b89b403sewardj 159d8a725e012a2af94bf265043a08d09c83b89b403sewardj for(tid = 1; tid < VG_N_THREADS; tid++) 160d8a725e012a2af94bf265043a08d09c83b89b403sewardj if (VG_(threads)[tid].status == VgTs_Runnable) 161d8a725e012a2af94bf265043a08d09c83b89b403sewardj count++; 162d8a725e012a2af94bf265043a08d09c83b89b403sewardj 163d8a725e012a2af94bf265043a08d09c83b89b403sewardj return count; 164d8a725e012a2af94bf265043a08d09c83b89b403sewardj} 165d8a725e012a2af94bf265043a08d09c83b89b403sewardj 166c7561b931e249acf3768ead77638545b0ccaa8f1njn/* Given an LWP id (ie, real kernel thread id), find the corresponding 167c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadId */ 1684278172aee9a9db96cc2f9aff9158e3164fa113csewardjThreadId VG_(lwpid_to_vgtid)(Int lwp) 169c7561b931e249acf3768ead77638545b0ccaa8f1njn{ 170c7561b931e249acf3768ead77638545b0ccaa8f1njn ThreadId tid; 171c7561b931e249acf3768ead77638545b0ccaa8f1njn 172c7561b931e249acf3768ead77638545b0ccaa8f1njn for(tid = 1; tid < VG_N_THREADS; tid++) 173d8a725e012a2af94bf265043a08d09c83b89b403sewardj if (VG_(threads)[tid].status != VgTs_Empty 174d8a725e012a2af94bf265043a08d09c83b89b403sewardj && VG_(threads)[tid].os_state.lwpid == lwp) 175c7561b931e249acf3768ead77638545b0ccaa8f1njn return tid; 176c7561b931e249acf3768ead77638545b0ccaa8f1njn 177c7561b931e249acf3768ead77638545b0ccaa8f1njn return VG_INVALID_THREADID; 178c7561b931e249acf3768ead77638545b0ccaa8f1njn} 179c7561b931e249acf3768ead77638545b0ccaa8f1njn 180c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 181c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--- end ---*/ 182c7561b931e249acf3768ead77638545b0ccaa8f1njn/*--------------------------------------------------------------------*/ 183